RK3368 GPU version Rogue M 1.28
authorzxl <zhuangxl@rock-chips.com>
Wed, 6 Jan 2016 06:05:20 +0000 (14:05 +0800)
committerGerrit Code Review <gerrit@rock-chips.com>
Wed, 6 Jan 2016 11:14:34 +0000 (19:14 +0800)
Upload 1.5_ED3776568 DDK to drivers/gpu/rogue_m.

Change-Id: If9c88760e3c311f04a1e11c6ec102b1a92b1299f
Signed-off-by: zxl <zhuangxl@rock-chips.com>
436 files changed:
drivers/gpu/Makefile
drivers/gpu/rogue_m/GPL-COPYING [new file with mode: 0644]
drivers/gpu/rogue_m/INSTALL [new file with mode: 0644]
drivers/gpu/rogue_m/Kconfig [new file with mode: 0644]
drivers/gpu/rogue_m/MIT-COPYING [new file with mode: 0644]
drivers/gpu/rogue_m/Makefile [new file with mode: 0644]
drivers/gpu/rogue_m/README [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/bits.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/buildvars.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/commands.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/3rdparty.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/arch.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/arch_common.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/extra_config.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/features.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/install.sh.tpl [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/paths.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/android/platform_version.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/pvrgdb.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/common/testchip.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compiler.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compilers/aarch64-linux-android.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compilers/arm-eabi.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compilers/arm-linux-androideabi.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compilers/i386-linux-gnu.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/compilers/x86_64-linux-gnu.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/core.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/help.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/kernel_version.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/config/preconfig.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/defs.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/generic_arm_android/Makefile [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/kbuild/Makefile.template [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/kbuild/kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/host_i386.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/host_x86_64.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/target_aarch64.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/target_armv7-a.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/target_i686.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/target_neutral.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs/target_x86_64.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/moduledefs_common.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/modules.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/modules/kernel_module.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/pc_android/Makefile [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/prepare_tree.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/pvrversion.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/scripts.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/sunxi_android/Makefile [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/this_makefile.mk [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/tools/cc-check.sh [new file with mode: 0644]
drivers/gpu/rogue_m/build/linux/toplevel.mk [new file with mode: 0644]
drivers/gpu/rogue_m/config_kernel.h [new file with mode: 0644]
drivers/gpu/rogue_m/config_kernel.mk [new file with mode: 0644]
drivers/gpu/rogue_m/generated/breakpoint_bridge/common_breakpoint_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/breakpoint_bridge/server_breakpoint_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/cachegeneric_bridge/common_cachegeneric_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/cachegeneric_bridge/server_cachegeneric_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/cmm_bridge/common_cmm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/cmm_bridge/server_cmm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/debugmisc_bridge/common_debugmisc_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/debugmisc_bridge/server_debugmisc_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/devicememhistory_bridge/client_devicememhistory_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/devicememhistory_bridge/common_devicememhistory_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/devicememhistory_bridge/server_devicememhistory_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dmabuf_bridge/common_dmabuf_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dmabuf_bridge/server_dmabuf_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dpdumpmm_bridge/client_pdumpmm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dpvrtl_bridge/client_pvrtl_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dri_bridge/client_ri_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/mm_bridge/common_mm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/mm_bridge/server_mm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdump_bridge/common_pdump_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdump_bridge/server_pdump_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdumpmm_bridge/client_pdumpmm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdumpmm_bridge/common_pdumpmm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pdumpmm_bridge/server_pdumpmm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pvrtl_bridge/client_pvrtl_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pvrtl_bridge/common_pvrtl_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/pvrtl_bridge/server_pvrtl_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/regconfig_bridge/common_regconfig_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/regconfig_bridge/server_regconfig_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxcmp_bridge/common_rgxcmp_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxcmp_bridge/server_rgxcmp_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxinit_bridge/common_rgxinit_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxinit_bridge/server_rgxinit_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxpdump_bridge/common_rgxpdump_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxpdump_bridge/server_rgxpdump_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxta3d_bridge/common_rgxta3d_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxta3d_bridge/server_rgxta3d_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxtq_bridge/common_rgxtq_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/rgxtq_bridge/server_rgxtq_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/ri_bridge/client_ri_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/ri_bridge/common_ri_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/ri_bridge/server_ri_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/smm_bridge/common_smm_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/smm_bridge/server_smm_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/srvcore_bridge/common_srvcore_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/srvcore_bridge/server_srvcore_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/sync_bridge/common_sync_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/sync_bridge/server_sync_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/syncsexport_bridge/common_syncsexport_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/syncsexport_bridge/server_syncsexport_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/generated/timerquery_bridge/common_timerquery_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/generated/timerquery_bridge/server_timerquery_bridge.c [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.0.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.20.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.30.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.5.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.12.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.15.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.19.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.5.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.6.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.51.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.57.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.58.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.4.53.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.6.62.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.2.34.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.4.38.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.32.4.19.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.33.2.5.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.39.4.19.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.48.2.0.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.72.4.12.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.20.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.30.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.76.4.6.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.81.4.15.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.82.4.5.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_12.5.1.20.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.29.2.51.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.32.2.52.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.40.2.51.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.41.2.57.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.42.4.53.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.43.6.62.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.45.2.58.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.11.1.46.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.9.1.46.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.21.2.34.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.41.4.38.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/rgx_cr_defs_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/rgxdefs_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/hwdefs/km/rgxmmudefs_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/adf/adf_ext.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/cache_external.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/dbgdrvif_srv5.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/devicemem_typedefs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/img_3dtypes.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/img_defs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/img_types.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/kernel_types.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/lock_types.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pdumpdefs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvr_debug.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvr_fd_sync_kernel.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrmodule.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrsrv_device_types.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrsrv_devmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrsrv_error.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrsrv_errors.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrsrv_memallocflags.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/pvrversion.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_common.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_heaps.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_hwperf_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_memallocflags.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_meta.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgx_options_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/rgxscript.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/ri_typedefs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/services.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/servicesext.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/sync_external.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/system/rgx_tc/apollo_regs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/system/rgx_tc/pdp_regs.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/system/rgx_tc/tcf_clk_ctrl.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/system/rgx_tc/tcf_pll.h [new file with mode: 0644]
drivers/gpu/rogue_m/include/system/rgx_tc/tcf_rgbpdp_regs.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Linux.mk [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_fbdev.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_pdp.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo_drv.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.c [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.h [new file with mode: 0644]
drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/services_kernel_client.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/cache_defines.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/env/linux/ion_sys.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/env/linux/pvr_bridge_io.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/mm_common.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/pdump.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/physheap.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/pvr_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/pvr_bridge_client.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/pvr_tl.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/pvr_tlcommon.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_bridge.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_fwif.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_fwif_alignchecks_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_fwif_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_fwif_resetframework.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_fwif_shared.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_pdump_panics.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgx_tq_shared.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/rgxapi_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/shared/allocmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/shared/hash.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/shared/lock.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/include/shared/ra.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/cache_generic.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/connection_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/devicemem_heapcfg.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/devicemem_history_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/devicemem_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/handle.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/lists.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/mmu_common.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/pdump_common.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/pdump_mmu.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/pdump_physmem.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/physheap.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/physmem.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/physmem_lma.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/pmr.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/power.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/process_stats.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/pvrsrv.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/ri_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/srvcore.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/sync_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/tlintern.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/tlserver.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/common/tlstream.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxdevice.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxheapconfig.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/Linux.mk [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/allocmem.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/devicemem_mmap_stub.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/driverlock.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/env_connection.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/env_data.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/event.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/event.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/handle_idr.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/linkage.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/mm.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/mm.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/mmap.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/module.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/module_common.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/module_common.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/osconnection_server.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/osfunc.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm64.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/osfunc_x86.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/ossecure_export.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pdump.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/physmem_dmabuf.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/physmem_tdmetacode_linux.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/physmem_tdsecbuf_linux.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/private_data.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_bridge_k.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_debug.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/pvr_uaccess.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/rogue_trace_events.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/trace_events.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/env/linux/trace_events.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/cache_generic.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/connection_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/debug_request_ids.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/device.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/devicemem_heapcfg.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/devicemem_history_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/devicemem_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/devicemem_server_utils.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/handle.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/handle_impl.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/lists.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/mmu_common.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/osconnection_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/osfunc.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/ossecure_export.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pdump_km.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pdump_mmu.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pdump_osfunc.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pdump_physmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pdump_symbolicaddr.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/physmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/physmem_dmabuf.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/physmem_lma.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/physmem_osmem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pmr.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pmr_impl.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/power.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/process_stats.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pvr_dvfs.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pvrsrv.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pvrsrv_cleanup.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/pvrsrv_device.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/ri_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/secure_export.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/srvcore.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/srvkm.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/sync_server.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/sync_server_internal.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/tlintern.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/tlserver.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/server/include/tlstream.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/devicemem.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/devicemem_pdump.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/devicemem_utils.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/dllist.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/hash.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/mem_utils.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/ra.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/sync.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/tlclient.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/cache_internal.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/devicemem.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/devicemem_history_shared.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/devicemem_mmap.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/devicemem_pdump.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/devicemem_utils.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/dllist.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/sync.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/sync_internal.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/shared/include/tlclient.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_linux_apollo/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysconfig.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysinfo.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_nohw/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_nohw/sysinfo.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/ion_support_sunxi.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.c [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.h [new file with mode: 0644]
drivers/gpu/rogue_m/services/system/rgx_sunxi/sysinfo.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/common/ion_support_generic.c [new file with mode: 0644]
drivers/gpu/rogue_m/system/common/pci_support.c [new file with mode: 0644]
drivers/gpu/rogue_m/system/include/ion_support.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/include/pci_support.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/include/syscommon.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/rk_init.c [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/rk_init.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/sysconfig.c [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/sysconfig.h [new file with mode: 0644]
drivers/gpu/rogue_m/system/rk3368/sysinfo.h [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Kbuild.mk [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Linux.mk [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.c [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.h [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv_ioctl.h [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/handle.c [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/hostfunc.h [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/ioctl.c [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/hostfunc.c [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/main.c [new file with mode: 0644]
drivers/gpu/rogue_m/tools/services/debug/include/linuxsrv.h [new file with mode: 0644]
drivers/video/Kconfig

index e9ed439a5b65329c33f450a1c82e78290581783a..f203eac28637049b503e87587f7373c9625c8424 100644 (file)
@@ -4,3 +4,4 @@
 obj-$(CONFIG_TEGRA_HOST1X)     += host1x/
 obj-y                  += drm/ vga/
 obj-$(CONFIG_IMX_IPUV3_CORE)   += ipu-v3/
+obj-$(CONFIG_POWERVR_ROGUE_M)  += rogue_m/
diff --git a/drivers/gpu/rogue_m/GPL-COPYING b/drivers/gpu/rogue_m/GPL-COPYING
new file mode 100644 (file)
index 0000000..83d1261
--- /dev/null
@@ -0,0 +1,344 @@
+-------------------------------------------------------------------------
+
+                   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/gpu/rogue_m/INSTALL b/drivers/gpu/rogue_m/INSTALL
new file mode 100644 (file)
index 0000000..1af7538
--- /dev/null
@@ -0,0 +1,58 @@
+Rogue Embedded Systems DDK for the Linux kernel.
+Copyright (C) Imagination Technologies Ltd. All rights reserved.
+======================================================================
+
+This file covers how to build and install the Imagination Technologies
+Rogue DDK for the Linux kernel.  For full details, see the relevant platform
+guide.
+
+
+Build System Environment Variables
+-------------------------------------------
+
+The Rogue 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.  To do so, they need to know where the 
+target system image resides: 
+$ export DISCIMAGE=/path/to/filesystem
+If you are building on the target system, you can set this to '/'.
+
+$KERNELDIR
+When building the Rogue DDK kernel module, the build needs access
+to the headers of the Linux kernel.
+If you are building on the target machine, you can set this as follows:
+$ export KERNELDIR=/usr/src/linux-headers-`uname -r`
+
+$CROSS_COMPILE
+If you intend on targeting a platform that is different from your build
+machine (e.g.,if you are compiling on an x86 but targeting ARM) you need
+to set the CROSS_COMPILE variable so that the build system uses the correct
+compiler. E.g., 
+$ export CROSS_COMPILE=arm-linux-gnueabi-
+
+
+Build and Install Instructions
+-------------------------------------------
+
+The Rogue DDK configures different target builds within directories under
+build/linux/.
+
+The most interesting build targets are:
+
+       build   Makes everything
+       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.
+
+To build for, change to the appropriate target directory, e.g.:
+$ cd eurasiacon/build/linux/<platform>
+$ make BUILD=debug
+$ sudo make install
diff --git a/drivers/gpu/rogue_m/Kconfig b/drivers/gpu/rogue_m/Kconfig
new file mode 100644 (file)
index 0000000..ca76515
--- /dev/null
@@ -0,0 +1,6 @@
+config POWERVR_ROGUE_M
+        tristate "PowerVR Rogue M"
+       help
+        Driver for PowerVR Rogue M hardware. Say Y here if your SoC contains
+        a PowerVR Rogue GPU. For more information, see
+        <http://www.imgtec.com/powervr/>.
diff --git a/drivers/gpu/rogue_m/MIT-COPYING b/drivers/gpu/rogue_m/MIT-COPYING
new file mode 100644 (file)
index 0000000..0cbd14e
--- /dev/null
@@ -0,0 +1,41 @@
+
+This software is Copyright (C) Imagination Technologies Ltd.
+
+You may use, distribute and copy this software under the terms of the MIT
+license displayed below.
+
+-----------------------------------------------------------------------------
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, this Software may be used under the terms of the GNU General
+Public License Version 2 ("GPL") in which case the provisions of GPL are
+applicable instead of those above.
+
+If you wish to allow use of your version of this Software only under the terms
+of GPL, and not to allow others to use your version of this file under the
+terms of the MIT license, indicate your decision by deleting from each file
+the provisions above and replace them with the notice and other provisions
+required by GPL as set out in the file called "GPL-COPYING" included in this
+distribution. If you do not delete the provisions above, a recipient may use
+your version of this file under the terms of either the MIT license or GPL.
+
+-----------------------------------------------------------------------------
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-----------------------------------------------------------------------------
diff --git a/drivers/gpu/rogue_m/Makefile b/drivers/gpu/rogue_m/Makefile
new file mode 100644 (file)
index 0000000..c990871
--- /dev/null
@@ -0,0 +1,250 @@
+include drivers/gpu/rogue_m/config_kernel.mk
+
+obj-$(CONFIG_POWERVR_ROGUE_M) += pvrsrvkm.o
+
+ccflags-y += -include $(srctree)/drivers/gpu/rogue_m/config_kernel.h \
+ -Idrivers/gpu/rogue_m \
+ -Idrivers/gpu/rogue_m/hwdefs \
+ -Idrivers/gpu/rogue_m/hwdefs/km \
+ -Idrivers/gpu/rogue_m/system/include \
+ -Idrivers/gpu/rogue_m/system/common \
+ -Idrivers/gpu/rogue_m/system/$(PVR_SYSTEM) \
+ -Idrivers/gpu/rogue_m/services/server/include \
+ -Idrivers/gpu/rogue_m/include \
+ -Idrivers/gpu/rogue_m/services/include \
+ -Idrivers/gpu/rogue_m/services/include/shared \
+ -Idrivers/gpu/rogue_m/services/shared/include \
+ -Idrivers/gpu/rogue_m/services/shared/devices/rgx \
+ -Idrivers/gpu/rogue_m/services/server/env/linux \
+ -Idrivers/gpu/rogue_m/kernel/drivers/staging/imgtec \
+ -Idrivers/gpu/rogue_m/services/include/env/linux \
+ -Idrivers/gpu/rogue_m/services/server/devices/rgx
+
+tmp := $(addprefix -I,$(wildcard $(srctree)/drivers/gpu/rogue_m/generated/*))
+ccflags-y += $(tmp)
+
+########
+pvrsrvkm-y += \
+ services/server/env/linux/event.o \
+ services/server/env/linux/mm.o \
+ services/server/env/linux/mmap.o \
+ services/server/env/linux/module.o \
+ services/server/env/linux/module_common.o \
+ services/server/env/linux/devicemem_mmap_stub.o \
+ services/server/env/linux/osfunc.o \
+ services/server/env/linux/allocmem.o \
+ services/server/env/linux/osconnection_server.o \
+ services/server/env/linux/pdump.o \
+ services/server/env/linux/physmem_osmem_linux.o \
+ services/server/env/linux/pvr_debugfs.o \
+ services/server/env/linux/pvr_bridge_k.o \
+ services/server/env/linux/pvr_debug.o \
+ services/server/env/linux/physmem_tdmetacode_linux.o \
+ services/server/env/linux/physmem_tdsecbuf_linux.o \
+ services/server/common/devicemem_heapcfg.o \
+ services/shared/common/devicemem.o \
+ services/shared/common/devicemem_utils.o \
+ services/shared/common/mem_utils.o \
+ services/shared/common/hash.o \
+ services/shared/common/ra.o \
+ services/shared/common/sync.o \
+ services/shared/common/dllist.o \
+ services/server/common/devicemem_server.o \
+ services/server/common/handle.o \
+ services/server/common/lists.o \
+ services/server/common/mmu_common.o \
+ services/server/common/connection_server.o \
+ services/server/common/physheap.o \
+ services/server/common/physmem.o \
+ services/server/common/physmem_lma.o \
+ services/server/common/pmr.o \
+ services/server/common/power.o \
+ services/server/common/process_stats.o \
+ services/server/common/pvrsrv.o \
+ services/server/common/srvcore.o \
+ services/server/common/sync_server.o \
+ services/server/common/tlintern.o \
+ services/shared/common/tlclient.o \
+ services/server/common/tlserver.o \
+ services/server/common/tlstream.o \
+ services/shared/common/uniq_key_splay_tree.o \
+ services/server/devices/rgx/rgxsync.o
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+pvrsrvkm-y += \
+ services/server/common/dc_server.o \
+ services/server/common/scp.o
+endif
+
+ifeq ($(PVR_RI_DEBUG),1)
+pvrsrvkm-y += services/server/common/ri_server.o
+endif
+
+ifeq ($(PVR_HANDLE_BACKEND),generic)
+pvrsrvkm-y += services/server/common/handle_generic.o
+else
+ifeq ($(PVR_HANDLE_BACKEND),idr)
+pvrsrvkm-y += services/server/env/linux/handle_idr.o
+endif
+endif
+
+ifeq ($(SUPPORT_GPUTRACE_EVENTS),1)
+pvrsrvkm-y += services/server/env/linux/pvr_gputrace.o
+endif
+
+
+pvrsrvkm-$(CONFIG_X86) += services/server/env/linux/osfunc_x86.o
+pvrsrvkm-$(CONFIG_ARM) += services/server/env/linux/osfunc_arm.o
+pvrsrvkm-$(CONFIG_ARM64) += services/server/env/linux/osfunc_arm64.o
+pvrsrvkm-$(CONFIG_METAG) += osfunc_metag.o
+pvrsrvkm-$(CONFIG_MIPS) += osfunc_mips.o
+pvrsrvkm-$(CONFIG_EVENT_TRACING) += services/server/env/linux/trace_events.o
+
+
+ifeq ($(PDUMP),1)
+pvrsrvkm-y += \
+ services/server/common/pdump_common.o \
+ services/server/common/pdump_mmu.o \
+ services/server/common/pdump_physmem.o \
+ services/shared/common/devicemem_pdump.o
+endif
+
+pvrsrvkm-y += \
+ services/server/devices/rgx/rgxinit.o \
+ services/server/devices/rgx/rgxdebug.o \
+ services/server/devices/rgx/rgxhwperf.o \
+ services/server/devices/rgx/rgxmem.o \
+ services/server/devices/rgx/rgxta3d.o \
+ services/server/devices/rgx/rgxcompute.o \
+ services/server/devices/rgx/rgxccb.o \
+ services/server/devices/rgx/rgxmmuinit.o \
+ services/server/devices/rgx/rgxpower.o \
+ services/server/devices/rgx/rgxtransfer.o \
+ services/server/devices/rgx/rgxutils.o \
+ services/server/devices/rgx/rgxfwutils.o \
+ services/server/devices/rgx/rgxbreakpoint.o \
+ services/server/devices/rgx/debugmisc_server.o \
+ services/shared/devices/rgx/rgx_compat_bvnc.o \
+ services/server/devices/rgx/rgxregconfig.o \
+ services/server/devices/rgx/rgxtimerquery.o \
+ services/server/devices/rgx/rgxtimecorr.o
+
+ifeq ($(SUPPORT_RAY_TRACING),1)
+pvrsrvkm-y += rgxray.o
+endif
+
+ifeq ($(PDUMP),1)
+pvrsrvkm-y += services/server/devices/rgx/rgxpdump.o
+endif
+
+ifeq ($(SUPPORT_NATIVE_FENCE_SYNC),1)
+pvrsrvkm-y += \
+ kernel/drivers/staging/imgtec/pvr_sync.o
+endif
+
+pvrsrvkm-y += \
+ generated/mm_bridge/server_mm_bridge.o \
+ generated/dmm_bridge/client_mm_bridge.o \
+ generated/pdumpmm_bridge/server_pdumpmm_bridge.o \
+ generated/dpdumpmm_bridge/client_pdumpmm_bridge.o \
+ generated/cmm_bridge/server_cmm_bridge.o \
+ generated/pdump_bridge/server_pdump_bridge.o \
+ generated/rgxtq_bridge/server_rgxtq_bridge.o \
+ generated/rgxinit_bridge/server_rgxinit_bridge.o \
+ generated/rgxta3d_bridge/server_rgxta3d_bridge.o \
+ generated/rgxcmp_bridge/server_rgxcmp_bridge.o \
+ generated/srvcore_bridge/server_srvcore_bridge.o \
+ generated/sync_bridge/server_sync_bridge.o \
+ generated/dsync_bridge/client_sync_bridge.o \
+ generated/breakpoint_bridge/server_breakpoint_bridge.o \
+ generated/debugmisc_bridge/server_debugmisc_bridge.o \
+ generated/rgxpdump_bridge/server_rgxpdump_bridge.o \
+ generated/pvrtl_bridge/server_pvrtl_bridge.o \
+ generated/dpvrtl_bridge/client_pvrtl_bridge.o \
+ generated/rgxhwperf_bridge/server_rgxhwperf_bridge.o \
+ generated/regconfig_bridge/server_regconfig_bridge.o \
+ generated/timerquery_bridge/server_timerquery_bridge.o \
+ generated/pdumpctrl_bridge/server_pdumpctrl_bridge.o
+
+ifeq ($(PVR_RI_DEBUG),1)
+pvrsrvkm-y += \
+ generated/ri_bridge/server_ri_bridge.o \
+ generated/dri_bridge/client_ri_bridge.o
+endif
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+pvrsrvkm-y += \
+ generated/dc_bridge/server_dc_bridge.o
+endif
+
+ifeq ($(SUPPORT_RAY_TRACING),1)
+pvrsrvkm-y += generated/rgxray_bridge/server_rgxray_bridge.o
+endif
+
+ifeq ($(CACHEFLUSH_TYPE),CACHEFLUSH_GENERIC)
+pvrsrvkm-y += \
+ services/server/common/cache_generic.o \
+ generated/cachegeneric_bridge/server_cachegeneric_bridge.o
+endif
+
+ifeq ($(SUPPORT_SECURE_EXPORT),1)
+pvrsrvkm-y += \
+ services/server/env/linux/ossecure_export.o \
+ generated/smm_bridge/server_smm_bridge.o \
+ generated/syncsexport_bridge/server_syncsexport_bridge.o
+endif
+ifeq ($(SUPPORT_INSECURE_EXPORT),1)
+pvrsrvkm-y += \
+ generated/syncexport_bridge/server_syncexport_bridge.o
+endif
+
+ifeq ($(SUPPORT_ION),1)
+pvrsrvkm-y += generated/dmabuf_bridge/server_dmabuf_bridge.o
+pvrsrvkm-y += services/server/env/linux/physmem_dmabuf.o
+endif # SUPPORT_ION
+
+#ccflags-y += \
+# -mno-soft-float
+
+#dc_pdp-y += \
+#      dc_pdp/dc_pdp.o \
+#      dc_pdp/pdp_osfuncs.o    \
+#      dc_osfuncs.o
+
+pvrsrvkm-y += \
+       system/$(PVR_SYSTEM)/sysconfig.o
+#      system/common/pci_support.o
+
+ifeq ($(PVR_SYSTEM),rgx_tc)
+pvrsrvkm-y += system/$(PVR_SYSTEM)/apollo_flasher_linux.o
+endif
+
+ifeq ($(PVR_SYSTEM),rk3368)
+pvrsrvkm-y += system/$(PVR_SYSTEM)/rk_init.o
+endif
+
+#ifneq ($(SUPPORT_DRM),1)
+#pvrsrvkm-y += system/common/interrupt_support.o
+#endif
+
+ifeq ($(SUPPORT_ION),1)
+ifeq ($(LMA),1)
+# For LMA, use the TC-specific ion heap.
+pvrsrvkm-y += \
+       system/$(PVR_SYSTEM)/ion_support.o \
+       system/common/ion_lma_heap.o
+else
+# For UMA, use the generic ion support code, which creates heaps from system
+# memory.
+#pvrsrvkm-y += \
+#      system/common/ion_support_generic.o
+endif # LMA
+endif # SUPPORT_ION
+
+dbgdrv-y += \
+       tools/services/debug/dbgdriv/common/dbgdriv.o \
+       tools/services/debug/dbgdriv/common/ioctl.o \
+       tools/services/debug/dbgdriv/common/handle.o \
+       tools/services/debug/dbgdriv/linux/main.o \
+       tools/services/debug/dbgdriv/linux/hostfunc.o
+
diff --git a/drivers/gpu/rogue_m/README b/drivers/gpu/rogue_m/README
new file mode 100644 (file)
index 0000000..8579ae1
--- /dev/null
@@ -0,0 +1,32 @@
+Rogue Embedded Systems DDK for Linux kernel.
+Copyright (C) Imagination Technologies Ltd. All rights reserved.
+======================================================================
+
+
+About 
+-------------------------------------------
+
+This is the Imagination Technologies Rogue DDK for the Linux kernel.
+
+
+License
+-------------------------------------------
+
+You may use, distribute and copy this software under the terms of the MIT
+license.  Details of this license can be found in the file "MIT-COPYING".
+
+Alternatively, you may use, distribute and copy this software under the terms
+of the GNU General Public License version 2.  The full GNU General Public
+License version 2 can be found in the file "GPL-COPYING".
+
+
+Build and Install Instructions
+-------------------------------------------
+
+For details see the "INSTALL" file and the platform guide.
+
+Contact information:
+-------------------------------------------
+
+Imagination Technologies Ltd. <gpl-support@imgtec.com>
+Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
diff --git a/drivers/gpu/rogue_m/build/linux/bits.mk b/drivers/gpu/rogue_m/build/linux/bits.mk
new file mode 100644 (file)
index 0000000..e993c63
--- /dev/null
@@ -0,0 +1,125 @@
+########################################################################### ###
+#@Title         Useful special targets which don't build anything
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifneq ($(filter dumpvar-%,$(MAKECMDGOALS)),)
+dumpvar-%: ;
+$(foreach _var_to_dump,$(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))),$(info $(if $(filter undefined,$(origin $(_var_to_dump))),# $$($(_var_to_dump)) is not set,$(_var_to_dump) := $($(_var_to_dump)))))
+endif
+
+ifneq ($(filter whereis-%,$(MAKECMDGOALS)),)
+whereis-%: ;
+$(foreach _module_to_find,$(patsubst whereis-%,%,$(filter whereis-%,$(MAKECMDGOALS))),$(info $(if $(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),$(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),# No module $(_module_to_find))))
+endif
+
+ifneq ($(filter whatis-%,$(MAKECMDGOALS)),)
+whatis-$(HOST_OUT)/%: ;
+whatis-$(TARGET_PRIMARY_OUT)/%: ;
+whatis-$(TARGET_NEUTRAL_OUT)/%: ;
+$(foreach _file_to_find,$(patsubst whatis-%,%,$(filter whatis-%,$(MAKECMDGOALS))),$(info $(strip $(foreach _m,$(ALL_MODULES),$(if $(filter $(_file_to_find),$(INTERNAL_TARGETS_FOR_$(_m))),$(_file_to_find) is in $(_m) which is defined in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)),)))))
+endif
+
+.PHONY: ls-modules
+ls-modules:
+       @: $(foreach _m,$(ALL_MODULES),$(info $($(_m)_type) $(_m) $(patsubst $(TOP)/%,%,$(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)))))
+
+.PHONY: ls-types
+ls-types:
+       @: $(info $(sort $(patsubst host_%,%,$(foreach _m,$(ALL_MODULES),$($(_m)_type)))))
+
+ifeq ($(strip $(MAKECMDGOALS)),visualise)
+FORMAT ?= xlib
+GRAPHVIZ ?= neato
+visualise: $(OUT)/MAKE_RULES.dot
+       $(GRAPHVIZ) -T$(FORMAT) -o $(OUT)/MAKE_RULES.$(FORMAT) $<
+$(OUT)/MAKE_RULES.dot: $(OUT)/MAKE_RULES
+       perl $(MAKE_TOP)/tools/depgraph.pl -t $(TOP) -g $(firstword $(GRAPHVIZ)) $(OUT)/MAKE_RULES >$(OUT)/MAKE_RULES.dot
+$(OUT)/MAKE_RULES: $(ALL_MAKEFILES)
+       -$(MAKE) -C $(TOP) -f $(MAKE_TOP)/toplevel.mk TOP=$(TOP) OUT=$(OUT) ls-modules -qp >$(OUT)/MAKE_RULES 2>&1
+else
+visualise:
+       @: $(error visualise specified along with other goals. This is not supported)
+endif
+
+.PHONY: help confighelp
+help:
+       @echo 'Build targets'
+       @echo '  make, make build       Build all components of the build'
+       @echo '  make components        Build only the user-mode components'
+       @echo '  make kbuild            Build only the kernel-mode components'
+       @echo "  make docs              Build the build's supporting documentation"
+       @echo '  make MODULE            Build the module MODULE and all of its dependencies'
+       @echo '  make binary_.../target/libsomething.so'
+       @echo '                         Build a particular file (including intermediates)'
+       @echo 'Variables'
+       @echo '  make V=1 ...           Print the commands that are executed'
+       @echo '  make W=1 ...           Enable extra compiler warnings'
+       @echo '  make D=opt ...         Set build system debug option (D=help for a list)'
+       @echo '  make OUT=dir ...       Place output+intermediates in specified directory'
+       @echo '  make CHECK=cmd ...     Check source with static analyser or other tool'
+       @echo '  EXCLUDED_APIS=...      List of APIs to remove from the build'
+       @echo '  make SOMEOPTION=1 ...  Set configuration options (see "make confighelp")'
+       @echo '                         Defaults are set by $(PVR_BUILD_DIR)/Makefile'
+       @echo 'Clean targets'
+       @echo '  make clean             Remove output files for the current build'
+       @echo '  make clobber           As "make clean", but remove build config too'
+       @echo '  make clean-MODULE      Clean (or clobber) only files for MODULE'
+       @echo ''
+       @echo 'Special targets'
+       @echo '  make whereis-MODULE    Show the path to the Linux.mk defining MODULE'
+       @echo '  make whatis-FILE       Show which module builds an output FILE'
+       @echo '  make ls-modules        List all modules defined by makefiles'
+
+# This rule runs in the configuration stage, in config/help.mk. Make a dummy
+# target here to suppress "no rule to make target 'confighelp' messages.
+confighelp: ;
+
+ifneq ($(filter help,$(D)),)
+empty :=
+space := $(empty) $(empty) 
+$(info Debug options)
+$(info $(space)D=modules            dump module info)
+$(info $(space)D=config             dump all config options + type and origin)
+$(info $(space)D=freeze-config      prevent config changes)
+$(info $(space)D=config-changes     dump diffs when config changes)
+$(info $(space)D=nobuild            stop before running the main build)
+$(info Options can be combined: make D=freeze-config,config-changes)
+$(error D=help given)
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/buildvars.mk b/drivers/gpu/rogue_m/build/linux/buildvars.mk
new file mode 100644 (file)
index 0000000..54cd79f
--- /dev/null
@@ -0,0 +1,281 @@
+########################################################################### ###
+#@Title         Define global variables
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@Description   This file is read once at the start of the build, after reading 
+#               in config.mk. It should define the non-MODULE_* variables used 
+#               in commands, like ALL_CFLAGS
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# NOTE: You must *not* use the cc-option et al macros in COMMON_FLAGS,
+# COMMON_CFLAGS or COMMON_USER_FLAGS. These flags are shared between
+# host and target, which might use compilers with different capabilities.
+
+# ANOTHER NOTE: All flags here must be architecture-independent (i.e. no
+# -march or toolchain include paths)
+
+# These flags are used for kernel, User C and User C++
+#
+COMMON_FLAGS := -W -Wall
+
+# Some GCC warnings are C only, so we must mask them from C++
+#
+COMMON_CFLAGS := $(COMMON_FLAGS) \
+ -Wdeclaration-after-statement -Wno-format-zero-length \
+ -Wmissing-prototypes -Wstrict-prototypes
+
+# User C and User C++ optimization control. Does not affect kernel.
+#
+ifeq ($(BUILD),debug)
+COMMON_USER_FLAGS := -O0
+else
+OPTIM ?= -O2
+ifeq ($(USE_LTO),1)
+COMMON_USER_FLAGS := $(OPTIM) -flto
+else
+COMMON_USER_FLAGS := $(OPTIM)
+endif
+endif
+
+# GCOV support for user-mode coverage statistics
+#
+ifeq ($(GCOV_BUILD),on)
+COMMON_USER_FLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+# Driver has not yet been audited for aliasing issues
+#
+COMMON_USER_FLAGS += -fno-strict-aliasing
+
+# We always enable debugging. Either the release binaries are stripped
+# and the symbols put in the symbolpackage, or we're building debug.
+#
+COMMON_USER_FLAGS += -g
+
+# User C and User C++ warning flags
+#
+COMMON_USER_FLAGS += \
+ -Wpointer-arith -Wunused-parameter \
+ -Wmissing-format-attribute
+
+# Additional warnings, and optional warnings.
+#
+TESTED_TARGET_USER_FLAGS := \
+ $(call cc-option,-Wno-missing-field-initializers) \
+ $(call cc-option,-fdiagnostics-show-option) \
+ $(call cc-option,-Wno-self-assign) \
+ $(call cc-option,-Wno-parentheses-equality)
+TESTED_HOST_USER_FLAGS := \
+ $(call host-cc-option,-Wno-missing-field-initializers) \
+ $(call host-cc-option,-fdiagnostics-show-option) \
+ $(call host-cc-option,-Wno-self-assign) \
+ $(call host-cc-option,-Wno-parentheses-equality)
+
+# These flags are clang-specific.
+# -Wno-unused-command-line-argument works around a buggy interaction
+# with ccache, see https://bugzilla.samba.org/show_bug.cgi?id=8118
+# -fcolor-diagnostics force-enables colored error messages which
+# get disabled when ccache is piped through ccache.
+#
+TESTED_TARGET_USER_FLAGS += \
+ $(call cc-option,-Qunused-arguments) \
+ $(call cc-option,-fcolor-diagnostics)
+TESTED_HOST_USER_FLAGS += \
+ $(call host-cc-option,-Qunused-arguments) \
+ $(call host-cc-option,-fcolor-diagnostics)
+
+ifeq ($(W),1)
+TESTED_TARGET_USER_FLAGS += \
+ $(call cc-option,-Wbad-function-cast) \
+ $(call cc-option,-Wcast-qual) \
+ $(call cc-option,-Wcast-align) \
+ $(call cc-option,-Wconversion) \
+ $(call cc-option,-Wdisabled-optimization) \
+ $(call cc-option,-Wlogical-op) \
+ $(call cc-option,-Wmissing-declarations) \
+ $(call cc-option,-Wmissing-include-dirs) \
+ $(call cc-option,-Wnested-externs) \
+ $(call cc-option,-Wold-style-definition) \
+ $(call cc-option,-Woverlength-strings) \
+ $(call cc-option,-Wpacked) \
+ $(call cc-option,-Wpacked-bitfield-compat) \
+ $(call cc-option,-Wpadded) \
+ $(call cc-option,-Wredundant-decls) \
+ $(call cc-option,-Wshadow) \
+ $(call cc-option,-Wswitch-default) \
+ $(call cc-option,-Wvla) \
+ $(call cc-option,-Wwrite-strings)
+TESTED_HOST_USER_FLAGS += \
+ $(call host-cc-option,-Wbad-function-cast) \
+ $(call host-cc-option,-Wcast-qual) \
+ $(call host-cc-option,-Wcast-align) \
+ $(call host-cc-option,-Wconversion) \
+ $(call host-cc-option,-Wdisabled-optimization) \
+ $(call host-cc-option,-Wlogical-op) \
+ $(call host-cc-option,-Wmissing-declarations) \
+ $(call host-cc-option,-Wmissing-include-dirs) \
+ $(call host-cc-option,-Wnested-externs) \
+ $(call host-cc-option,-Wold-style-definition) \
+ $(call host-cc-option,-Woverlength-strings) \
+ $(call host-cc-option,-Wpacked) \
+ $(call host-cc-option,-Wpacked-bitfield-compat) \
+ $(call host-cc-option,-Wpadded) \
+ $(call host-cc-option,-Wredundant-decls) \
+ $(call host-cc-option,-Wshadow) \
+ $(call host-cc-option,-Wswitch-default) \
+ $(call host-cc-option,-Wvla) \
+ $(call host-cc-option,-Wwrite-strings)
+endif
+
+TESTED_TARGET_USER_FLAGS += \
+ $(call cc-optional-warning,-Wunused-but-set-variable) \
+ $(call cc-optional-warning,-Wtypedef-redefinition)
+TESTED_HOST_USER_FLAGS += \
+ $(call host-cc-optional-warning,-Wunused-but-set-variable) \
+ $(call host-cc-optional-warning,-Wtypedef-redefinition)
+
+KBUILD_FLAGS := \
+ -Wno-unused-parameter -Wno-sign-compare
+
+TESTED_KBUILD_FLAGS := \
+ $(call kernel-cc-option,-Wmissing-include-dirs) \
+ $(call kernel-cc-option,-Wno-type-limits) \
+ $(call kernel-cc-option,-Wno-pointer-arith) \
+ $(call kernel-cc-option,-Wno-aggregate-return) \
+ $(call kernel-cc-option,-Wno-unused-but-set-variable) \
+ $(call kernel-cc-optional-warning,-Wbad-function-cast) \
+ $(call kernel-cc-optional-warning,-Wcast-qual) \
+ $(call kernel-cc-optional-warning,-Wcast-align) \
+ $(call kernel-cc-optional-warning,-Wconversion) \
+ $(call kernel-cc-optional-warning,-Wdisabled-optimization) \
+ $(call kernel-cc-optional-warning,-Wlogical-op) \
+ $(call kernel-cc-optional-warning,-Wmissing-declarations) \
+ $(call kernel-cc-optional-warning,-Wmissing-include-dirs) \
+ $(call kernel-cc-optional-warning,-Wnested-externs) \
+ $(call kernel-cc-optional-warning,-Wno-missing-field-initializers) \
+ $(call kernel-cc-optional-warning,-Wold-style-definition) \
+ $(call kernel-cc-optional-warning,-Woverlength-strings) \
+ $(call kernel-cc-optional-warning,-Wpacked) \
+ $(call kernel-cc-optional-warning,-Wpacked-bitfield-compat) \
+ $(call kernel-cc-optional-warning,-Wpadded) \
+ $(call kernel-cc-optional-warning,-Wredundant-decls) \
+ $(call kernel-cc-optional-warning,-Wshadow) \
+ $(call kernel-cc-optional-warning,-Wswitch-default) \
+ $(call kernel-cc-optional-warning,-Wvla) \
+ $(call kernel-cc-optional-warning,-Wwrite-strings)
+
+# User C only
+#
+ALL_CFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(TESTED_TARGET_USER_FLAGS) \
+ $(SYS_CFLAGS)
+ALL_HOST_CFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(TESTED_HOST_USER_FLAGS)
+
+# User C++ only
+#
+ALL_CXXFLAGS := \
+ -fno-rtti -fno-exceptions \
+ $(COMMON_USER_FLAGS) $(COMMON_FLAGS) $(TESTED_TARGET_USER_FLAGS) \
+ $(SYS_CXXFLAGS)
+ALL_HOST_CXXFLAGS := \
+ -fno-rtti -fno-exceptions \
+ $(COMMON_USER_FLAGS) $(COMMON_FLAGS) $(TESTED_HOST_USER_FLAGS)
+
+# Workaround for some target clangs that don't support -O0 w/ PIC.
+#
+ifeq ($(cc-is-clang),true)
+ALL_CFLAGS := $(patsubst -O0,-O1,$(ALL_CFLAGS))
+ALL_CXXFLAGS := $(patsubst -O0,-O1,$(ALL_CXXFLAGS))
+endif
+
+# Add GCOV_DIR just for target
+#
+ifeq ($(GCOV_BUILD),on)
+ifneq ($(GCOV_DIR),)
+ALL_CFLAGS += -fprofile-dir=$(GCOV_DIR)
+ALL_CXXFLAGS += -fprofile-dir=$(GCOV_DIR)
+endif
+endif
+
+# Kernel C only
+#
+ALL_KBUILD_CFLAGS := $(COMMON_CFLAGS) $(KBUILD_FLAGS) $(TESTED_KBUILD_FLAGS)
+
+# User C and C++
+#
+# NOTE: ALL_HOST_LDFLAGS should probably be using -rpath-link too, and if we
+# ever need to support building host shared libraries, it's required.
+#
+# We can't use it right now because we want to support non-GNU-compatible
+# linkers like the Darwin 'ld' which doesn't support -rpath-link.
+#
+# For the same reason (Darwin 'ld') don't bother checking for text
+# relocations in host binaries.
+#
+ALL_HOST_LDFLAGS :=
+ALL_LDFLAGS := -Wl,--warn-shared-textrel
+
+ifeq ($(GCOV_BUILD),on)
+ALL_LDFLAGS += -fprofile-arcs
+ALL_HOST_LDFLAGS += -fprofile-arcs
+endif
+
+ALL_LDFLAGS += $(SYS_LDFLAGS)
+
+# This variable contains a list of all modules built by kbuild
+ALL_KBUILD_MODULES :=
+
+# This variable contains a list of all modules which contain C++ source files
+ALL_CXX_MODULES :=
+
+# Toolchain triple for cross environment
+CROSS_TRIPLE := $(patsubst %-,%,$(CROSS_COMPILE))
+
+ifneq ($(TOOLCHAIN),)
+$(warning **********************************************)
+$(warning  The TOOLCHAIN option has been removed, but)
+$(warning  you have it set (via $(origin TOOLCHAIN)))
+$(warning **********************************************)
+endif
+
+# We need the glibc version to generate the cache names for LLVM and XOrg components.
+ifeq ($(CROSS_COMPILE),)
+LIBC_VERSION_PROBE := $(shell ldd  $(shell which true) | awk '/libc.so/{print $$3'} )
+LIBC_VERSION := $(shell $(LIBC_VERSION_PROBE)| tr -d '(),' | head -1)
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/commands.mk b/drivers/gpu/rogue_m/build/linux/commands.mk
new file mode 100644 (file)
index 0000000..3ab5fcb
--- /dev/null
@@ -0,0 +1,357 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# from-one-* recipes make a thing from one source file, so they use $<. Others
+# use $(MODULE_something) instead of $^
+
+# We expect that MODULE_*FLAGS contains all the flags we need, including the
+# flags for all modules (like $(ALL_CFLAGS) and $(ALL_HOST_CFLAGS)), and
+# excluding flags for include search dirs or for linking libraries. The
+# exceptions are ALL_EXE_LDFLAGS and ALL_LIB_LDFLAGS, since they depend on the
+# type of thing being linked, so they appear in the commands below
+
+define host-o-from-one-c
+$(if $(V),,@echo "  HOST_CC " $(call relative-to-top,$<))
+$(MODULE_CC) -MD -MF $(patsubst %.o,%.d,$@) -c $(MODULE_CFLAGS) \
+       $(MODULE_INCLUDE_FLAGS) -include $(CONFIG_H) $< -o $@
+endef
+
+define target-o-from-one-c
+$(if $(V),,@echo "  CC      " $(call relative-to-top,$<))
+$(MODULE_CC) -MD -MF $(patsubst %.o,%.d,$@) -c $(MODULE_CFLAGS) \
+       $(MODULE_INCLUDE_FLAGS) -include $(CONFIG_H) $< -o $@
+endef
+
+define host-o-from-one-cxx
+$(if $(V),,@echo "  HOST_CXX" $(call relative-to-top,$<))
+$(MODULE_CXX) -MD -MF $(patsubst %.o,%.d,$@) -c $(MODULE_CXXFLAGS) \
+       $(MODULE_INCLUDE_FLAGS) -include $(CONFIG_H) $< -o $@
+endef
+
+define target-o-from-one-cxx
+$(if $(V),,@echo "  CXX     " $(call relative-to-top,$<))
+$(MODULE_CXX) -MD -MF $(patsubst %.o,%.d,$@) -c $(MODULE_CXXFLAGS) \
+       $(MODULE_INCLUDE_FLAGS) -include $(CONFIG_H) $< -o $@
+endef
+
+define host-executable-from-o
+$(if $(V),,@echo "  HOST_LD " $(call relative-to-top,$@))
+$(MODULE_CC) $(MODULE_LDFLAGS) \
+       -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \
+       $(MODULE_LIBRARY_FLAGS)
+endef
+
+define host-executable-cxx-from-o
+$(if $(V),,@echo "  HOST_LD " $(call relative-to-top,$@))
+$(MODULE_CXX) $(MODULE_LDFLAGS) \
+       -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \
+       $(MODULE_LIBRARY_FLAGS)
+endef
+
+define target-executable-from-o
+$(if $(V),,@echo "  LD      " $(call relative-to-top,$@))
+$(MODULE_CC) \
+       $(MODULE_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+       $(MODULE_EXE_CRTBEGIN) $(MODULE_ALL_OBJECTS) $(MODULE_EXE_CRTEND) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(MODULE_LIBGCC)
+endef
+
+define target-executable-cxx-from-o
+$(if $(V),,@echo "  LD      " $(call relative-to-top,$@))
+$(MODULE_CXX) \
+       $(MODULE_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+       $(MODULE_EXE_CRTBEGIN) $(MODULE_ALL_OBJECTS) $(MODULE_EXE_CRTEND) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(MODULE_LIBGCC)
+endef
+
+define target-shared-library-from-o
+$(if $(V),,@echo "  LD      " $(call relative-to-top,$@))
+$(MODULE_CC) -shared -Wl,-Bsymbolic \
+       $(MODULE_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+       $(MODULE_LIB_CRTBEGIN) $(MODULE_ALL_OBJECTS) $(MODULE_LIB_CRTEND) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(MODULE_LIBGCC)
+endef
+
+define host-shared-library-from-o
+$(if $(V),,@echo "  HOST_LD " $(call relative-to-top,$@))
+$(MODULE_CC) -shared -Wl,-Bsymbolic \
+       $(MODULE_LDFLAGS) -o $@ \
+       $(sort $(MODULE_ALL_OBJECTS)) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS)
+endef
+
+# If there were any C++ source files in a shared library, we use one of
+# these recipes, which run the C++ compiler to link the final library
+define target-shared-library-cxx-from-o
+$(if $(V),,@echo "  LD      " $(call relative-to-top,$@))
+$(MODULE_CXX) -shared -Wl,-Bsymbolic \
+       $(MODULE_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+       $(MODULE_LIB_CRTBEGIN) $(MODULE_ALL_OBJECTS) $(MODULE_LIB_CRTEND) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(MODULE_LIBGCC)
+endef
+
+define host-shared-library-cxx-from-o
+$(if $(V),,@echo "  HOST_LD " $(call relative-to-top,$@))
+$(MODULE_CXX) -shared -Wl,-Bsymbolic \
+       $(MODULE_LDFLAGS) -o $@ \
+       $(sort $(MODULE_ALL_OBJECTS)) \
+       $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS)
+endef
+
+define host-copy-debug-information
+$(HOST_OBJCOPY) --only-keep-debug $@ $(basename $@).dbg
+endef
+
+define host-strip-debug-information
+$(HOST_STRIP) --strip-unneeded $@
+endef
+
+define host-add-debuglink
+$(if $(V),,@echo "  DBGLINK " $(call relative-to-top,$(basename $@).dbg))
+$(HOST_OBJCOPY) --add-gnu-debuglink=$(basename $@).dbg $@
+endef
+
+define target-copy-debug-information
+$(OBJCOPY) --only-keep-debug $@ $(basename $@).dbg
+endef
+
+define target-strip-debug-information
+$(STRIP) --strip-unneeded $@
+endef
+
+define target-add-debuglink
+$(if $(V),,@echo "  DBGLINK " $(call relative-to-top,$(basename $@).dbg))
+$(OBJCOPY) --add-gnu-debuglink=$(basename $@).dbg $@
+endef
+
+define host-static-library-from-o
+$(if $(V),,@echo "  HOST_AR " $(call relative-to-top,$@))
+$(HOST_AR) cru $@ $(sort $(MODULE_ALL_OBJECTS))
+endef
+
+define target-static-library-from-o
+$(if $(V),,@echo "  AR      " $(call relative-to-top,$@))
+$(AR) cru $@ $(sort $(MODULE_ALL_OBJECTS))
+endef
+
+define tab-c-from-y
+$(if $(V),,@echo "  BISON   " $(call relative-to-top,$<))
+$(BISON) $(MODULE_BISON_FLAGS) -o $@ -d $<
+endef
+
+define l-c-from-l
+$(if $(V),,@echo "  FLEX    " $(call relative-to-top,$<))
+$(FLEX) $(MODULE_FLEX_FLAGS) -o$@ $<
+endef
+
+define l-cc-from-l
+$(if $(V),,@echo "  FLEXXX  " $(call relative-to-top,$<))
+$(FLEXXX) $(MODULE_FLEXXX_FLAGS) -o$@ $<
+endef
+
+define clean-dirs
+$(if $(V),,@echo "  RM      " $(call relative-to-top,$(MODULE_DIRS_TO_REMOVE)))
+$(RM) -rf $(MODULE_DIRS_TO_REMOVE)
+endef
+
+define make-directory
+$(MKDIR) -p $@
+endef
+
+ifeq ($(DISABLE_CHECK_EXPORTS),)
+define check-exports
+endef
+else
+define check-exports
+endef
+endif
+
+# Check a source file with the program specified in $(CHECK).
+# If $(CHECK) is empty, don't do anything.
+ifeq ($(CHECK),)
+check-src :=
+else
+define check-src-1
+$(if $(V),,@echo "  CHECK   " $(call relative-to-top,$<))
+$(if $(IGNORE_CHECK_ERRORS),-,)$(CHECK) $(MODULE_INCLUDE_FLAGS) \
+       $(if $(CHECK_NO_CONFIG_H),,-include $(CONFIG_H)) \
+       $(filter -D%,$(MODULE_CFLAGS)) \
+       $(CHECKFLAGS) $<
+endef
+# If CHECK_ONLY is set, only check files matching a Make pattern.
+# e.g. CHECK_ONLY=opengles1/%.c
+define check-src
+$(if $(and $(if $(CHECK_ONLY),$(filter $(CHECK_ONLY),$<),true), \
+               $(if $(CHECK_EXCLUDE),$(filter-out $(CHECK_EXCLUDE),$<),true)),$(check-src-1),@:)
+endef
+endif
+
+# Programs used in recipes
+
+BISON ?= bison
+CC ?= gcc
+CC_SECONDARY ?= $(CC)
+CROSS_COMPILE_SECONDARY ?= $(CROSS_COMPILE)
+CXX ?= g++
+CXX_SECONDARY ?= $(CXX)
+HOST_CC ?= gcc
+HOST_CXX ?= g++
+JAR ?= jar
+JAVA ?= java
+JAVAC ?= javac
+PYTHON ?= python
+ZIP ?= zip
+
+ifeq ($(USE_CCACHE),1)
+CCACHE ?= ccache
+endif
+ifeq ($(USE_DISTCC),1)
+DISTCC ?= distcc
+endif
+
+# Define CHMOD and CC_CHECK first so we can use cc-is-clang
+#
+override CHMOD         := $(if $(V),,@)chmod
+override CC_CHECK      := $(if $(V),,@)$(MAKE_TOP)/tools/cc-check.sh
+
+# If clang is detected, the compiler name is invariant but CROSS_COMPILE
+# is reflected in the use of -target. For GCC this is always encoded into
+# the binary. If CROSS_COMPILE is not set we can skip this.
+#
+# If we're doing a build with multiple target architectures, we might need
+# two separate compilers to build binaries for each architecture. In this
+# case, CROSS_COMPILE and CROSS_COMPILE_SECONDARY are the cross compiler
+# prefix for the two compilers - $(CC) and $(CC_SECONDARY).
+#
+# Set the secondary compiler first before we overwrite $(CC).
+#
+
+ifneq ($(CROSS_COMPILE_SECONDARY),)
+ ifeq ($(cc-is-clang),true)
+  override CC_SECONDARY   := \
+   $(CC_SECONDARY) \
+   -target $(patsubst %-,%,$(CROSS_COMPILE_SECONDARY)) \
+   -B$(dir $(shell which $(CROSS_COMPILE_SECONDARY)gcc))
+  override CXX_SECONDARY  := \
+   $(CXX_SECONDARY) \
+   -target $(patsubst %-,%,$(CROSS_COMPILE_SECONDARY)) \
+   -B$(dir $(shell which $(CROSS_COMPILE_SECONDARY)gcc))
+ else
+  ifeq ($(origin CC_SECONDARY),file)
+   override CC_SECONDARY  := $(CROSS_COMPILE_SECONDARY)$(CC_SECONDARY)
+  endif
+  ifeq ($(origin CXX_SECONDARY),file)
+   override CXX_SECONDARY := $(CROSS_COMPILE_SECONDARY)$(CXX_SECONDARY)
+  endif
+ endif
+endif
+
+# Apply compiler wrappers and V=1 handling
+override CC_SECONDARY     := $(if $(V),,@)$(CCACHE)$(DISTCC) $(CC_SECONDARY)
+override CXX_SECONDARY    := $(if $(V),,@)$(CCACHE)$(DISTCC) $(CXX_SECONDARY)
+
+ifneq ($(CROSS_COMPILE),)
+ ifeq ($(cc-is-clang),true)
+  override CC   := \
+   $(CC) \
+   -target $(patsubst %-,%,$(CROSS_COMPILE)) \
+   -B$(dir $(shell which $(CROSS_COMPILE)gcc))
+  override CXX  := \
+   $(CXX) \
+   -target $(patsubst %-,%,$(CROSS_COMPILE)) \
+   -B$(dir $(shell which $(CROSS_COMPILE)gcc))
+ else
+  ifeq ($(origin CC),file)
+   override CC  := $(CROSS_COMPILE)$(CC)
+  endif
+  ifeq ($(origin CXX),file)
+   override CXX := $(CROSS_COMPILE)$(CXX)
+  endif
+ endif
+else
+ $(if $(CROSS_COMPILE_SECONDARY),$(error CROSS_COMPILE_SECONDARY is set but CROSS_COMPILE is empty))
+endif
+
+# Apply compiler wrappers and V=1 handling
+override CC     := $(if $(V),,@)$(CCACHE)$(DISTCC) $(CC)
+override CXX    := $(if $(V),,@)$(CCACHE)$(DISTCC) $(CXX)
+
+override AR                            := $(if $(V),,@)$(CROSS_COMPILE)ar
+override BISON                 := $(if $(V),,@)$(BISON)
+override BZIP2                 := $(if $(V),,@)bzip2 -9
+override CAT                   := $(if $(V),,@)cat
+override CHECK                 := $(if $(CHECK),$(if $(V),,@)$(CHECK),)
+override CP                            := $(if $(V),,@)cp
+override ECHO                  := $(if $(V),,@)echo
+override FLEX                  := $(if $(V),,@)flex
+override FLEXXX                        := $(if $(V),,@)flex++
+override GREP                  := $(if $(V),,@)grep
+override HOST_AR               := $(if $(V),,@)ar
+override HOST_CC               := $(if $(V),,@)$(CCACHE) $(HOST_CC)
+override HOST_CXX              := $(if $(V),,@)$(CCACHE) $(HOST_CXX)
+override HOST_OBJCOPY  := $(if $(V),,@)objcopy
+override HOST_STRIP            := $(if $(V),,@)strip
+override INSTALL               := $(if $(V),,@)install
+override JAR                   := $(if $(V),,@)$(JAR)
+override JAVA                  := $(if $(V),,@)$(JAVA)
+override JAVAC                 := $(if $(V),,@)$(JAVAC)
+override LN                            := $(if $(V),,@)ln -f -s
+override M4                            := $(if $(V),,@)m4
+override MKDIR                 := $(if $(V),,@)mkdir
+override MV                            := $(if $(V),,@)mv
+override OBJCOPY               := $(if $(V),,@)$(CROSS_COMPILE)objcopy
+override PERL                  := $(if $(V),,@)perl
+override PSC                   := $(if $(V),,@)$(HOST_OUT)/psc_standalone
+override PYTHON                        := $(if $(V),,@)$(PYTHON)
+override RANLIB                        := $(if $(V),,@)$(CROSS_COMPILE)ranlib
+override RM                            := $(if $(V),,@)rm -f
+override ROGUEASM              := $(if $(V),,@)$(HOST_OUT)/rogueasm
+override SED                   := $(if $(V),,@)sed
+override STRIP                 := $(if $(V),,@)$(CROSS_COMPILE)strip
+override TAR                   := $(if $(V),,@)tar
+override TOUCH                 := $(if $(V),,@)touch
+override TEST                  := $(if $(V),,@)test
+override VHD2INC               := $(if $(V),,@)$(HOST_OUT)/vhd2inc
+override XXD            := $(if $(V),,@)xxd
+override ZIP                   := $(if $(V),,@)$(ZIP)
+
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/commands_neutrino.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/3rdparty.mk b/drivers/gpu/rogue_m/build/linux/common/3rdparty.mk
new file mode 100644 (file)
index 0000000..fb58e1e
--- /dev/null
@@ -0,0 +1,103 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+########################################################################### ###
+# Display class drivers
+########################################################################### ###
+
+ifeq ($(DISPLAY_CONTROLLER),dc_example)
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_WIDTH,))
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_HEIGHT,))
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_DPI,))
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_BIT_DEPTH,))
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_FBC_MODE,))
+$(eval $(call TunableKernelConfigC,DC_EXAMPLE_MEMORY_LAYOUT,))
+endif
+
+ifeq ($(DISPLAY_CONTROLLER),dc_fbdev)
+$(eval $(call TunableKernelConfigC,DC_FBDEV_REFRESH,))
+
+$(eval $(call TunableKernelConfigC,DC_FBDEV_FORCE_XRGB8888,,\
+Force the dc_fbdev display driver to use XRGB8888. This is necessary_\
+when the underlying Linux framebuffer driver does not ignore alpha_\
+meaning an alpha value of 0 results in nothing being displayed._\
+))
+
+$(eval $(call TunableKernelConfigC,DC_FBDEV_NUM_PREFERRED_BUFFERS,,\
+The maximum number of display buffers the dc_fbdev display driver_\
+supports. The underlying Linux framebuffer driver must be capable_\
+of allocating sufficient memory for the number of buffers chosen._\
+))
+endif
+
+ifeq ($(DISPLAY_CONTROLLER),dc_pdp)
+$(eval $(call TunableKernelConfigC,DCPDP_WIDTH,))
+$(eval $(call TunableKernelConfigC,DCPDP_HEIGHT,))
+$(eval $(call TunableKernelConfigC,DCPDP_DPI,))
+$(eval $(call TunableKernelConfigC,DCPDP_DYNAMIC_GTF_TIMING,1))
+$(eval $(call TunableKernelConfigC,DCPDP_NO_INTERRUPTS,))
+endif
+
+ifeq ($(DISPLAY_CONTROLLER),adf_pdp)
+$(eval $(call TunableKernelConfigC,ADF_PDP_WIDTH,))
+$(eval $(call TunableKernelConfigC,ADF_PDP_HEIGHT,))
+endif
+
+########################################################################### ###
+# DRM display drivers
+########################################################################### ###
+
+ifeq ($(DISPLAY_CONTROLLER),drm_fbdev)
+$(eval $(call TunableKernelConfigC,DRM_FBDEV_FORCE_XRGB8888,,\
+Force the drm_fbdev display driver to use XRGB8888. This is necessary_\
+when the underlying Linux framebuffer driver does not ignore alpha_\
+meaning an alpha value of 0 results in nothing being displayed._\
+))
+
+$(eval $(call TunableKernelConfigC,DRM_FBDEV_NUM_PREFERRED_BUFFERS,,\
+The maximum number of display buffers the drm_fbdev display driver_\
+supports. The underlying Linux framebuffer driver must be capable_\
+of allocating sufficient memory for the number of buffers chosen._\
+))
+
+$(eval $(call TunableKernelConfigC,DRM_FBDEV_SET_BPP,,\
+Set the number of bits per pixel to a particular value.\
+))
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/arch.mk b/drivers/gpu/rogue_m/build/linux/common/android/arch.mk
new file mode 100644 (file)
index 0000000..fd34469
--- /dev/null
@@ -0,0 +1,101 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+include ../common/android/platform_version.mk
+
+# Now we have included the platform_version.mk file, we know we have a
+# correctly configured OUT_DIR and can probe it to figure out our
+# architecture. For backwards compatibility with KitKat, use the deprecated
+# ro.product.cpu.abi (primary architecture) property instead of abilist64.
+
+$(eval $(subst #,$(newline),$(shell cat $(BUILD_PROP) | \
+    grep '^ro.product.cpu.abi=\|^ro.product.cpu.abilist32=' | \
+    sed -e 's,ro.product.cpu.abi=,JNI_CPU_ABI=,' \
+        -e 's,ro.product.cpu.abilist32=,JNI_CPU_ABI_2ND=,' | \
+    tr ',' ' ' | tr '\n' '#')))
+
+# If ARCH is set, use that to remap to an "Android" ARCH..
+ANDROID_ARCH := $(filter arm arm64 mips mips64 x86 x86_64,$(ARCH))
+
+# x86 is special and has another legacy ARCH name which is remapped
+ifeq ($(ARCH),i386)
+ANDROID_ARCH := x86
+endif
+
+ifeq ($(ANDROID_ARCH),)
+# ..otherwise, try to use the ABI list to figure it out.
+ifneq ($(filter armeabi-v7a armeabi,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=arm
+else ifneq ($(filter arm64-v8a,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=arm64
+else ifneq ($(filter mips,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=mips
+else ifneq ($(filter mips64,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=mips64
+else ifneq ($(filter x86,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=x86
+else ifneq ($(filter x86_64,$(JNI_CPU_ABI)),)
+ANDROID_ARCH=x86_64
+else
+$(error ARCH not set and JNI_CPU_ABI=$(JNI_CPU_ABI) was not remappable)
+endif
+endif
+
+JNI_CPU_ABI := $(word 1,$(JNI_CPU_ABI))
+JNI_CPU_ABI_2ND := $(word 1,$(JNI_CPU_ABI_2ND))
+
+include ../common/android/arch_common.mk
+
+ifneq ($(filter arm arm64 mips mips64,$(ANDROID_ARCH)),)
+LDM_PLATFORM ?= 1
+endif
+
+ifneq ($(filter x86 x86_64,$(ANDROID_ARCH)),)
+KERNEL_CROSS_COMPILE ?= undef
+endif
+
+ifneq ($(filter arm64 mips64 x86_64,$(ANDROID_ARCH)),)
+PVR_ANDROID_ARCH_IS_64BIT := 1
+ifeq ($(MULTIARCH),)
+$(warning *** 64-bit architecture detected. Enabling MULTIARCH=1.)
+$(warning *** If you want a 64-bit only build, use MULTIARCH=64only.)
+export MULTIARCH := 1
+endif
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/arch_common.mk b/drivers/gpu/rogue_m/build/linux/common/android/arch_common.mk
new file mode 100644 (file)
index 0000000..280a128
--- /dev/null
@@ -0,0 +1,85 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+SYS_CFLAGS := \
+ -fno-short-enums \
+ -funwind-tables \
+ -D__linux__
+SYS_INCLUDES := \
+ -isystem $(ANDROID_ROOT)/bionic/libc/include \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/uapi \
+ -isystem $(ANDROID_ROOT)/bionic/libm/include \
+ -isystem $(ANDROID_ROOT)/bionic/libthread_db/include \
+ -isystem $(ANDROID_ROOT)/external/libunwind/include \
+ -isystem $(ANDROID_ROOT)/frameworks/base/include \
+ -isystem $(ANDROID_ROOT)/hardware/libhardware/include \
+ -isystem $(ANDROID_ROOT)/system/core/include \
+ -isystem $(ANDROID_ROOT)/system/core/include/sync \
+ -isystem $(ANDROID_ROOT)/system/core/adf/libadf/include \
+ -isystem $(ANDROID_ROOT)/system/core/adf/libadfhwc/include \
+ -isystem $(ANDROID_ROOT)/system/core/libsync/include \
+ -isystem $(ANDROID_ROOT)/system/core/libsync \
+ -isystem $(ANDROID_ROOT)/system/media/camera/include
+
+ifneq ($(wildcard $(ANDROID_ROOT)/external/boringssl/src/include),)
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/external/boringssl/src/include
+else
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/external/openssl/include
+endif
+
+# Obsolete libc includes
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/common \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/arch-$(ANDROID_ARCH)
+
+# The following include is a workaround for ICS 4.0.4 partial directory change
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/frameworks/base/native/include \
+ -isystem $(ANDROID_ROOT)/frameworks/native/include
+
+ifeq ($(_CLANG),true)
+SYS_INCLUDES := \
+ -nostdinc $(SYS_INCLUDES) \
+ -isystem $(ANDROID_ROOT)/external/clang/lib/Headers
+endif
+
+OPTIM := -O2
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/extra_config.mk b/drivers/gpu/rogue_m/build/linux/common/android/extra_config.mk
new file mode 100644 (file)
index 0000000..40c0703
--- /dev/null
@@ -0,0 +1,80 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(eval $(call UserConfigMake,libpthread_ldflags,))
+$(eval $(call UserConfigMake,librt_ldflags,))
+# On versions of Android prior to L, remap the use of libc++ to a combination
+# of stlport and libstdc++. Not every module written in C++ in the DDK needs
+# the STL, but linking it should be harmless (and most modules do need it).
+ifneq ($(is_at_least_lollipop),1)
+$(eval $(call UserConfigMake,libc++_ldflags,-lstlport -lstdc++))
+endif
+
+$(eval $(call UserConfigMake,TARGET_ROOT,$(TARGET_ROOT)))
+$(eval $(call UserConfigMake,TARGET_DEVICE,$(TARGET_DEVICE)))
+
+$(eval $(call BothConfigMake,SUPPORT_ANDROID_PLATFORM,1))
+
+$(eval $(call BothConfigC,ANDROID,))
+
+$(eval $(call UserConfigC,SUPPORT_ANDROID_PLATFORM,1))
+
+# These are set automatically according to the platform version.
+$(eval $(call TunableBothConfigC,SUPPORT_NATIVE_FENCE_SYNC,))
+
+# These are user-tunable.
+
+
+$(eval $(call TunableBothConfigC,PVR_ANDROID_HAS_SW_INCOMPATIBLE_FRAMEBUFFER,,\
+Enable this to support running Android$(apos)s software GLES renderer_\
+with gralloc from the DDK._\
+))
+
+
+
+
+# These are set automatically according to the platform version.
+$(eval $(call TunableBothConfigMake,SUPPORT_NATIVE_FENCE_SYNC,))
+
+# These are user-tunable.
+
+
+
+$(eval $(call TunableKernelConfigC,ADF_FBDEV_NUM_PREFERRED_BUFFERS,))
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/features.mk b/drivers/gpu/rogue_m/build/linux/common/android/features.mk
new file mode 100644 (file)
index 0000000..ced4df3
--- /dev/null
@@ -0,0 +1,312 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Basic support option tuning for Android
+#
+SUPPORT_ANDROID_PLATFORM := 1
+SUPPORT_OPENGLES1_V1_ONLY := 1
+DONT_USE_SONAMES := 1
+
+# Always print debugging after 5 seconds of no activity
+#
+CLIENT_DRIVER_DEFAULT_WAIT_RETRIES := 50
+
+# Android WSEGL is always the same
+#
+OPK_DEFAULT := libpvrANDROID_WSEGL.so
+
+# srvkm is always built
+#
+KERNEL_COMPONENTS := srvkm
+
+# Kernel modules are always installed here under Android
+#
+# Time:2014-08-26 
+# Note:change module's path from /system/modules/ to /system/lib/modules/
+# Modifier: zxl
+PVRSRV_MODULE_BASEDIR := /system/lib/modules/
+
+# Enable secure FD export in Services
+#
+SUPPORT_SECURE_EXPORT := 1
+
+# Disable multi sync support in Services
+#
+SUPPORT_MULTI_SYNC := 0
+
+# It is no longer supported disable this for Android, but we can still
+# do so for the Linux DDK, so don't use NonTunableOption.
+#
+override SUPPORT_ION := 1
+
+# Show GPU activity in systrace
+#
+SUPPORT_GPUTRACE_EVENTS ?= 1
+
+##############################################################################
+# Unless overridden by the user, assume the RenderScript Compute API level
+# matches that of the SDK API_LEVEL.
+#
+RSC_API_LEVEL ?= $(API_LEVEL)
+ifneq ($(findstring $(RSC_API_LEVEL),21 22),)
+RSC_API_LEVEL := 20
+endif
+
+##############################################################################
+# JB MR1 introduces cross-process syncs associated with a fd.
+# This requires a new enough kernel version to have the base/sync driver.
+#
+#zxl:Temporarily closed for user build mode(Depend on libgui: LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC)
+EGL_EXTENSION_ANDROID_NATIVE_FENCE_SYNC ?= 1
+
+ifeq ($(PDUMP),1)
+# PDUMPs won't process if any native synchronization is enabled
+override EGL_EXTENSION_ANDROID_NATIVE_FENCE_SYNC := 0
+override SUPPORT_NATIVE_FENCE_SYNC := 0
+override PVR_ANDROID_DEFER_CLEAR := 0
+else
+override SUPPORT_NATIVE_FENCE_SYNC := 1
+endif
+
+##############################################################################
+# Handle various platform includes
+#
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/external/zlib/src \
+ -isystem $(ANDROID_ROOT)/libnativehelper/include/nativehelper
+SYS_KHRONOS_INCLUDES += \
+ -I$(ANDROID_ROOT)/frameworks/native/opengl/include
+
+##############################################################################
+# Android doesn't use these install script variables. They're still in place
+# because the Linux install scripts use them.
+#
+SHLIB_DESTDIR := not-used
+EGL_DESTDIR := not-used
+
+# Must give our EGL/GLES libraries a globally unique name
+#
+EGL_BASENAME_SUFFIX := _POWERVR_ROGUE
+
+##############################################################################
+# In K and older, augment the libstdc++ includes with stlport includes. Any
+# part of the C++ library not implemented by stlport will be handled by
+# linking in libstdc++ too (see extra_config.mk).
+#
+# On L and newer, don't use stlport OR libstdc++ at all; just use libc++.
+#
+SYS_CXXFLAGS := -fuse-cxa-atexit $(SYS_CFLAGS)
+ifeq ($(is_at_least_lollipop),1)
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/external/libcxx/include
+else
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/bionic \
+ -isystem $(ANDROID_ROOT)/external/stlport/stlport
+endif
+
+##############################################################################
+# ICS requires that at least one driver EGLConfig advertises the
+# EGL_RECORDABLE_ANDROID attribute. The platform requires that surfaces
+# rendered with this config can be consumed by an OMX video encoder.
+#
+EGL_EXTENSION_ANDROID_RECORDABLE := 1
+
+##############################################################################
+# ICS added the EGL_ANDROID_blob_cache extension. Enable support for this
+# extension in EGL/GLESv2.
+#
+EGL_EXTENSION_ANDROID_BLOB_CACHE ?= 1
+
+##############################################################################
+# Framebuffer target extension is used to find configs compatible with
+# the framebuffer
+#
+EGL_EXTENSION_ANDROID_FRAMEBUFFER_TARGET := 1
+
+##############################################################################
+# Disable the MEMINFO wrapper pvCpuVirtAddr feature. All Android DDK
+# components no longer require it. This enables lazy CPU mappings, which
+# improves allocation performance.
+#
+ifneq ($(PDUMP),1)
+PVRSRV_NO_MEMINFO_CPU_VIRT_ADDR ?= 1
+endif
+
+##############################################################################
+# JB added a new corkscrew API for userland backtracing.
+#
+ifeq ($(is_at_least_lollipop),0)
+PVR_ANDROID_HAS_CORKSCREW_API := 1
+endif
+
+##############################################################################
+# This is currently broken on KK. Disable until fixed.
+#
+SUPPORT_ANDROID_APPHINTS := 0
+
+##############################################################################
+# KitKat added very provisional/early support for sRGB render targets
+#
+# (Leaving this optional until the framework makes it mandatory.)
+#
+PVR_ANDROID_HAS_HAL_PIXEL_FORMAT_sRGB ?= 1
+
+##############################################################################
+# Switch on ADF support for KitKat MR1 or newer.
+#
+# Customers using AOSP KitKat MR1 sources need to copy and build the libadf
+# and libadfhwc libraries from AOSP master system/core into their device/
+# directories and build the components as dynamic libraries. Examples of how
+# to do this are shown in the bundled 'pc_android' and 'generic_arm_android'
+# directories in the device package.
+#
+# Customers using AOSP master do not need to make any changes.
+# ADF requires kernel/common derivative kernels >= 3.10.
+#
+ifeq ($(is_at_least_kitkat_mr1),1)
+#SUPPORT_ADF ?= 1
+SUPPORT_DISPLAY_CLASS := 0
+else
+SUPPORT_DISPLAY_CLASS ?= 1
+endif
+
+##############################################################################
+# Versions of Android between Cupcake and KitKat MR1 required Java 6.
+#
+ifeq ($(is_at_least_lollipop),0)
+LEGACY_USE_JAVA6 ?= 1
+endif
+
+##############################################################################
+# Versions of Android between ICS and KitKat MR1 used ion .heap_mask instead
+# of .heap_id_mask.
+#
+ifeq ($(is_at_least_lollipop),0)
+PVR_ANDROID_HAS_ION_FIELD_HEAP_MASK := 1
+endif
+
+##############################################################################
+# Lollipop supports 64-bit. Configure BCC to emit both 32-bit and 64-bit LLVM
+# bitcode in the renderscript driver.
+#
+ifeq ($(is_at_least_lollipop),1)
+PVR_ANDROID_BCC_MULTIARCH_SUPPORT := 1
+endif
+
+##############################################################################
+# Lollipop annotates the cursor allocation with USAGE_CURSOR to enable it to
+# be accelerated with special cursor hardware (rather than wasting an
+# overlay). This flag stops the DDK from blocking the allocation.
+#
+ifeq ($(is_at_least_lollipop),1)
+PVR_ANDROID_HAS_GRALLOC_USAGE_CURSOR := 1
+endif
+
+##############################################################################
+# Lollipop changed the camera HAL metadata specification to require that
+# CONTROL_MAX_REGIONS specifies 3 integers (instead of 1).
+#
+ifeq ($(is_at_least_lollipop),1)
+PVR_ANDROID_CAMERA_CONTROL_MAX_REGIONS_HAS_THREE := 1
+endif
+
+##############################################################################
+# Lollipop adds async versions of the CPU access functions to gralloc.
+#
+ifeq ($(is_at_least_lollipop),1)
+PVR_ANDROID_HAS_GRALLOC_ASYNC_LOCK := 1
+endif
+
+##############################################################################
+# Marshmallow needs --soname turned on
+#
+ifeq ($(is_at_least_marshmallow),1)
+PVR_ANDROID_NEEDS_SONAME ?= 1
+endif
+
+##############################################################################
+# Marshmallow replaces RAW_SENSOR with RAW10, RAW12 and RAW16
+#
+ifeq ($(is_at_least_marshmallow),1)
+PVR_ANDROID_HAS_HAL_PIXEL_FORMAT_RAWxx := 1
+endif
+
+##############################################################################
+# Marshmallow has redesigned sRGB support
+#
+ifeq ($(is_at_least_marshmallow),1)
+PVR_ANDROID_HAS_SET_BUFFERS_DATASPACE ?= 1
+PVR_ANDROID_HAS_HAL_PIXEL_FORMAT_sRGB := 0
+endif
+
+##############################################################################
+# fenv was rewritten in Marshmallow
+#
+ifeq ($(is_at_least_marshmallow),1)
+PVR_ANDROID_HAS_WORKING_FESETROUND := 1
+endif
+
+##############################################################################
+# Marshmallow renderscript support
+#
+ifeq ($(is_at_least_marshmallow),1)
+# Bump the RenderScript API level to 23 for future versions
+# API_LEVEL itself shouldn't be touched.
+RSC_API_LEVEL := 23
+
+# RenderScript header file was moved in AOSP master
+PVR_ANDROID_HAS_RS_INTERNAL_DEFINES := 1
+
+# LLVM's MemoryBuffer is now passed via reference
+PVR_ANDROID_HAS_RS_MEMBUFFER_REF := 1
+
+# RenderScript ScriptGroup API has ScriptGroupBase instead of ScriptGroup
+PVR_ANDROID_HAS_SCRIPTGROUPBASE := 1
+
+# RenderScript elementData API is generic
+PVR_ANDROID_POST_L_HAL := 1
+endif
+
+# Placeholder for future version handling
+#
+ifeq ($(is_future_version),1)
+-include ../common/android/future_version.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/install.sh.tpl b/drivers/gpu/rogue_m/build/linux/common/android/install.sh.tpl
new file mode 100644 (file)
index 0000000..b949c8c
--- /dev/null
@@ -0,0 +1,323 @@
+#!/bin/bash
+############################################################################ ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#### ###########################################################################
+# Help on how to invoke
+#
+function usage {
+    echo "usage: $0 [options...]"
+    echo ""
+    echo "Options: -v            Verbose mode."
+    echo "         -n            Dry-run mode."
+    echo "         -u            Uninstall-only mode."
+    echo "         --root <path> Use <path> as the root of the install file system."
+    echo "                       (Overrides the DISCIMAGE environment variable.)"
+    exit 1
+}
+
+WD=`pwd`
+SCRIPT_ROOT=`dirname $0`
+cd $SCRIPT_ROOT
+
+PVRVERSION=[PVRVERSION]
+PVRBUILD=[PVRBUILD]
+PRIMARY_ARCH="[PRIMARY_ARCH]"
+ARCHITECTURES="[ARCHITECTURES]"
+
+# These destination directories are the same for 32- or 64-bit binaries.
+# zxl: change module's path from /system/modules/ to /system/lib/modules/
+MOD_DESTDIR=/system/lib/modules
+BIN_DESTDIR=/system/vendor/bin
+DATA_DESTDIR=${BIN_DESTDIR}
+
+# Exit with an error messages.
+# $1=blurb
+#
+function bail {
+    if [ ! -z "$1" ]; then
+        echo "$1" >&2
+    fi
+
+    echo "" >&2
+    echo "Installation failed" >&2
+    exit 1
+}
+
+# Copy all the required files into their appropriate places on the local machine.
+function install_locally {
+    # Define functions required for local installs
+
+    # basic installation function
+    # $1=fromfile, $2=destfilename, $3=blurb, $4=chmod-flags, $5=chown-flags
+    #
+    function install_file {
+        if [ -z "$DDK_INSTALL_LOG" ]; then
+            bail "INTERNAL ERROR: Invoking install without setting logfile name"
+        fi
+        DESTFILE=${DISCIMAGE}$2
+        DESTDIR=`dirname $DESTFILE`
+    
+        if [ ! -e $1 ]; then
+            [ -n "$VERBOSE" ] && echo "skipping file $1 -> $2"
+            return
+        fi
+        
+        # Destination directory - make sure it's there and writable
+        #
+        if [ -d "${DESTDIR}" ]; then
+            if [ ! -w "${DESTDIR}" ]; then
+                bail "${DESTDIR} is not writable."
+            fi
+        else
+            $DOIT mkdir -p ${DESTDIR} || bail "Couldn't mkdir -p ${DESTDIR}"
+            [ -n "$VERBOSE" ] && echo "Created directory `dirname $2`"
+        fi
+    
+        # Delete the original so that permissions don't persist.
+        #
+        $DOIT rm -f $DESTFILE
+    
+        $DOIT cp -f $1 $DESTFILE || bail "Couldn't copy $1 to $DESTFILE"
+        $DOIT chmod $4 ${DESTFILE}
+    
+        echo "$3 `basename $1` -> $2"
+        $DOIT echo "file $2" >> $DDK_INSTALL_LOG
+    }
+
+       # Android-specific targetfs mkdir workarounds
+       if [ ! -d ${DISCIMAGE}/data ]; then
+               mkdir ${DISCIMAGE}/data
+               chown 1000:1000 ${DISCIMAGE}/data
+               chmod 0771 ${DISCIMAGE}/data
+       fi
+       if [ ! -d ${DISCIMAGE}/data/app ]; then
+               mkdir ${DISCIMAGE}/data/app
+               chown 1000:1000 ${DISCIMAGE}/data/app
+               chmod 0771 ${DISCIMAGE}/data/app
+       fi
+
+    for arch in $ARCHITECTURES; do
+        if [ ! -d $arch ]; then
+            echo "Unknown architecture $arch.  Aborting"
+            #exit 1
+        fi
+
+        case $arch in
+            target*64)
+                SHLIB_DESTDIR=/system/vendor/lib64
+                ;;
+            *)
+                SHLIB_DESTDIR=/system/vendor/lib
+        esac
+        EGL_DESTDIR=${SHLIB_DESTDIR}/egl
+
+        pushd $arch > /dev/null
+        # Install UM components
+        if [ -f install_um.sh ]; then
+            DDK_INSTALL_LOG=$UMLOG
+            echo "Installing User components for architecture $arch"
+            $DOIT echo "version $PVRVERSION" > $DDK_INSTALL_LOG
+            source install_um.sh
+            echo 
+        fi
+        popd > /dev/null
+    done
+
+    pushd $PRIMARY_ARCH > /dev/null
+    # Install KM components
+    if [ -f install_km.sh ]; then
+        DDK_INSTALL_LOG=$KMLOG
+        echo "Installing Kernel components for architecture $PRIMARY_ARCH"
+        $DOIT echo "version $PVRVERSION" > $DDK_INSTALL_LOG
+        source install_km.sh
+        echo
+    fi
+    popd > /dev/null
+
+       $DOIT mkdir -p ${DISCIMAGE}/system/lib/egl
+       $DOIT cat >${DISCIMAGE}/system/lib/egl/egl.cfg <<EOF
+0 0 POWERVR_ROGUE
+EOF
+       $DOIT echo "file /system/lib/egl/egl.cfg" >> $DDK_INSTALL_LOG
+
+    # Create an OLDLOG so old versions of the driver can uninstall.
+    $DOIT echo "version $PVRVERSION" > $OLDLOG
+    if [ -f $KMLOG ]; then
+        tail -n +2 $KMLOG >> $OLDLOG
+    fi
+    if [ -f $UMLOG ]; then
+        tail -n +2 $UMLOG >> $OLDLOG
+    fi
+    
+    # Make sure new logs are newer than $OLDLOG
+    touch -m -d "last sunday" $OLDLOG
+}
+
+# Read the appropriate install log and delete anything therein.
+function uninstall_locally {
+    # Function to uninstall something.
+    function do_uninstall {
+        LOG=$1
+
+        if [ ! -f $LOG ]; then
+            echo "Nothing to un-install."
+            return;
+        fi
+    
+        BAD=0
+        VERSION=""
+        while read type data; do
+            case $type in
+            version)
+                echo "Uninstalling existing version $data"
+                VERSION="$data"
+                ;;
+            link|file) 
+                if [ -z "$VERSION" ]; then
+                    BAD=1;
+                    echo "No version record at head of $LOG"
+                elif ! $DOIT rm -f ${DISCIMAGE}${data}; then
+                    BAD=1;
+                else
+                    [ -n "$VERBOSE" ] && echo "Deleted $type $data"
+                fi
+                ;;
+            tree)
+                ;;
+            esac
+        done < $1;
+
+        if [ $BAD = 0 ]; then
+            echo "Uninstallation completed."
+            $DOIT rm -f $LOG
+        else
+            echo "Uninstallation failed!!!"
+        fi
+    }
+
+    if [ -z "$OLDLOG" -o -z "$KMLOG" -o -z "$UMLOG" ]; then
+        bail "INTERNAL ERROR: Invoking uninstall without setting logfile name"
+    fi
+
+    # Uninstall anything installed using the old-style install scripts.
+    LEGACY_LOG=0
+    if [ -f $OLDLOG ]; then
+        if [ -f $KMLOG -a $KMLOG -nt $OLDLOG ]; then
+            # Last install was new scheme.
+            rm $OLDLOG
+        elif [ -f $UMLOG -a $UMLOG -nt $OLDLOG ]; then
+            # Last install was new scheme.
+            rm $OLDLOG
+        else
+            echo "Uninstalling all components from legacy log."
+            do_uninstall $OLDLOG
+            LEGACY_LOG=1
+            echo 
+        fi
+    fi
+
+    if [ $LEGACY_LOG = 0 ]; then
+        # Uninstall KM components if we are doing a KM install.
+        if [ -f install_km.sh -a -f $KMLOG ]; then
+            echo "Uninstalling Kernel components"
+            do_uninstall $KMLOG
+            echo 
+        fi
+        # Uninstall UM components if we are doing a UM install.
+        if [ -f install_um.sh -a -f $UMLOG ]; then
+            echo "Uninstalling User components"
+            do_uninstall $UMLOG
+            echo 
+        fi
+    fi
+}
+
+# Work out if there are any special instructions.
+#
+while [ "$1" ]; do
+    case "$1" in
+    -v|--verbose)
+        VERBOSE=v
+        ;;
+    -r|--root)
+        DISCIMAGE=$2
+        shift;
+        ;;
+    -u|--uninstall)
+        UNINSTALL_ONLY=y
+        ;;
+    -n)
+        DOIT=echo
+        ;;
+    -h | --help | *)
+        usage
+        ;;
+    esac
+    shift
+done
+
+if [ ! -z "$DISCIMAGE" ]; then
+
+    if [ ! -d "$DISCIMAGE" ]; then
+       bail "$0: $DISCIMAGE does not exist."
+    fi
+
+    echo
+    if [ $DISCIMAGE == "/" ]; then
+        echo "Installing PowerVR '$PVRVERSION ($PVRBUILD)' locally"
+    else
+        echo "Installing PowerVR '$PVRVERSION ($PVRBUILD)' on $DISCIMAGE"
+    fi
+    echo
+    echo "File system installation root is $DISCIMAGE"
+    echo
+
+    OLDLOG=$DISCIMAGE/powervr_ddk_install.log
+    KMLOG=$DISCIMAGE/powervr_ddk_install_km.log
+    UMLOG=$DISCIMAGE/powervr_ddk_install_um.log
+
+    uninstall_locally
+
+    if [ "$UNINSTALL_ONLY" != "y" ]; then
+        install_locally
+    fi
+
+else
+    bail "DISCIMAGE must be set for installation to be possible."
+fi
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/paths.mk b/drivers/gpu/rogue_m/build/linux/common/android/paths.mk
new file mode 100644 (file)
index 0000000..6cc7cc7
--- /dev/null
@@ -0,0 +1,52 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+TARGET_BUILD_TYPE ?= release
+
+HOST_OS ?= linux
+HOST_ARCH ?= x86
+
+OUT_DIR ?= $(ANDROID_ROOT)/out
+
+ifeq ($(TARGET_BUILD_TYPE),debug)
+TARGET_ROOT := $(OUT_DIR)/debug/target
+else
+TARGET_ROOT := $(OUT_DIR)/target
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/android/platform_version.mk b/drivers/gpu/rogue_m/build/linux/common/android/platform_version.mk
new file mode 100644 (file)
index 0000000..93d4800
--- /dev/null
@@ -0,0 +1,172 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# If there's no build.prop file in the expected location, bail out. Tell the
+# user which file we were trying to read in case TARGET_DEVICE was not set.
+#
+BUILD_PROP := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/build.prop
+ifeq ($(wildcard $(BUILD_PROP)),)
+$(warning *** Could not determine Android version.  Did you set ANDROID_ROOT,\
+OUT_DIR and TARGET_DEVICE in your environment correctly?)
+$(error Error reading $(BUILD_PROP))
+endif
+
+# Extract version.release and version.codename from the build.prop file.
+# If either of the values aren't in the build.prop, the Make variables won't
+# be defined, and fallback handling will take place.
+#
+define newline
+
+
+endef
+$(eval $(subst #,$(newline),$(shell cat $(BUILD_PROP) | \
+       grep '^ro.build.version.release=\|^ro.build.version.codename=' | \
+       sed -e 's,ro.build.version.release=,PLATFORM_RELEASE=,' \
+           -e 's,ro.build.version.codename=,PLATFORM_CODENAME=,' | tr '\n' '#')))
+
+define release-starts-with
+$(shell echo $(PLATFORM_RELEASE) | grep -q ^$(1); \
+       [ "$$?" = "0" ] && echo 1 || echo 0)
+endef
+
+# ro.build.version.release contains the version number for release builds, or
+# the version codename otherwise. In this case we need to assume that the
+# version of Android we're building against has the features that are in the
+# final release of that version, so we set PLATFORM_RELEASE to the
+# corresponding release number.
+#
+# NOTE: It's the _string_ ordering that matters here, not the version number
+# ordering. You need to make sure that strings that are sub-strings of other
+# checked strings appear _later_ in this list.
+#
+# e.g. 'KitKatMR' starts with 'KitKat', but it is not KitKat.
+#
+# NOTE: The version codenames for Android stopped after KitKat, don't read
+# too much into the below names. They are mostly placeholders/reminders.
+#
+ifeq ($(call release-starts-with,KitKatMR),1)
+PLATFORM_RELEASE := 4.4.1
+else ifeq ($(call release-starts-with,KitKat),1)
+PLATFORM_RELEASE := 4.4
+else ifeq ($(call release-starts-with,LollipopMR1),1)
+PLATFORM_RELEASE := 5.1
+else ifeq ($(call release-starts-with,Lollipop),1)
+PLATFORM_RELEASE := 5.0
+else ifeq ($(call release-starts-with,Marshmallow),1)
+PLATFORM_RELEASE := 6.0
+else ifeq ($(PLATFORM_CODENAME),AOSP)
+# AOSP (master) will normally have PLATFORM_CODENAME set to AOSP
+PLATFORM_RELEASE := 6.0.60
+else ifeq ($(shell echo $(PLATFORM_RELEASE) | grep -qE "[A-Za-z]+"; echo $$?),0)
+PLATFORM_RELEASE := 6.1
+endif
+
+# Workaround for master. Sometimes there is an AOSP version ahead of
+# the current master version number, but master still has more features.
+#
+ifeq ($(PLATFORM_RELEASE),6.0.60)
+PLATFORM_RELEASE := 6.1
+is_aosp_master := 1
+endif
+
+PLATFORM_RELEASE_MAJ   := $(shell echo $(PLATFORM_RELEASE) | cut -f1 -d'.')
+PLATFORM_RELEASE_MIN   := $(shell echo $(PLATFORM_RELEASE) | cut -f2 -d'.')
+PLATFORM_RELEASE_PATCH := $(shell echo $(PLATFORM_RELEASE) | cut -f3 -d'.')
+
+# Not all versions have a patchlevel; fix that up here
+#
+ifeq ($(PLATFORM_RELEASE_PATCH),)
+PLATFORM_RELEASE_PATCH := 0
+endif
+
+# Macros to help categorize support for features and API_LEVEL for tests.
+#
+is_at_least_kitkat := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -gt 4 || \
+                               ( test $(PLATFORM_RELEASE_MAJ) -eq 4 && \
+                                 test $(PLATFORM_RELEASE_MIN) -ge 4 ) ) && echo 1 || echo 0)
+is_at_least_kitkat_mr1 := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -gt 4 || \
+                               ( test $(PLATFORM_RELEASE_MAJ) -eq 4 && \
+                                 test $(PLATFORM_RELEASE_MIN) -gt 4 ) || \
+                                       ( test $(PLATFORM_RELEASE_MAJ) -eq 4 && \
+                                         test $(PLATFORM_RELEASE_MIN) -eq 4 && \
+                                         test $(PLATFORM_RELEASE_PATCH) -ge 1 ) ) && echo 1 || echo 0)
+is_at_least_lollipop := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -ge 5 ) && echo 1 || echo 0)
+is_at_least_lollipop_mr1 := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -gt 5 || \
+                               ( test $(PLATFORM_RELEASE_MAJ) -eq 5 && \
+                                 test $(PLATFORM_RELEASE_MIN) -gt 0 ) ) && echo 1 || echo 0)
+is_at_least_marshmallow := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -ge 6 ) && echo 1 || echo 0)
+
+# Assume "future versions" are >6.0, but we don't really know
+is_future_version := \
+       $(shell ( test $(PLATFORM_RELEASE_MAJ) -gt 6 || \
+                               ( test $(PLATFORM_RELEASE_MAJ) -eq 6 && \
+                                 test $(PLATFORM_RELEASE_MIN) -gt 0 ) ) && echo 1 || echo 0)
+
+# Picking an exact match of API_LEVEL for the platform we're building
+# against can avoid compatibility theming and affords better integration.
+#
+ifeq ($(is_future_version),1)
+API_LEVEL := 23
+else ifeq ($(is_at_least_marshmallow),1)
+API_LEVEL := 23
+else ifeq ($(is_at_least_lollipop_mr1),1)
+API_LEVEL := 22
+else ifeq ($(is_at_least_lollipop),1)
+API_LEVEL := 21
+#API_LEVEL := 20 was l-preview
+else ifeq ($(is_at_least_kitkat),1)
+API_LEVEL := 19
+else
+$(error Must build against Android >= 4.4)
+endif
+
+# Each DDK is tested against only a single version of the platform.
+# Warn if a different platform version is used.
+#
+ifeq ($(is_future_version),1)
+$(info WARNING: Android version is newer than this DDK supports)
+else ifneq ($(is_at_least_kitkat),1)
+$(info WARNING: Android version is older than this DDK supports)
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/common/pvrgdb.mk b/drivers/gpu/rogue_m/build/linux/common/pvrgdb.mk
new file mode 100644 (file)
index 0000000..b5f84d4
--- /dev/null
@@ -0,0 +1,40 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
diff --git a/drivers/gpu/rogue_m/build/linux/common/testchip.mk b/drivers/gpu/rogue_m/build/linux/common/testchip.mk
new file mode 100644 (file)
index 0000000..80b9672
--- /dev/null
@@ -0,0 +1,70 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifeq ($(RGX_BVNC),1.82.4.5)
+ $(eval $(call TunableKernelConfigC,TC_APOLLO_ES2,1))
+endif
+
+ifeq ($(RGX_BVNC),12.4.1.48)
+ $(eval $(call TunableKernelConfigC,TC_APOLLO_TCF5,1))
+endif
+
+ifeq ($(RGX_BVNC),4.31.4.55)
+ $(eval $(call TunableKernelConfigC,TC_APOLLO_BONNIE,1))
+endif
+
+ifeq ($(PVR_SYSTEM),$(filter $(PVR_SYSTEM),rgx_tc rgx_tc_es2 plato))
+$(eval $(call TunableKernelConfigC,TC_MEMORY_CONFIG,$(TC_MEMORY_CONFIG),\
+Selects the memory configuration to be used. The choices are:_\
+* TC_MEMORY_LOCAL (Rogue and the display controller use local card memory)_\
+* TC_MEMORY_HOST (Rogue and the display controller use system memory)_\
+* TC_MEMORY_HYBRID (Rogue uses system memory and the display controller uses local card memory)))
+endif
+ifeq ($(PVR_SYSTEM), rgx_linux_apollo)
+$(eval $(call BothConfigC,TC_MEMORY_CONFIG,TC_MEMORY_LOCAL))
+$(call $(NonTunableOption,TC_MEMORY_CONFIG))
+endif
+
+ifeq ($(TC_MEMORY_CONFIG),TC_MEMORY_LOCAL)
+LMA := 1
+endif
+
+$(eval $(call TunableBothConfigC,LMA,))
+$(eval $(call TunableKernelConfigMake,LMA,))
diff --git a/drivers/gpu/rogue_m/build/linux/config/compiler.mk b/drivers/gpu/rogue_m/build/linux/config/compiler.mk
new file mode 100644 (file)
index 0000000..c1384ea
--- /dev/null
@@ -0,0 +1,194 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Check for valid values of $(MULTIARCH).
+ifeq ($(strip $(MULTIARCH)),0)
+$(error MULTIARCH must be empty to disable multiarch)
+endif
+
+define calculate-compiler-preferred-target
+ ifeq ($(2),qcc)
+  $(1)_compiler_preferred_target := qcc
+ else
+  $(1)_compiler_preferred_target := $$(shell $(2) -dumpmachine)
+  ifeq ($$($(1)_compiler_preferred_target),)
+   $$(warning No output from '$(2) -dumpmachine')
+   $$(warning Check that the compiler is in your PATH and CROSS_COMPILE is)
+   $$(warning set correctly.)
+   $$(error Unable to run compiler '$(2)')
+  endif
+  ifneq ($$(filter x86_64-%,$$($(1)_compiler_preferred_target)),)
+   $(1)_compiler_preferred_target := x86_64-linux-gnu
+  endif
+  ifneq ($$(filter i386-% i486-% i686-%,$$($(1)_compiler_preferred_target)),)
+   $(1)_compiler_preferred_target := i386-linux-gnu
+  endif
+  ifneq ($$(filter armv7a-cros-linux-gnueabi,$$($(1)_compiler_preferred_target)),)
+   $(1)_compiler_preferred_target := arm-linux-gnueabi
+  endif
+ endif
+endef
+
+define cross-compiler-name
+ ifeq ($$(origin CC),file)
+  $(1) := $(2)$(3)
+ else
+  ifeq ($$(_CLANG),true)
+   $(1) := $(3) -target $$(patsubst %-,%,$(2))
+  else
+   $(1) := $(3)
+  endif
+ endif
+endef
+
+# Work out the host compiler architecture
+$(eval $(call calculate-compiler-preferred-target,host,$(HOST_CC)))
+
+ifeq ($(host_compiler_preferred_target),x86_64-linux-gnu)
+ HOST_PRIMARY_ARCH := host_x86_64
+ HOST_32BIT_ARCH   := host_i386
+ HOST_FORCE_32BIT  := -m32
+else
+ifeq ($(host_compiler_preferred_target),i386-linux-gnu)
+ HOST_PRIMARY_ARCH := host_i386
+ HOST_32BIT_ARCH   := host_i386
+else
+ $(error Unknown host compiler target architecture $(host_compiler_preferred_target))
+endif
+endif
+
+# Workaround our lack of support for non-Linux HOST_CCs
+ifneq ($(HOST_CC_IS_LINUX),1)
+ $(warning $$(HOST_CC) is non-Linux. Trying to work around.)
+ override HOST_CC := $(HOST_CC) -D__linux__
+ $(eval $(call BothConfigMake,HOST_CC,$(HOST_CC)))
+endif
+
+$(eval $(call BothConfigMake,HOST_PRIMARY_ARCH,$(HOST_PRIMARY_ARCH)))
+$(eval $(call BothConfigMake,HOST_32BIT_ARCH,$(HOST_32BIT_ARCH)))
+$(eval $(call BothConfigMake,HOST_FORCE_32BIT,$(HOST_FORCE_32BIT)))
+
+TARGET_ALL_ARCH := 
+TARGET_PRIMARY_ARCH :=
+TARGET_SECONDARY_ARCH :=
+
+# Work out the target compiler cross triple, and include the corresponding
+# compilers/*.mk file, which sets TARGET_PRIMARY_ARCH and
+# TARGET_SECONDARY_ARCH for that compiler.
+#
+compilers := ../config/compilers
+define include-compiler-file
+ ifeq ($(strip $(1)),)
+  $$(error empty arg passed to include-compiler-file)
+ endif
+ ifeq ($$(wildcard $$(compilers)/$(1).mk),)
+  $$(warning ******************************************************)
+  $$(warning Compiler target '$(1)' not recognised)
+  $$(warning (missing $$(compilers)/$(1).mk file))
+  $$(warning ******************************************************)
+  $$(error Compiler '$(1)' not recognised)
+ endif
+ include $$(compilers)/$(1).mk
+endef
+
+# Check the kernel cross compiler to work out which architecture it targets.
+# We can then tell if CROSS_COMPILE targets a different architecture.
+ifneq ($(origin KERNEL_CROSS_COMPILE),undefined)
+ # First, calculate the value of KERNEL_CROSS_COMPILE as it would be seen by
+ # the main build, so we can check it here in the config stage.
+ $(call one-word-only,KERNEL_CROSS_COMPILE)
+ _kernel_cross_compile := $(if $(filter undef,$(KERNEL_CROSS_COMPILE)),,$(KERNEL_CROSS_COMPILE))
+ # We can take shortcuts with KERNEL_CROSS_COMPILE, as we don't want to
+ # respect CC and we don't support clang in that part currently.
+ _kernel_cross_compile := $(_kernel_cross_compile)gcc
+ # Then check the compiler.
+ $(eval $(call calculate-compiler-preferred-target,target,$(_kernel_cross_compile)))
+ $(eval $(call include-compiler-file,$(target_compiler_preferred_target)))
+ _kernel_primary_arch := $(TARGET_PRIMARY_ARCH)
+else
+ # We can take shortcuts with KERNEL_CROSS_COMPILE, as we don't want to
+ # respect CC and we don't support clang in that part currently.
+ _kernel_cross_compile := $(CROSS_COMPILE)gcc
+ # KERNEL_CROSS_COMPILE will be the same as CROSS_COMPILE, so we don't need
+ # to do the compatibility check.
+ _kernel_primary_arch :=
+endif
+
+$(eval $(call cross-compiler-name,_cc,$(CROSS_COMPILE),$(CC)))
+$(eval $(call cross-compiler-name,_cc_secondary,$(if $(CROSS_COMPILE_SECONDARY),$(CROSS_COMPILE_SECONDARY),$(CROSS_COMPILE)),$(CC_SECONDARY)))
+$(eval $(call calculate-compiler-preferred-target,target,$(_cc)))
+$(eval $(call include-compiler-file,$(target_compiler_preferred_target)))
+
+# Sanity check: if KERNEL_CROSS_COMPILE was set, it has to target the same
+# architecture as CROSS_COMPILE.
+ifneq ($(_kernel_primary_arch),)
+ ifneq ($(TARGET_PRIMARY_ARCH),$(_kernel_primary_arch))
+  $(warning ********************************************************)
+  $(warning Error: Kernel and user-mode cross compilers build for)
+  $(warning different targets)
+  $(warning $(space)$(space)CROSS_COMPILE=$(CROSS_COMPILE))
+  $(warning $(space)$(space)$(space)builds for $(TARGET_PRIMARY_ARCH))
+  $(warning $(space)$(space)KERNEL_CROSS_COMPILE=$(KERNEL_CROSS_COMPILE))
+  $(warning $(space)$(space)$(space)builds for $(_kernel_primary_arch))
+  $(warning ********************************************************)
+  $(error Mismatching kernel and user-mode cross compilers)
+ endif
+endif
+
+ifneq ($(MULTIARCH),32only)
+TARGET_ALL_ARCH += $(TARGET_PRIMARY_ARCH)
+endif
+ifneq ($(MULTIARCH),64only)
+TARGET_ALL_ARCH += $(TARGET_SECONDARY_ARCH)
+endif
+
+$(eval $(call BothConfigMake,TARGET_PRIMARY_ARCH,$(TARGET_PRIMARY_ARCH)))
+$(eval $(call BothConfigMake,TARGET_SECONDARY_ARCH,$(TARGET_SECONDARY_ARCH)))
+$(eval $(call BothConfigMake,TARGET_ALL_ARCH,$(TARGET_ALL_ARCH)))
+$(eval $(call BothConfigMake,TARGET_FORCE_32BIT,$(TARGET_FORCE_32BIT)))
+
+$(info ******* Multiarch build: $(if $(MULTIARCH),yes,no))
+$(info ******* Primary arch:    $(if $(TARGET_PRIMARY_ARCH),$(TARGET_PRIMARY_ARCH),none))
+$(info ******* Secondary arch:  $(if $(TARGET_SECONDARY_ARCH),$(TARGET_SECONDARY_ARCH),none))
+
+# Find the paths to libgcc for the primary and secondary architectures.
+LIBGCC := $(shell $(_cc) -print-libgcc-file-name)
+LIBGCC_SECONDARY := $(shell $(_cc_secondary) $(TARGET_FORCE_32BIT) -print-libgcc-file-name)
diff --git a/drivers/gpu/rogue_m/build/linux/config/compilers/aarch64-linux-android.mk b/drivers/gpu/rogue_m/build/linux/config/compilers/aarch64-linux-android.mk
new file mode 100644 (file)
index 0000000..97136fe
--- /dev/null
@@ -0,0 +1,12 @@
+# 64-bit Android AArch64 compiler
+TARGET_PRIMARY_ARCH := target_aarch64
+ifeq ($(MULTIARCH),1)
+ TARGET_SECONDARY_ARCH := target_armv7-a
+ ifneq ($(MAKECMDGOALS),kbuild)
+  ifneq ($(COMPONENTS),)
+   ifeq ($(CROSS_COMPILE_SECONDARY),)
+    $(error CROSS_COMPILE_SECONDARY must be set for multiarch ARM builds)
+   endif
+  endif
+ endif
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/config/compilers/arm-eabi.mk b/drivers/gpu/rogue_m/build/linux/config/compilers/arm-eabi.mk
new file mode 100644 (file)
index 0000000..d671ba9
--- /dev/null
@@ -0,0 +1,2 @@
+# 32-bit ARM EABI compiler
+TARGET_PRIMARY_ARCH := target_armv7-a
diff --git a/drivers/gpu/rogue_m/build/linux/config/compilers/arm-linux-androideabi.mk b/drivers/gpu/rogue_m/build/linux/config/compilers/arm-linux-androideabi.mk
new file mode 100644 (file)
index 0000000..8aaeaad
--- /dev/null
@@ -0,0 +1,2 @@
+# 32-bit Android ARM compiler
+include $(compilers)/arm-eabi.mk
diff --git a/drivers/gpu/rogue_m/build/linux/config/compilers/i386-linux-gnu.mk b/drivers/gpu/rogue_m/build/linux/config/compilers/i386-linux-gnu.mk
new file mode 100644 (file)
index 0000000..cd9539c
--- /dev/null
@@ -0,0 +1,2 @@
+# 32-bit x86 compiler
+TARGET_PRIMARY_ARCH   := target_i686
diff --git a/drivers/gpu/rogue_m/build/linux/config/compilers/x86_64-linux-gnu.mk b/drivers/gpu/rogue_m/build/linux/config/compilers/x86_64-linux-gnu.mk
new file mode 100644 (file)
index 0000000..008e86b
--- /dev/null
@@ -0,0 +1,29 @@
+# 64-bit x86 compiler
+TARGET_FORCE_32BIT := -m32
+
+ifneq ($(KERNELDIR),)
+ ifneq ($(ARCH),i386)
+  ifeq ($(shell grep -q "CONFIG_X86_32=y" $(KERNELDIR)/.config && echo 1 || echo 0),1)
+   $(warning ******************************************************)
+   $(warning Your kernel appears to be configured for 32-bit x86,)
+   $(warning but CROSS_COMPILE (or KERNEL_CROSS_COMPILE) points)
+   $(warning to a 64-bit compiler.)
+   $(warning If you want a 32-bit build, either set CROSS_COMPILE)
+   $(warning to point to a 32-bit compiler, or build with ARCH=i386)
+   $(warning to force 32-bit mode with your existing compiler.)
+   $(warning ******************************************************)
+   $(error Invalid CROSS_COMPILE / kernel architecture combination)
+  endif # CONFIG_X86_32
+ endif # ARCH=i386
+endif # KERNELDIR
+
+# If ARCH=i386 is set, force a build for 32-bit only, even though we're
+# using a 64-bit compiler.
+ifeq ($(ARCH),i386)
+ include $(compilers)/i386-linux-gnu.mk
+else
+ TARGET_PRIMARY_ARCH := target_x86_64
+ ifeq ($(MULTIARCH),1)
+  TARGET_SECONDARY_ARCH := target_i686
+ endif # MULTIARCH
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/config/core.mk b/drivers/gpu/rogue_m/build/linux/config/core.mk
new file mode 100644 (file)
index 0000000..4941210
--- /dev/null
@@ -0,0 +1,862 @@
+########################################################################### ###
+#@File
+#@Title         Root build configuration.
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Configuration wrapper for new build system. This file deals with
+# configuration of the build. Add to this file anything that deals
+# with switching driver options on/off and altering the defines or
+# objects the build uses.
+#
+# At the end of this file is an exhaustive list of all variables
+# that are passed between the platform/config stage and the generic
+# build. PLEASE refrain from adding more variables than necessary
+# to this stage -- almost all options can go through config.h.
+#
+
+# Sanity check: Make sure preconfig has been included
+ifeq ($(TOP),)
+$(error TOP not defined: Was preconfig.mk included in root makefile?)
+endif
+
+################################# MACROS ####################################
+
+ALL_TUNABLE_OPTIONS :=
+
+# This records the config option's help text and default value. Note that
+# the help text can't contain a literal comma. Use $(comma) instead.
+define RegisterOptionHelp
+ALL_TUNABLE_OPTIONS += $(1)
+ifeq ($(INTERNAL_DESCRIPTION_FOR_$(1)),)
+INTERNAL_DESCRIPTION_FOR_$(1) := $(3)
+endif
+INTERNAL_CONFIG_DEFAULT_FOR_$(1) := $(2)
+$(if $(4),\
+       $(error Too many arguments in config option '$(1)' (stray comma in help text?)))
+endef
+
+# Write out a kernel GNU make option.
+#
+define KernelConfigMake
+$$(shell echo "override $(1) := $(2)" >>$(CONFIG_KERNEL_MK).new)
+$(if $(filter config,$(D)),$(info KernelConfigMake $(1) := $(2)        # $(if $($(1)),$(origin $(1)),default)))
+endef
+
+# Write out a GNU make option for both user & kernel
+#
+define BothConfigMake
+$$(eval $$(call KernelConfigMake,$(1),$(2)))
+$$(eval $$(call UserConfigMake,$(1),$(2)))
+endef
+
+# Conditionally write out a kernel GNU make option
+#
+define _TunableKernelConfigMake
+ifneq ($$($(1)),)
+ifneq ($$($(1)),0)
+$$(eval $$(call KernelConfigMake,$(1),$$($(1))))
+endif
+else
+ifneq ($(2),)
+$$(eval $$(call KernelConfigMake,$(1),$(2)))
+endif
+endif
+endef
+
+define TunableKernelConfigMake
+$$(eval $$(call _TunableKernelConfigMake,$(1),$(2)))
+$(call RegisterOptionHelp,$(1),$(2),$(3),$(4))
+endef
+
+# Conditionally write out a GNU make option for both user & kernel
+#
+define TunableBothConfigMake
+$$(eval $$(call _TunableKernelConfigMake,$(1),$(2)))
+$$(eval $$(call _TunableUserConfigMake,$(1),$(2)))
+$(call RegisterOptionHelp,$(1),$(2),$(3),$(4))
+endef
+
+# Write out a kernel-only option
+#
+define KernelConfigC
+$$(shell echo "#define $(1) $(2)" >>$(CONFIG_KERNEL_H).new)
+$(if $(filter config,$(D)),$(info KernelConfigC    #define $(1) $(2)   /* $(if $($(1)),$(origin $(1)),default) */),)
+endef
+
+# Write out an option for both user & kernel
+#
+define BothConfigC
+$$(eval $$(call KernelConfigC,$(1),$(2)))
+$$(eval $$(call UserConfigC,$(1),$(2)))
+endef
+
+# Conditionally write out a kernel-only option
+#
+define _TunableKernelConfigC
+ifneq ($$($(1)),)
+ifneq ($$($(1)),0)
+ifeq ($$($(1)),1)
+$$(eval $$(call KernelConfigC,$(1),))
+else
+$$(eval $$(call KernelConfigC,$(1),$$($(1))))
+endif
+endif
+else
+ifneq ($(2),)
+ifeq ($(2),1)
+$$(eval $$(call KernelConfigC,$(1),))
+else
+$$(eval $$(call KernelConfigC,$(1),$(2)))
+endif
+endif
+endif
+endef
+
+define TunableKernelConfigC
+$$(eval $$(call _TunableKernelConfigC,$(1),$(2)))
+ALL_TUNABLE_OPTIONS += $(1)
+ifeq ($(INTERNAL_DESCRIPTION_FOR_$(1)),)
+INTERNAL_DESCRIPTION_FOR_$(1) := $(3)
+endif
+INTERNAL_CONFIG_DEFAULT_FOR_$(1) := $(2)
+endef
+
+# Conditionally write out an option for both user & kernel
+#
+define TunableBothConfigC
+$$(eval $$(call _TunableKernelConfigC,$(1),$(2)))
+$$(eval $$(call _TunableUserConfigC,$(1),$(2)))
+$(call RegisterOptionHelp,$(1),$(2),$(3),$(4))
+endef
+
+# Use this to mark config options which have to exist, but aren't
+# user-tunable. Warn if an attempt is made to change it.
+#
+define NonTunableOption
+$(if $(filter command line environment,$(origin $(1))),\
+       $(error Changing '$(1)' is not supported))
+endef
+
+############################### END MACROS ##################################
+
+# Check we have a new enough version of GNU make.
+#
+need := 3.81
+ifeq ($(filter $(need),$(firstword $(sort $(MAKE_VERSION) $(need)))),)
+$(error A version of GNU make >= $(need) is required - this is version $(MAKE_VERSION))
+endif
+
+# Decide whether we need a BVNC
+ifneq ($(COMPILER_BVNC_LIST),)
+ DONT_NEED_RGX_BVNC := 1
+endif
+
+include ../defs.mk
+
+# Infer PVR_BUILD_DIR from the directory configuration is launched from.
+# Check anyway that such a directory exists.
+#
+PVR_BUILD_DIR := $(notdir $(abspath .))
+$(call directory-must-exist,$(TOP)/build/linux/$(PVR_BUILD_DIR))
+
+# Output directory for configuration, object code,
+# final programs/libraries, and install/rc scripts.
+#
+BUILD        ?= release
+ifneq ($(filter $(WINDOW_SYSTEM),xorg wayland nullws nulldrmws ews_drm nulladfws ews_adf screen),)
+OUT          ?= $(TOP)/binary_$(PVR_BUILD_DIR)_$(WINDOW_SYSTEM)_$(BUILD)
+else
+OUT          ?= $(TOP)/binary_$(PVR_BUILD_DIR)_$(BUILD)
+endif
+override OUT := $(if $(filter /%,$(OUT)),$(OUT),$(TOP)/$(OUT))
+
+CONFIG_MK                      := $(OUT)/config.mk
+CONFIG_H                       := $(OUT)/config.h
+CONFIG_KERNEL_MK       := $(OUT)/config_kernel.mk
+CONFIG_KERNEL_H                := $(OUT)/config_kernel.h
+
+# Convert commas to spaces in $(D). This is so you can say "make
+# D=config-changes,freeze-config" and have $(filter config-changes,$(D))
+# still work.
+override D := $(subst $(comma),$(space),$(D))
+
+# Create the OUT directory 
+#
+$(shell mkdir -p $(OUT))
+
+# Some targets don't need information about any modules. If we only specify
+# these targets on the make command line, set INTERNAL_CLOBBER_ONLY to
+# indicate that toplevel.mk shouldn't read any makefiles
+CLOBBER_ONLY_TARGETS := clean clobber help install
+INTERNAL_CLOBBER_ONLY :=
+ifneq ($(strip $(MAKECMDGOALS)),)
+INTERNAL_CLOBBER_ONLY := \
+$(if \
+ $(strip $(foreach _cmdgoal,$(MAKECMDGOALS),\
+          $(if $(filter $(_cmdgoal),$(CLOBBER_ONLY_TARGETS)),,x))),,true)
+endif
+
+# For a clobber-only build, we shouldn't regenerate any config files
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+
+-include ../config/user-defs.mk
+
+#
+# Core handling 
+
+
+# delete any previous intermediary files
+$(shell \
+       for file in $(CONFIG_KERNEL_H).new $(CONFIG_KERNEL_MK).new ; do \
+               rm -f $$file; \
+       done)
+
+ifeq ($(DONT_NEED_RGX_BVNC),)
+ # Extract the BNC config name
+ RGX_BNC_SPLIT := $(subst .,$(space) ,$(RGX_BVNC))
+ RGX_BNC := $(word 1,$(RGX_BNC_SPLIT)).V.$(word 3,$(RGX_BNC_SPLIT)).$(word 4,$(RGX_BNC_SPLIT))
+ # Check BVNC core version
+ ALL_KM_BVNCS := \
+  $(patsubst rgxcore_km_%.h,%,\
+       $(notdir $(shell ls $(TOP)/hwdefs/km/cores/rgxcore_km_*.h)))
+ ifeq ($(filter $(RGX_BVNC),$(ALL_KM_BVNCS)),)
+ $(error Error: Invalid Kernel core RGX_BVNC=$(RGX_BVNC). \
+       Valid Kernel core BVNCs: $(subst $(space),$(comma)$(space),$(ALL_KM_BVNCS)))
+ endif
+ # Check if BVNC core file exist
+ RGX_BVNC_CORE_KM := $(TOP)/hwdefs/km/cores/rgxcore_km_$(RGX_BVNC).h
+ RGX_BVNC_CORE_KM_HEADER := \"cores/rgxcore_km_$(RGX_BVNC).h\" 
+ # "rgxcore_km_$(RGX_BVNC).h"
+ ifeq ($(wildcard $(RGX_BVNC_CORE_KM)),)
+ $(error The file $(RGX_BVNC_CORE_KM) does not exist. \
+       Valid BVNCs: $(ALL_KM_BVNCS))
+ endif
+ # Check BNC config version
+ ALL_KM_BNCS := \
+  $(patsubst rgxconfig_km_%.h,%,\
+       $(notdir $(shell ls $(TOP)/hwdefs/km/configs/rgxconfig_km_*.h)))
+ ifeq ($(filter $(RGX_BNC),$(ALL_KM_BNCS)),)
+ $(error Error: Invalid Kernel config RGX_BNC=$(RGX_BNC). \
+       Valid Kernel config BNCs: $(subst $(space),$(comma)$(space),$(ALL_KM_BNCS)))
+ endif
+ # Check if BNC config file exist
+ RGX_BNC_CONFIG_KM := $(TOP)/hwdefs/km/configs/rgxconfig_km_$(RGX_BNC).h
+ RGX_BNC_CONFIG_KM_HEADER := \"configs/rgxconfig_km_$(RGX_BNC).h\" 
+ #"rgxcore_km_$(RGX_BNC).h"
+ ifeq ($(wildcard $(RGX_BNC_CONFIG_KM)),)
+ $(error The file $(RGX_BNC_CONFIG_KM) does not exist. \
+       Valid BNCs: $(ALL_KM_BNCS))
+ endif
+endif
+
+# Enforced dependencies. Move this to an include.
+#
+SUPPORT_LINUX_USING_WORKQUEUES ?= 1
+ifeq ($(SUPPORT_LINUX_USING_WORKQUEUES),1)
+override PVR_LINUX_USING_WORKQUEUES := 1
+override PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE := 1
+override PVR_LINUX_TIMERS_USING_WORKQUEUES := 1
+else ifeq ($(SUPPORT_LINUX_USING_SHARED_WORKQUEUES),1)
+override PVR_LINUX_USING_WORKQUEUES := 1
+override PVR_LINUX_MISR_USING_WORKQUEUE := 1
+override PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE := 1
+endif
+
+ifeq ($(NO_HARDWARE),1)
+override SYS_USING_INTERRUPTS := 0
+endif
+
+# Rather than requiring the user to have to define two variables (one quoted,
+# one not), make PVRSRV_MODNAME a non-tunable and give it an overridable
+# default here.
+#
+PVRSRV_MODNAME ?= pvrsrvkm
+
+# Normally builds don't touch these, but we use them to influence the
+# components list. Make sure these are defined early enough to make this
+# possible.
+#
+ifeq ($(DONT_NEED_RGX_BVNC),)
+# we can only do this stuff if we have a BVNC
+ SUPPORT_RAY_TRACING := \
+  $(shell grep -qw RGX_FEATURE_RAY_TRACING $(RGX_BNC_CONFIG_KM) && echo 1)
+
+SUPPORT_META_DMA :=\
+  $(shell grep -qw RGX_FEATURE_META_DMA $(RGX_BNC_CONFIG_KM) && echo 1)
+endif
+
+# Default place for shared libraries
+SHLIB_DESTDIR ?= /usr/lib
+
+# Build's selected list of components.
+# - components.mk is a per-build file that specifies the components that are
+#   to be built
+-include components.mk
+
+# Set up the host and target compiler.
+include ../config/compiler.mk
+
+# PDUMP needs extra components
+#
+ifeq ($(PDUMP),1)
+ifneq ($(COMPONENTS),)
+COMPONENTS += pdump
+endif
+ifeq ($(SUPPORT_DRM),1)
+EXTRA_PVRSRVKM_COMPONENTS += dbgdrv
+else
+KERNEL_COMPONENTS += dbgdrv
+endif
+endif
+
+# HWPerf KM Interface example
+#
+ifeq ($(SUPPORT_KERNEL_HWPERF_TEST),1)
+KERNEL_COMPONENTS += rgxhwpdrv
+endif
+
+# PVRGDB needs extra components
+#
+ifeq ($(PVRGDB),1)
+ifneq ($(COMPONENTS),)
+COMPONENTS += pvrdebugger pvrgdb pvrdebugipc
+ifneq ($(filter opencl,$(COMPONENTS)),)
+COMPONENTS += gdb_ocl_test
+endif
+endif
+override SUPPORT_EXPORTING_MEMORY_CONTEXT := 1
+endif
+
+# RenderScript Replay needs extra components
+ifeq ($(RSCREPLAY),1)
+ifneq ($(COMPONENTS),)
+COMPONENTS += librscruntime librsccompiler renderscript renderscript_sha1 rscreplay
+endif
+endif
+
+$(if $(filter config,$(D)),$(info Build configuration:))
+
+################################# CONFIG ####################################
+
+ifneq ($(SUPPORT_NEUTRINO_PLATFORM), 1)
+
+# If KERNELDIR is set, write it out to the config.mk, with
+# KERNEL_COMPONENTS and KERNEL_ID
+#
+ifneq ($(strip $(KERNELDIR)),)
+PVRSRV_MODULE_BASEDIR ?= /lib/modules/$(KERNEL_ID)/extra/
+$(eval $(call BothConfigMake,KERNELDIR,$(KERNELDIR)))
+$(eval $(call BothConfigMake,KERNEL_ID,$(KERNEL_ID)))
+$(eval $(call KernelConfigMake,KERNEL_COMPONENTS,$(KERNEL_COMPONENTS)))
+$(eval $(call TunableKernelConfigMake,EXTRA_PVRSRVKM_COMPONENTS,,\
+List of components that should be built in to pvrsrvkm.ko$(comma) rather than_\
+forming separate kernel modules._\
+))
+
+# If KERNEL_CROSS_COMPILE is set to "undef", this is magically
+# equivalent to being unset. If it is unset, we use CROSS_COMPILE
+# (which might also be unset). If it is set, use it directly.
+ifneq ($(KERNEL_CROSS_COMPILE),undef)
+KERNEL_CROSS_COMPILE ?= $(CROSS_COMPILE)
+$(eval $(call TunableBothConfigMake,KERNEL_CROSS_COMPILE,))
+endif
+
+# Check the KERNELDIR has a kernel built and also check that it is
+# not 64-bit, which we do not support.
+KERNEL_AUTOCONF := \
+ $(strip $(wildcard $(KERNELDIR)/include/linux/autoconf.h) \
+         $(wildcard $(KERNELDIR)/include/generated/autoconf.h))
+ifeq ($(KERNEL_AUTOCONF),)
+$(warning autoconf.h not found in $$(KERNELDIR)/include/linux \
+or $$(KERNELDIR)/include/generated. Check your $$(KERNELDIR) variable \
+and kernel configuration.)
+endif
+else
+$(if $(KERNEL_COMPONENTS),$(warning KERNELDIR is not set. Kernel components cannot be built))
+endif
+
+endif # !Neutrino
+
+# Normally this is off for Linux, and only used by Android, but if customers
+# are testing their display engines using NULLADFWS, they need to enable it
+# for dmabuf support under Linux. The sync header is needed by adf_pdp.
+#
+SUPPORT_ION ?= 0
+ifneq ($(SUPPORT_ION),0)
+# Support kernels built out-of-tree with O=/other/path
+# In those cases, KERNELDIR will be O, not the source tree.
+ifneq ($(wildcard $(KERNELDIR)/source),)
+KSRCDIR := $(KERNELDIR)/source
+else
+KSRCDIR := $(KERNELDIR)
+endif
+ifneq ($(wildcard $(KSRCDIR)/drivers/staging/android/ion/ion.h),)
+# The kernel has a more recent version of ion, located in drivers/staging.
+# Change the default header paths and the behaviour wrt sg_dma_len.
+PVR_ANDROID_ION_HEADER := \"../drivers/staging/android/ion/ion.h\"
+PVR_ANDROID_ION_PRIV_HEADER := \"../drivers/staging/android/ion/ion_priv.h\"
+PVR_ANDROID_ION_USE_SG_LENGTH := 1
+endif
+ifneq ($(wildcard $(KSRCDIR)/drivers/staging/android/sync.h),)
+# The kernel has a more recent version of the sync driver, located in
+# drivers/staging. Change the default header path.
+PVR_ANDROID_SYNC_HEADER := \"../drivers/staging/android/sync.h\"
+endif
+$(eval $(call BothConfigMake,SUPPORT_ION,1))
+$(eval $(call BothConfigC,SUPPORT_ION,))
+$(eval $(call TunableKernelConfigC,PVR_ANDROID_ION_HEADER,\"linux/ion.h\"))
+$(eval $(call TunableKernelConfigC,PVR_ANDROID_ION_PRIV_HEADER,\"../drivers/gpu/ion/ion_priv.h\"))
+$(eval $(call TunableKernelConfigC,PVR_ANDROID_ION_USE_SG_LENGTH,))
+$(eval $(call TunableKernelConfigC,PVR_ANDROID_SYNC_HEADER,\"linux/sync.h\"))
+endif
+
+$(eval $(call UserConfigC,PVRSRV_MODULE_BASEDIR,\"$(PVRSRV_MODULE_BASEDIR)\"))
+
+# Ideally configured by platform Makefiles, as necessary
+#
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+$(eval $(call TunableBothConfigMake,RGX_FW_FILENAME,rgx.fw))
+$(eval $(call TunableBothConfigC,RGX_FW_FILENAME,"\"rgx.fw\""))
+endif
+
+
+$(if $(USE_CCACHE),$(if $(USE_DISTCC),$(error\
+Enabling both USE_CCACHE and USE_DISTCC at the same time is not supported)))
+
+# Invariant options for Linux
+#
+$(eval $(call BothConfigC,LINUX,))
+
+$(eval $(call BothConfigC,PVR_BUILD_DIR,"\"$(PVR_BUILD_DIR)\""))
+$(eval $(call BothConfigC,PVR_BUILD_TYPE,"\"$(BUILD)\""))
+$(eval $(call BothConfigC,PVRSRV_MODNAME,"\"$(PVRSRV_MODNAME)\""))
+$(eval $(call BothConfigMake,PVRSRV_MODNAME,$(PVRSRV_MODNAME)))
+$(eval $(call BothConfigMake,PVR_BUILD_DIR,$(PVR_BUILD_DIR)))
+$(eval $(call BothConfigMake,PVR_BUILD_TYPE,$(BUILD)))
+
+$(eval $(call BothConfigC,SUPPORT_RGX,1))
+$(eval $(call UserConfigMake,SUPPORT_RGX,1))
+
+# Some of the definitions in stdint.h aren't exposed by default in C++ mode,
+# unless these macros are defined. To make sure we get these definitions
+# regardless of which files include stdint.h, define them here.
+$(eval $(call UserConfigC,__STDC_CONSTANT_MACROS,))
+$(eval $(call UserConfigC,__STDC_FORMAT_MACROS,))
+$(eval $(call UserConfigC,__STDC_LIMIT_MACROS,))
+
+$(eval $(call UserConfigC,PVR_TLS_USE_GCC__thread_KEYWORD,))
+
+ifneq ($(DISPLAY_CONTROLLER),)
+$(eval $(call BothConfigC,DISPLAY_CONTROLLER,$(DISPLAY_CONTROLLER)))
+$(eval $(call BothConfigMake,DISPLAY_CONTROLLER,$(DISPLAY_CONTROLLER)))
+endif
+
+$(eval $(call UserConfigC,OPK_DEFAULT,"\"$(OPK_DEFAULT)\""))
+$(eval $(call UserConfigC,OPK_FALLBACK,"\"$(OPK_FALLBACK)\""))
+
+$(eval $(call BothConfigMake,PVR_SYSTEM,$(PVR_SYSTEM)))
+$(eval $(call KernelConfigMake,PVR_LOADER,$(PVR_LOADER)))
+
+ifeq ($(MESA_EGL),1)
+$(eval $(call UserConfigMake,LIB_IMG_EGL,pvr_dri_support))
+$(eval $(call UserConfigC,LIB_IMG_EGL_NAME,\"libpvr_dri_support.so\"))
+else
+$(eval $(call UserConfigMake,LIB_IMG_EGL,IMGegl))
+$(eval $(call UserConfigC,LIB_IMG_EGL_NAME,\"libIMGegl.so\"))
+endif
+
+# Build-type dependent options
+#
+$(eval $(call BothConfigMake,BUILD,$(BUILD)))
+
+ifeq ($(BUILD),debug)
+PVR_RI_DEBUG ?= 1
+SUPPORT_PAGE_FAULT_DEBUG ?= 1
+$(eval $(call BothConfigC,DEBUG,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MEMORY_ALLOCATIONS,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MEM_AREAS,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MMAP_AREAS,))
+$(eval $(call KernelConfigC,DEBUG_BRIDGE_KM,))
+$(eval $(call KernelConfigC,DEBUG_HANDLEALLOC_KM,))
+$(eval $(call UserConfigC,DLL_METRIC,1))
+$(eval $(call TunableBothConfigC,RGXFW_ALIGNCHECKS,1))
+$(eval $(call TunableBothConfigC,PVRSRV_DEBUG_CCB_MAX,))
+else ifeq ($(BUILD),release)
+$(eval $(call BothConfigC,RELEASE,))
+$(eval $(call TunableBothConfigMake,DEBUGLINK,1))
+$(eval $(call TunableBothConfigC,RGXFW_ALIGNCHECKS,))
+else ifeq ($(BUILD),timing)
+$(eval $(call BothConfigC,TIMING,))
+$(eval $(call UserConfigC,DLL_METRIC,1))
+$(eval $(call TunableBothConfigMake,DEBUGLINK,1))
+else
+$(error BUILD= must be either debug, release or timing)
+endif
+
+
+
+# User-configurable options
+#
+ifeq ($(DONT_NEED_RGX_BVNC),)
+  $(eval $(call TunableBothConfigC,RGX_BVNC_CORE_KM_HEADER,))
+ $(eval $(call TunableBothConfigC,RGX_BVNC_CORE_HEADER,))
+   $(eval $(call TunableBothConfigC,RGX_BNC_CONFIG_KM_HEADER,))
+ $(eval $(call TunableBothConfigC,RGX_BNC_CONFIG_HEADER,))
+  endif
+
+$(eval $(call TunableBothConfigC,SUPPORT_DBGDRV_EVENT_OBJECTS,1))
+$(eval $(call TunableBothConfigC,PVR_DBG_BREAK_ASSERT_FAIL,,\
+Enable this to treat PVR_DBG_BREAK as PVR_ASSERT(0)._\
+Otherwise it is ignored._\
+))
+$(eval $(call TunableBothConfigC,PDUMP,,\
+Enable parameter dumping in the driver._\
+This adds code to record the parameters being sent to the hardware for_\
+later analysis._\
+))
+PDUMP_STREAMBUF_SIZE_MB ?= 16
+$(eval $(call TunableBothConfigC,PDUMP_STREAMBUF_MAX_SIZE_MB,$(PDUMP_STREAMBUF_SIZE_MB),))
+$(eval $(call TunableBothConfigC,NO_HARDWARE,,\
+Disable hardware interactions (e.g. register writes) that the driver would_\
+normally perform. A driver built with this option can$(apos)t drive hardware$(comma)_\
+but with PDUMP enabled$(comma) it can capture parameters to be played back later._\
+))
+$(eval $(call TunableBothConfigC,PDUMP_DEBUG_OUTFILES,))
+$(eval $(call TunableBothConfigC,SYS_USING_INTERRUPTS,1))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_DPF,,\
+Enable this to turn on PVR_DPF in release builds._\
+))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_ASSERT,,\
+Enable this to turn on PVR_ASSERT in release builds._\
+))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_TRACE,,\
+Enable this to turn on PVR_TRACE in release builds._\
+))
+$(eval $(call TunableBothConfigC,REFCOUNT_DEBUG,))
+$(eval $(call TunableBothConfigC,DC_DEBUG,))
+$(eval $(call TunableBothConfigC,SCP_DEBUG,))
+$(eval $(call TunableBothConfigC,CACHEFLUSH_TYPE,CACHEFLUSH_GENERIC))
+$(eval $(call TunableBothConfigC,SUPPORT_INSECURE_EXPORT,))
+$(eval $(call TunableBothConfigC,SUPPORT_SECURE_EXPORT,1,\
+Enable support for secure device memory and sync export._\
+This replaces export handles with file descriptors$(comma) which can be passed_\
+between processes to share memory._\
+))
+$(eval $(call TunableBothConfigC,SUPPORT_GPUTRACE_EVENTS,))
+$(eval $(call TunableBothConfigC,SUPPORT_KERNEL_HWPERF,))
+$(eval $(call TunableBothConfigC,SUPPORT_DISPLAY_CLASS,))
+$(eval $(call TunableBothConfigC,PVRSRV_DEBUG_CCB_MAX,))
+$(eval $(call TunableBothConfigC,SUPPORT_TRUSTED_DEVICE,))
+$(eval $(call TunableBothConfigC,SUPPORT_GPUVIRT_VALIDATION,))
+$(eval $(call TunableBothConfigC,GPUVIRT_VALIDATION_NUM_OS,8))
+$(eval $(call TunableBothConfigC,TRUSTED_DEVICE_DEFAULT_ENABLED,))
+$(eval $(call TunableBothConfigC,SUPPORT_EXPORTING_MEMORY_CONTEXT,))
+$(eval $(call TunableBothConfigMake,SUPPORT_USER_REGISTER_CONFIGURATION,))
+$(eval $(call TunableBothConfigC,SUPPORT_USER_REGISTER_CONFIGURATION,))
+$(eval $(call TunableBothConfigC,SUPPORT_VALIDATION,))
+$(eval $(call TunableBothConfigC,FIX_DUSTS_POW_ON_INIT,))
+$(eval $(call TunableBothConfigC,PVR_DVFS,,\
+Enables PVR DVFS implementation to actively change frequency / voltage depending_\
+on current GPU load. Currently only supported on Linux._\
+))
+$(eval $(call TunableBothConfigC,PVR_POWER_ACTOR,,\
+Enables PVR power actor implementation for registration with a kernel configured_\
+with IPA. Enables power counter measurement timer in the FW which is periodicaly_\
+read by the host DVFS in order to operate within a governor set power envelope._\
+))
+$(eval $(call TunableBothConfigC,PVR_POWER_ACTOR_SCALING,,\
+Scaling factor for the dynamic power coefficients._\
+))
+$(eval $(call TunableKernelConfigC,PVR_POWER_ACTOR_DEBUG,,\
+Enable debug logging for power actor._\
+))
+$(eval $(call TunableKernelConfigC,DEBUG_HANDLEALLOC_INFO_KM,))
+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_WRITECOMBINE,1))
+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_PAT,1))
+$(eval $(call TunableKernelConfigC,PVRSRV_RESET_ON_HWTIMEOUT,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_USING_WORKQUEUES,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_WORKQUEUES,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,PVR_LDM_PLATFORM_PRE_REGISTERED,))
+$(eval $(call TunableKernelConfigC,PVR_LDM_DRIVER_REGISTRATION_NAME,"\"$(PVRSRV_MODNAME)\""))
+$(eval $(call TunableBothConfigC,LDM_PLATFORM,))
+$(eval $(call TunableBothConfigC,LDM_PCI,))
+$(eval $(call TunableBothConfigC,PVRSRV_ENABLE_FULL_SYNC_TRACKING,))
+$(eval $(call TunableKernelConfigC,PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN,256))
+$(eval $(call TunableKernelConfigC,PVRSRV_ENABLE_FULL_CCB_DUMP,))
+$(eval $(call TunableKernelConfigC,SYNC_DEBUG,))
+$(eval $(call TunableKernelConfigC,SUPPORT_DUMP_CLIENT_CCB_COMMANDS,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_DONT_USE_RANGE_BASED_INVALIDATE,))
+$(eval $(call TunableKernelConfigC,SUPPORT_MMU_PxE_MAP_ON_DEMAND,))
+$(eval $(call TunableKernelConfigC,SUPPORT_MMU_MODIFICATION_LOGGING,,\
+Enable support for logging of page table modifications. This is as debug_\
+feature for use when debugging page-faults which are showing what look to_\
+be unexpected values. It keeps a history of the last few modifications types_\
+(map/unmap) and the value written during as a result of that operation._\
+))
+$(eval $(call TunableKernelConfigC,SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT,))
+$(eval $(call TunableKernelConfigC,SUPPORT_DC_COMPLETE_TIMEOUT_DEBUG,))
+$(eval $(call TunableKernelConfigC,SUPPORT_SYSTEM_INTERRUPT_HANDLING,,\
+Enable support for system level interrupt handling. This is intended_\
+for use on systems that have two or more levels of interrupt registers_\
+which require the top level register to be cleared by the system layer_\
+because it is not specific to one single device._\
+))
+
+$(eval $(call TunableBothConfigC,SUPPORT_PVR_VALGRIND,))
+
+
+$(eval $(call TunableBothConfigC,PVRSRV_DEVMEM_SAFE_MEMSETCPY,,\
+Enable this to force the use of *DeviceMemSet/Copy in the drvier _\
+instead of the built-in libc functions. These implemenations are device _\
+memory safe and are used by default on AARCH64 platform._\
+))
+
+$(eval $(call TunableBothConfigC,PVRSRV_BRIDGE_LOGGING,))
+
+
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),1)
+  endif
+
+ifneq ($(DWARF_DEBUG), 1)
+    endif
+
+$(eval $(call TunableBothConfigMake,CACHEFLUSH_TYPE,CACHEFLUSH_GENERIC))
+$(eval $(call TunableBothConfigMake,PDUMP,))
+$(eval $(call TunableBothConfigMake,SUPPORT_INSECURE_EXPORT,))
+$(eval $(call TunableBothConfigMake,SUPPORT_SECURE_EXPORT,1))
+$(eval $(call TunableBothConfigMake,SUPPORT_DISPLAY_CLASS,))
+$(eval $(call TunableBothConfigMake,SUPPORT_RAY_TRACING,))
+$(eval $(call TunableBothConfigC,FORCE_DM_OVERLAP,))
+$(eval $(call TunableBothConfigC,SUPPORT_EXTRA_METASP_DEBUG,))
+$(eval $(call TunableBothConfigC,GPU_UTIL_SLC_STALL_COUNTERS,))
+
+$(eval $(call TunableBothConfigMake,SUPPORT_GPUTRACE_EVENTS,))
+$(eval $(call TunableBothConfigMake,SUPPORT_KERNEL_HWPERF,))
+
+$(eval $(call TunableBothConfigMake,OPTIM,,\
+Specify the optimisation flags passed to the compiler. Normally this_\
+is autoconfigured based on the build type._\
+))
+$(eval $(call TunableBothConfigC,SUPPORT_PERCONTEXT_FREELIST,1))
+$(eval $(call TunableBothConfigC,SUPPORT_MMU_FREELIST,))
+$(eval $(call TunableBothConfigC,SUPPORT_VFP,))
+
+$(eval $(call TunableBothConfigC,SUPPORT_META_SLAVE_BOOT,))
+
+$(eval $(call UserConfigC,EGL_BASENAME_SUFFIX,\"$(EGL_BASENAME_SUFFIX)\"))
+
+
+
+
+
+$(eval $(call TunableBothConfigC,PVR_TESTING_UTILS,,\
+Enable this to build in support for testing the PVR Transport Layer API._\
+))
+
+
+TQ_CAPTURE_PARAMS ?= 1
+
+$(eval $(call TunableBothConfigC,TDMETACODE,))
+$(eval $(call TunableBothConfigC,PVR_DPF_ADHOC_DEBUG_ON,))
+$(eval $(call TunableBothConfigC,RGXFW_DEBUG_LOG_GROUP,))
+$(eval $(call TunableBothConfigC,SUPPORT_POWMON_WO_GPIO_PIN,))
+
+
+$(eval $(call TunableKernelConfigMake,PVR_HANDLE_BACKEND,idr,\
+Specifies the back-end that should be used$(comma) by the Services kernel handle_\
+interface$(comma) to allocate handles. The available backends are:_\
+* generic (OS agnostic)_\
+* idr (Uses the Linux IDR interface)_\
+))
+
+
+$(eval $(call TunableBothConfigC,PVRSRV_ENABLE_PROCESS_STATS,1,\
+Enable Process Statistics via DebugFS._\
+))
+
+$(eval $(call TunableBothConfigC,SUPPORT_SHARED_SLC,,\
+When the SLC is shared the SLC reset is performed by the System layer when \
+calling RGXInitSLC and not the GPU driver. Define this for system layer \
+SLC handling. \
+))
+
+# PVR_RI_DEBUG is set to enable RI annotation of devmem allocations
+# This is enabled by default for debug builds.
+#
+$(eval $(call TunableBothConfigMake,PVR_RI_DEBUG,))
+$(eval $(call TunableBothConfigC,PVR_RI_DEBUG,,\
+Enable Resource Information (RI) debug. This logs details of_\
+resource allocations with annotation to help indicate their use._\
+))
+
+$(eval $(call TunableBothConfigMake,SUPPORT_PAGE_FAULT_DEBUG,))
+$(eval $(call TunableBothConfigC,SUPPORT_PAGE_FAULT_DEBUG,,\
+Collect information about allocations such as descriptive strings_\
+and timing data for more detailed page fault analysis._\
+))
+
+$(eval $(call TunableBothConfigC,PVRSRV_ENABLE_MEMORY_STATS,,\
+Enable Memory allocations to be recorded and published via Process Statistics._\
+))
+
+$(eval $(call TunableKernelConfigC,PVRSRV_ENABLE_FW_TRACE_DEBUGFS,,\
+Enable automatic decoding of Firmware Trace via DebugFS._\
+))
+
+$(eval $(call TunableBothConfigC,PVR_LINUX_PHYSMEM_MAX_POOL_PAGES,10240))
+
+$(eval $(call TunableBothConfigC,PVR_MMAP_USE_VM_INSERT,,\
+If enabled Linux will always use vm_insert_page for CPU mappings._\
+vm_insert_page was found to be slower than remap_pfn_range on ARM kernels_\
+but guarantees full memory accounting for the process that mapped the memory.\
+The slowdown in vm_insert_page is caused by a dcache flush_\
+that is only implemented for ARM and a few other architectures._\
+This tunable can be enabled to debug memory issues. On x86 platforms_\
+we always use vm_insert_page independent of this tunable._\
+))
+
+# ARM-Linux specific: 
+# When allocating uncached or write-combine memory we need to invalidate the
+# CPU cache before we can use the acquired pages. 
+# The threshhold defines at which number of pages we want to do a full 
+# cache flush instead of invalidating pages one by one.
+$(eval $(call TunableBothConfigC,PVR_LINUX_ARM_PAGEALLOC_FLUSH_THRESHOLD, 256))
+
+# Choose the threshold at which iterative page-by-page ('n' 1 page allocs) 
+# allocation is replaced with multiple block (1 'n' page alloc) allocation;
+# for PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER, the valid range is [0:MAX_ORDER-1]
+# NOTE: To disable higher-order allocation, set XXX_MAX_ALLOC_ORDER to zero
+$(eval $(call TunableBothConfigC,PVR_LINUX_PHYSMEM_MIN_NUM_PAGES, 256 ))
+$(eval $(call TunableBothConfigC,PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER, 2 ))
+
+# Choose the threshold at which allocation size we want to use vmalloc instead of
+# kmalloc. On highly fragmented systems large kmallocs can fail because it requests 
+# physically contiguous pages. All allocations bigger than this define use vmalloc.
+$(eval $(call TunableBothConfigC,PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD, 16384 ))
+
+# Tunable RGX_MAX_TA_SYNCS / RGX_MAX_3D_SYNCS to increase the size of sync array in the DDK
+# If defined, these macros take up the values as defined in the environment,
+# Else, the default value is taken up as defined in include/rgxapi.h
+#
+
+$(eval $(call TunableBothConfigMake,SUPPORT_KERNEL_SRVINIT,))
+$(eval $(call TunableBothConfigC,SUPPORT_KERNEL_SRVINIT,))
+
+
+$(eval $(call TunableKernelConfigC,PVRSRV_SPLIT_LARGE_OSMEM_ALLOC,,\
+Splits some critical allocations greater than page size into_\
+two allocations: multiple page size and allocation size minus multiple_\
+page size._\
+))
+
+$(eval $(call TunableKernelConfigC,PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS,,\
+If enabled, all kernel mappings will use vmap/vunmap._\
+vmap/vunmap is slower than vm_map_ram/vm_unmap_ram and can_\
+even have bad peaks taking up to 100x longer than vm_map_ram._\
+The disadvantage of vm_map_ram is that it can lead to vmalloc space_\
+fragmentation that can lead to vmalloc space exhaustion on 32 bit Linux systems._\
+This flag only affects 64 bit Linux builds, on 32 bit we always default to use vmap_\
+because of the described fragmentation problem._\
+))
+
+
+$(eval $(call TunableKernelConfigC,PVRSRV_DEBUG_LISR_EXECUTION,,\
+Collect information about the last execution of the LISR in order to_\
+debug interrupt handling timeouts._\
+))
+
+endif # INTERNAL_CLOBBER_ONLY
+
+export INTERNAL_CLOBBER_ONLY
+export TOP
+export OUT
+
+MAKE_ETC := -Rr --no-print-directory -C $(TOP) TOP=$(TOP) OUT=$(OUT) \
+               -f build/linux/toplevel.mk
+
+# This must match the default value of MAKECMDGOALS below, and the default
+# goal in toplevel.mk
+.DEFAULT_GOAL := build
+
+ifeq ($(MAKECMDGOALS),)
+MAKECMDGOALS := build
+else
+# We can't pass autogen to toplevel.mk
+MAKECMDGOALS := $(filter-out autogen,$(MAKECMDGOALS))
+endif
+
+.PHONY: autogen
+autogen:
+ifeq ($(INTERNAL_CLOBBER_ONLY),)
+       @$(MAKE) -s --no-print-directory -C $(TOP) \
+               -f build/linux/prepare_tree.mk \
+               LDM_PCI=$(LDM_PCI) \
+               LDM_PLATFORM=$(LDM_PLATFORM)
+else
+       @:
+endif
+
+include ../config/help.mk
+
+# This deletes built-in suffix rules. Otherwise the submake isn't run when
+# saying e.g. "make thingy.a"
+.SUFFIXES:
+
+# Because we have a match-anything rule below, we'll run the main build when
+# we're actually trying to remake various makefiles after they're read in.
+# These rules try to prevent that
+%.mk: ;
+Makefile%: ;
+Makefile: ;
+
+.PHONY: build kbuild install
+build kbuild install: autogen
+       @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:)
+
+%: autogen
+       @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:)
diff --git a/drivers/gpu/rogue_m/build/linux/config/help.mk b/drivers/gpu/rogue_m/build/linux/config/help.mk
new file mode 100644 (file)
index 0000000..4d6ef01
--- /dev/null
@@ -0,0 +1,74 @@
+########################################################################### ###
+#@File
+#@Title         Targets for printing config option help
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+define newline
+
+
+endef
+empty :=
+
+define abbrev-option-value
+$(if $(word 6,$(1)),$(wordlist 1,5,$(1))...,$(1))
+endef
+
+define print-option-help
+# Print the option name and value
+$(info $(1) ($(if $($(1)),$(call abbrev-option-value,$($(1))),<unset>), default $(if $(INTERNAL_CONFIG_DEFAULT_FOR_$(1)),$(call abbrev-option-value,$(INTERNAL_CONFIG_DEFAULT_FOR_$(1))),<unset>))$(if $(INTERNAL_DESCRIPTION_FOR_$(1)),:,))
+# Ensure the config help text ends with a newline
+$(and $(INTERNAL_DESCRIPTION_FOR_$(1)),$(if $(filter %_,$(word $(words $(INTERNAL_DESCRIPTION_FOR_$(1))),$(INTERNAL_DESCRIPTION_FOR_$(1)))),,$(eval INTERNAL_DESCRIPTION_FOR_$(1) := $(INTERNAL_DESCRIPTION_FOR_$(1))_ )))
+# Print the config help text
+$(info $(empty)  $(subst _ ,$(newline)  ,$(INTERNAL_DESCRIPTION_FOR_$(1))))
+endef
+
+.PHONY: confighelp allconfighelp
+# Show only the config options that have help text
+confighelp:
+       @: $(foreach _o,$(sort $(ALL_TUNABLE_OPTIONS)),$(if $(INTERNAL_DESCRIPTION_FOR_$(_o)),$(call print-option-help,$(_o)),))
+# Show all the config options
+allconfighelp:
+       @: $(foreach _o,$(sort $(ALL_TUNABLE_OPTIONS)),$(call print-option-help,$(_o)))
+
+
+ifneq ($(filter confighelp-%,$(MAKECMDGOALS)),)
+confighelp-%:
+       @: $(if $(filter $*,$(ALL_TUNABLE_OPTIONS)),$(call print-option-help,$*),$(info $* is not a tunable config option))
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/config/kernel_version.mk b/drivers/gpu/rogue_m/build/linux/config/kernel_version.mk
new file mode 100644 (file)
index 0000000..35ecceb
--- /dev/null
@@ -0,0 +1,100 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(if $(KERNELDIR),,$(error KERNELDIR must be set to obtain a version))
+
+override KERNEL_VERSION := \
+ $(shell grep "^VERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_PATCHLEVEL := \
+ $(shell grep "^PATCHLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_SUBLEVEL := \
+ $(shell grep "^SUBLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_EXTRAVERSION := \
+ $(shell grep "^EXTRAVERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+
+# Break the kernel version up into a space separated list
+kernel_version_as_list := $(KERNEL_VERSION) \
+                               $(KERNEL_PATCHLEVEL) \
+                               $(KERNEL_SUBLEVEL) \
+                               $(patsubst .%,%,$(KERNEL_EXTRAVERSION))
+
+# The base ID doesn't have to be accurate; we only use it for
+# feature checks which will not care about extraversion bits
+#
+override KERNEL_BASE_ID := \
+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL)
+
+# Try to get the kernel ID from the kernel.release file.
+# 
+KERNEL_ID ?= \
+ $(shell cat $(KERNELDIR)/include/config/kernel.release 2>/dev/null)
+
+# If the kernel ID isn't set yet, try to set it from the UTS_RELEASE
+# macro.
+#
+ifeq ($(strip $(KERNEL_ID)),)
+KERNEL_ID := \
+ $(shell grep -h '\#define UTS_RELEASE' \
+       $(KERNELDIR)/include/linux/* | cut -f3 -d' ' | sed s/\"//g)
+endif
+
+ifeq ($(strip $(KERNEL_ID)),)
+KERNEL_ID := \
+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL)$(KERNEL_EXTRAVERSION)
+endif
+
+# Return 1 if the kernel version is at least the value passed to the
+# function, else return nothing.
+# Examples
+#      $(call kernel-version-at-least,2,6,35)
+#      $(call kernel-version-at-least,2,6,35,7)
+#
+define kernel-version-at-least
+$(shell set -- $(kernel_version_as_list) 0 0 0 0; \
+       Y=true; \
+       for D in $1 $2 $3 $4; \
+       do \
+               [ $$1 ] || break; \
+               [ $$1 -eq $$D ] && { shift; continue; };\
+               [ $$1 -lt $$D ] && Y=; \
+               break; \
+       done; \
+       echo $$Y)
+endef
diff --git a/drivers/gpu/rogue_m/build/linux/config/preconfig.mk b/drivers/gpu/rogue_m/build/linux/config/preconfig.mk
new file mode 100644 (file)
index 0000000..041508e
--- /dev/null
@@ -0,0 +1,157 @@
+########################################################################### ###
+#@File
+#@Title         Set up configuration required by build-directory Makefiles
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# NOTE: Don't put anything in this file that isn't strictly required
+# by the build-directory Makefiles. It should go in core.mk otherwise.
+
+TOP := $(abspath ../../..)
+
+# Some miscellaneous things to make comma substitutions easier.
+apos := '#'
+comma := ,
+empty :=
+space := $(empty) $(empty)
+
+ifneq ($(words $(TOP)),1)
+$(warning This source tree is located in a path which contains whitespace,)
+$(warning which is not supported.)
+$(warning )
+$(warning $(space)The root is: $(TOP))
+$(warning )
+$(error Whitespace found in $$(TOP))
+endif
+
+$(call directory-must-exist,$(TOP))
+
+ifneq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+
+CC_CHECK  := ../tools/cc-check.sh
+CHMOD     := chmod
+
+# GNU Make has builtin values for CC/CXX which we don't want to trust. This
+# is because $(CROSS_COMPILE)$(CC) doesn't always expand to a cross compiler
+# toolchain binary name (e.g. most toolchains have 'gcc' but not 'cc').
+
+ifeq ($(origin CC),default)
+ _CC      := $(CROSS_COMPILE)gcc
+ CC       := gcc
+else
+ _CLANG   := $(shell $(CC_CHECK) --clang --cc $(CC))
+ ifeq ($(_CLANG),true)
+  _CC     := $(CC) -target $(patsubst %-,%,$(CROSS_COMPILE))
+ else
+  _CC     := $(CC)
+ endif
+endif
+
+ifeq ($(origin CXX),default)
+ _CXX     := $(CROSS_COMPILE)g++
+ CXX      := g++
+else
+ _CLANGXX := $(shell $(CC_CHECK) --clang --cc $(CXX))
+ ifeq ($(_CLANGXX),true)
+  _CXX    := $(CXX) -target $(patsubst %-,%,$(CROSS_COMPILE))
+ else
+  _CXX    := $(CXX)
+ endif
+endif
+
+CC_SECONDARY ?= $(CC)
+HOST_CC      ?= gcc
+
+# Work out if we are targeting ARM before we start tweaking _CC.
+TARGETING_AARCH64 := $(shell \
+ $(_CC) -dM -E - </dev/null | grep -q __aarch64__ && echo 1)
+
+TARGETING_ARM := $(shell \
+ $(_CC) -dM -E - </dev/null | grep __arm__ >/dev/null 2>&1 && echo 1)
+
+TARGETING_MIPS := $(shell \
+ $(_CC) -dM -E - </dev/null | grep __mips__ >/dev/null 2>&1 && echo 1)
+
+HOST_CC_IS_LINUX := $(shell \
+ $(HOST_CC) -dM -E - </dev/null | grep __linux__ >/dev/null 2>&1 && echo 1)
+
+ifneq ($(strip $(KERNELDIR)),)
+include ../config/kernel_version.mk
+endif
+
+# The user didn't set CROSS_COMPILE. There's probably nothing wrong
+# with that, but we'll let them know anyway.
+#
+ifeq ($(origin CROSS_COMPILE), undefined)
+$(warning CROSS_COMPILE is not set. Target components will be built with the host compiler)
+endif
+
+endif # !Neutrino
+
+# The user is trying to set one of the old SUPPORT_ options on the
+# command line or in the environment. This isn't supported any more
+# and will often break the build. The user is generally only trying
+# to remove a component from the list of targets to build, so we'll
+# point them at the new way of doing this.
+define sanity-check-support-option-origin
+ifeq ($$(filter undefined file,$$(origin $(1))),)
+$$(warning *** Setting $(1) via $$(origin $(1)) is deprecated)
+$$(error If you are trying to disable a component, use e.g. EXCLUDED_APIS="opengles1 opengl")
+endif
+endef
+$(foreach _o,SYS_CFLAGS SYS_CXXFLAGS SYS_INCLUDES SYS_EXE_LDFLAGS SYS_LIB_LDFLAGS,$(eval $(call sanity-check-support-option-origin,$(_o))))
+
+# Check for words in EXCLUDED_APIS that aren't understood by the
+# common/apis/*.mk files. This should be kept in sync with all the tests on
+# EXCLUDED_APIS in those files
+_excludable_apis := opencl opengl opengles1 opengles3 openrl unittests renderscript scripts composerhal servicestools hwperftools testchiptools rogue2d memtrackhal camerahal sensorhal
+_excluded_apis := $(subst $(comma),$(space),$(EXCLUDED_APIS))
+
+_unrecognised := $(strip $(filter-out $(_excludable_apis),$(_excluded_apis)))
+ifneq ($(_unrecognised),)
+$(warning *** Ignoring unrecognised entries in EXCLUDED_APIS: $(_unrecognised))
+$(warning *** EXCLUDED_APIS was set via $(origin EXCLUDED_APIS) to: $(EXCLUDED_APIS))
+$(warning *** Excludable APIs are: $(_excludable_apis))
+endif
+
+override EXCLUDED_APIS := $(filter $(_excludable_apis), $(_excluded_apis))
+
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include ../common/neutrino/preconfig_neutrino.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/defs.mk b/drivers/gpu/rogue_m/build/linux/defs.mk
new file mode 100644 (file)
index 0000000..14cf6f6
--- /dev/null
@@ -0,0 +1,262 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+define must-be-defined
+$(if $(filter undefined,$(origin $(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must be defined),)
+endef
+
+define must-be-nonempty
+$(if $(strip $($(1))),,$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain a value))
+endef
+
+define directory-must-exist
+$(if $(wildcard $(abspath $(1)/)),,$(error Directory $(1) must exist))
+endef
+
+define one-word-only
+$(if $(filter-out $(firstword $($(1))),$($(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain only one word),)
+endef
+
+define module-library
+$(patsubst lib%.so,%,$(if $($(1)_target),$($(1)_target),$(1).so))
+endef
+
+# This is done to allow module type makefiles to use $(THIS_MAKEFILE)
+define register-module
+INTERNAL_MAKEFILE_FOR_MODULE_$(1) := $(THIS_MAKEFILE)
+endef
+
+define process-module-arch
+MODULE_ARCH := $$(strip $(2))
+include $$(MAKE_TOP)/moduledefs_common.mk
+include $$(MAKE_TOP)/moduledefs/$$(MODULE_ARCH).mk
+include $$(MAKE_TOP)/modules/$$(strip $$($$(THIS_MODULE)_type)).mk
+.SECONDARY: $$(MODULE_INTERMEDIATES_DIR)
+$$(MODULE_INTERMEDIATES_DIR):
+       $$(make-directory)
+MODULE_CLEAN_TARGETS += $$(MODULE_INTERMEDIATES_DIR)
+INTERNAL_TARGETS_FOR_$(1) += $$(MODULE_TARGETS)
+INTERNAL_CLEAN_TARGETS_FOR_$(1) += $$(MODULE_CLEAN_TARGETS)
+INTERNAL_CLOBBER_TARGETS_FOR_$(1) += $$(MODULE_CLEAN_TARGETS) $$(MODULE_CLOBBER_TARGETS) $$(MODULE_TARGETS)
+endef
+
+target_neutral_types := \
+ apk \
+ bison_parser \
+ bridge \
+ copy_files \
+ custom \
+ flex_lexer \
+ flexxx_lexer \
+ gen_dispatch \
+ rsc_scriptc \
+ image_header \
+ inline_shaders \
+ java_archive \
+ module_group \
+ pds_header \
+ rgxfw \
+ test_image \
+ usc_header \
+ rscbitcode_header \
+ yuv_test_image
+
+doc_types := \
+ doc \
+ doxygen
+
+define calculate-arch-list
+# Work out the target platforms for this module
+MODULE_ARCH_LIST := $(2)
+ifeq ($$(MODULE_ARCH_LIST),)
+ifneq ($$(filter $(1),$(doc_types)),)
+MODULE_ARCH_LIST := doc
+else
+ifneq ($$(filter $(1),$(target_neutral_types)),)
+MODULE_ARCH_LIST := target_neutral
+else
+ifneq ($$(filter $(1),kernel_module),)
+MODULE_ARCH_LIST := $(TARGET_PRIMARY_ARCH)
+else
+MODULE_ARCH_LIST := $(TARGET_ALL_ARCH)
+endif
+endif
+endif
+endif
+endef
+
+define process-module
+THIS_MODULE := $(1)
+THIS_MAKEFILE := $(INTERNAL_MAKEFILE_FOR_MODULE_$(1))
+INTERNAL_TARGETS_FOR_$(1) :=
+INTERNAL_CLEAN_TARGETS_FOR_$(1) :=
+INTERNAL_CLOBBER_TARGETS_FOR_$(1) :=
+include $$(MAKE_TOP)/this_makefile.mk
+$$(call must-be-nonempty,THIS_MAKEFILE)
+$$(call must-be-nonempty,$(1)_type)
+$$(eval $$(call calculate-arch-list,$$($(1)_type),$$($(1)_arch)))
+INTERNAL_ARCH_LIST_FOR_$(1) := $$(MODULE_ARCH_LIST)
+$$(foreach _m,$$(MODULE_ARCH_LIST),$$(eval $$(call process-module-arch,$(1),$$(_m))))
+endef
+
+# This can be used by module_type.mk files to indicate that they can't be
+# built as host_module_type
+define target-build-only
+$(if $(filter true,$(MODULE_HOST_BUILD)),$(error In makefile $(THIS_MAKEFILE): Module $(THIS_MODULE) attempted to build a host $(1), which is not supported))
+endef
+
+define relative-to-top
+$(patsubst $(TOP)/%,%,$(1))
+endef
+
+define cc-check
+$(shell \
+       CC_CHECK=$(patsubst @%,%,$(CC_CHECK)) && \
+       $(patsubst @%,%,$(CHMOD)) +x $$CC_CHECK && \
+       $$CC_CHECK --cc "$(1)" --out "$(2)" $(3))
+endef
+
+define cc-is-clang
+$(call cc-check,$(patsubst @%,%,$(CC)),$(OUT),--clang)
+endef
+
+define cc-option
+$(call cc-check,$(patsubst @%,%,$(CC)),$(OUT),$(1))
+endef
+
+define cxx-option
+$(call cc-check,$(patsubst @%,%,$(CXX)),$(OUT),$(1))
+endef
+
+define host-cc-option
+$(call cc-check,$(patsubst @%,%,$(HOST_CC)),$(OUT),$(1))
+endef
+
+define host-cxx-option
+$(call cc-check,$(patsubst @%,%,$(HOST_CXX)),$(OUT),$(1))
+endef
+
+define kernel-cc-option
+$(call cc-check,$(KERNEL_CROSS_COMPILE)gcc,$(OUT),$(1))
+endef
+
+# Turn a particular warning on, or explicitly turn it off, depending on
+# the value of W. The "-W" or "-Wno-" part of the warning need not be
+# specified.
+define cc-optional-warning
+$(call cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define host-cc-optional-warning
+$(call host-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define kernel-cc-optional-warning
+$(call kernel-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define module-info-line
+$(if $(filter modules,$(D)),$(info [$(THIS_MODULE)] <$(MODULE_ARCH)> $(1)),)
+endef
+
+# $(call if-exists,A,B) => A if A is a file which exists, otherwise B
+define if-exists
+$(if $(wildcard $(1)),$(1),$(2))
+endef
+
+#
+# Joins a given list of strings together with the given separator.
+#
+# (1): the list of strings to join
+# (2): the separator to use for joining
+#
+NOOP=
+SPACE=$(NOOP) $(NOOP)
+define list-join
+$(subst $(SPACE),$(2),$(strip $(1)))
+endef
+
+# 
+# Check if a given path is absolute
+#
+# $(1): path to check
+# $(2): return when true
+# $(3): return when false
+#
+define if-abs-path
+$(if $(filter /%,$(1)),$(2),$(3))
+endef
+
+# 
+# Add a prefix to every path in a list, when the path isn't absolute.
+#
+# $(1): prefix to add
+# $(2): list of paths
+#
+define addprefix-ifnot-abs
+$(foreach _path,$(2),$(call if-abs-path,$(_path),$(_path),$(1)$(_path)))
+endef
+
+#
+# Return the directory part of a path normalized (without trailing slashes)
+#
+# $(1): Path to normalize
+#
+define normalized-dir
+$(if $(filter /,$(dir $(1))),$(dir $(1)),$(if $(findstring /,$(dir $(1))),$(patsubst %/,%,$(dir $(1))),$(dir $(1))))
+endef
+
+# Definitions to handle the various suffixes allowed for C++ files.
+INTERNAL_CXX_SUFFIXES := .cc .cxx .cpp .c++
+define filter-cxx-files
+$(filter $(addprefix %,$(INTERNAL_CXX_SUFFIXES)),$(1))
+endef
+
+define filter-out-cxx-files
+$(filter-out $(addprefix %,$(INTERNAL_CXX_SUFFIXES)),$(1))
+endef
+
+define objects-from-cxx-files
+$(foreach _suffix,$(INTERNAL_CXX_SUFFIXES),$(patsubst %$(_suffix),%.o,$(filter %$(_suffix),$(1))))
+endef
+
+define unsupported-module-var
+$(if $(strip $($(THIS_MODULE)_$(1))),$(error In makefile $(THIS_MAKEFILE): Setting '$(THIS_MODULE)_$(1)' has no effect, because $(THIS_MODULE) has type $($(THIS_MODULE)_type)))
+endef
diff --git a/drivers/gpu/rogue_m/build/linux/generic_arm_android/Makefile b/drivers/gpu/rogue_m/build/linux/generic_arm_android/Makefile
new file mode 100644 (file)
index 0000000..3fb294a
--- /dev/null
@@ -0,0 +1,122 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+include ../config/preconfig.mk
+
+# If a TARGET_PRODUCT is specified but not a TARGET_DEVICE, try to
+# derive the TARGET_DEVICE from TARGET_PRODUCT.
+#
+ifeq ($(TARGET_DEVICE),)
+override TARGET_DEVICE := \
+ $(patsubst mini_%,%,$(patsubst full_%,%,$(TARGET_PRODUCT)))
+ifeq ($(TARGET_DEVICE),arm64_img)
+override TARGET_DEVICE := arm64
+endif
+ifeq ($(TARGET_DEVICE),armv7a_neon_img)
+override TARGET_DEVICE := armv7-a-neon
+endif
+endif
+
+ifeq ($(TARGET_DEVICE),)
+# Prefer arm64 now for MULTIARCH=1 builds.
+# Use TARGET_DEVICE=armv7-a-neon for 32-bit only builds.
+override TARGET_DEVICE := arm64
+endif
+
+ifeq ($(TARGET_DEVICE),armv7-a-neon)
+# The 32-bit only Android build is still using separate toolchains for
+# kernel and userspace, force this on the DDK side when it's detected.
+KERNEL_CROSS_COMPILE ?= arm-eabi-
+endif
+
+ifeq ($(MULTIARCH),1)
+override TARGET_DEVICE := rk3368
+else
+override TARGET_DEVICE := rk3368_32
+endif
+HAL_VARIANT ?= rk3368
+PVR_SYSTEM := rk3368
+NO_HARDWARE := 0
+LDM_PLATFORM := 1
+#RGX_BVNC ?= 1.75.2.30
+#rockchip G6110
+RGX_BVNC ?= 5.9.1.46
+
+include ../common/android/paths.mk
+include ../common/android/arch.mk
+include ../common/android/features.mk
+
+ifeq ($(SUPPORT_ADF),1)
+ifneq ($(is_at_least_lollipop),1)
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/device/img/generic/adf/libadf/include \
+ -isystem $(ANDROID_ROOT)/device/img/generic/adf/libadfhwc/include
+endif
+endif
+
+PVR_LDM_PLATFORM_PRE_REGISTERED := 1
+
+#zxl: build adf_fbdev.ko
+ifeq ($(SUPPORT_ADF),1)
+ADF_FBDEV ?= adf_fbdev
+KERNEL_COMPONENTS += $(ADF_FBDEV)
+endif
+
+ifneq ($(SUPPORT_ADF),1)
+ifeq ($(SUPPORT_DC),1)
+DISPLAY_CONTROLLER ?= dc_fbdev
+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER)
+ifeq ($(DISPLAY_CONTROLLER),dc_example)
+DC_EXAMPLE_WIDTH ?= 640
+DC_EXAMPLE_HEIGHT ?= 480
+DC_EXAMPLE_BIT_DEPTH ?= 32
+DC_EXAMPLE_DPI ?= 160
+endif
+endif
+endif
+
+#zxl: 3 fb buffer
+DC_FBDEV_NUM_PREFERRED_BUFFERS := 3
+
+CACHEFLUSH_TYPE ?= CACHEFLUSH_GENERIC
+
+include ../config/core.mk
+include ../common/3rdparty.mk
+include ../common/android/extra_config.mk
diff --git a/drivers/gpu/rogue_m/build/linux/kbuild/Makefile.template b/drivers/gpu/rogue_m/build/linux/kbuild/Makefile.template
new file mode 100644 (file)
index 0000000..6d7fb6e
--- /dev/null
@@ -0,0 +1,95 @@
+########################################################################### ###
+#@Title         Root kernel makefile
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# This top-level kbuild makefile builds all the Linux kernel modules in the
+# DDK. To run kbuild, this makefile is copied to $(TARGET_PRIMARY_OUT)/kbuild/Makefile
+# and make is invoked in $(TARGET_PRIMARY_OUT)/kbuild.
+
+# This makefile doesn't define any kbuild special variables apart from
+# ccflags-y and obj-m. The variables for objects are picked up by including
+# the kbuild makefile fragments named in $(INTERNAL_KBUILD_MAKEFILES). The
+# list of objects that these fragments make is collected in
+# $(INTERNAL_KBUILD_OBJECTS) and $(INTERNAL_EXTRA_KBUILD_OBJECTS). These
+# variables are set according to the build's $(KERNEL_COMPONENTS) and
+# $(EXTRA_PVRSRVKM_COMPONENTS). To add a new kernel module to the build, edit
+# these variables in the per-build Makefile.
+
+include $(OUT)/config_kernel.mk
+
+.SECONDARY:
+
+define symlink-source-file
+@if [ ! -e $(dir $@) ]; then mkdir -p $(dir $@); fi
+@if [ ! -h $@ ]; then ln -sf $< $@; fi
+endef
+
+bridge_base := $(BRIDGE_SOURCE_ROOT)
+
+$(OUT)/$(TARGET_PRIMARY_ARCH)/kbuild/%.c: $(TOP)/%.c
+       $(symlink-source-file)
+
+$(OUT)/$(TARGET_PRIMARY_ARCH)/kbuild/generated/%.c: $(bridge_base)/%.c
+       $(symlink-source-file)
+
+$(OUT)/$(TARGET_PRIMARY_ARCH)/kbuild/external/%.c: $(srctree)/%.c
+       $(symlink-source-file)
+
+ccflags-y += -D__linux__ -include $(OUT)/config_kernel.h \
+ -I$(OUT)/include \
+ -I$(TOP)/include \
+ -I$(TOP)/hwdefs/km \
+ -I$(TOP)/services/include \
+ -I$(TOP)/services/include/shared \
+ -I$(TOP)/services/shared/include \
+ -I$(TOP)/services/shared/common \
+ -I$(TOP)/services/system/$(PVR_SYSTEM) \
+ -I$(TOP)/services/system/include \
+ -I$(TOP)/services/server/common \
+ -I$(TOP)/services/server/devices/rgx \
+ -I$(TOP)/services/server/env/linux \
+ -I$(TOP)/services/server/include
+
+include $(INTERNAL_KBUILD_MAKEFILES)
+
+$(if $(pvrsrvkm-y),,$(error pvrsrvkm-y was empty, which could mean that srvkm is missing from $$(KERNEL_COMPONENTS)))
+pvrsrvkm-y += $(foreach _m,$(INTERNAL_EXTRA_KBUILD_OBJECTS:.o=),$($(_m)-y))
+
+obj-m += $(INTERNAL_KBUILD_OBJECTS)
diff --git a/drivers/gpu/rogue_m/build/linux/kbuild/kbuild.mk b/drivers/gpu/rogue_m/build/linux/kbuild/kbuild.mk
new file mode 100644 (file)
index 0000000..766cdb3
--- /dev/null
@@ -0,0 +1,94 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(TARGET_PRIMARY_OUT)/kbuild/Makefile: $(MAKE_TOP)/kbuild/Makefile.template
+       @[ ! -e $(dir $@) ] && mkdir -p $(dir $@) || true
+       $(CP) -f $< $@
+
+# We need to make INTERNAL_KBUILD_MAKEFILES absolute because the files will be
+# read while chdir'd into $(KERNELDIR)
+INTERNAL_KBUILD_MAKEFILES := $(abspath $(foreach _m,$(KERNEL_COMPONENTS) $(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(error Unknown kbuild module "$(_m)"))))
+INTERNAL_KBUILD_OBJECTS := $(foreach _m,$(KERNEL_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier)))
+INTERNAL_EXTRA_KBUILD_OBJECTS := $(foreach _m,$(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier)))
+.PHONY: kbuild kbuild_clean kbuild_check
+
+kbuild_check:
+       @: $(if $(strip $(KERNELDIR)),,$(error KERNELDIR must be set))
+       @: $(call directory-must-exist,$(KERNELDIR))
+       @: $(foreach _m,$(ALL_KBUILD_MODULES),$(if $(wildcard $(abspath $(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)))),,$(error In makefile $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)): Module $(_m) requires kbuild makefile $(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)), which is missing)))
+       @: $(if $(filter-out command line override,$(origin build)),,$(error Overriding $$(build) (with "make build=...") will break kbuild))
+
+# Services server headers are generated as part of running the bridge
+# generator, which might be included in KM code. So as well as depending on
+# the kbuild Makefile, we need to make kbuild also depend on each bridge
+# module (including direct bridges), so that 'make kbuild' in a clean tree
+# works.
+kbuild: kbuild_check $(TARGET_PRIMARY_OUT)/kbuild/Makefile $(BRIDGES) $(DIRECT_BRIDGES)
+       $(if $(V),,@)$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) \
+               M=$(abspath $(TARGET_PRIMARY_OUT)/kbuild) \
+               INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \
+               INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \
+               INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \
+               BRIDGE_SOURCE_ROOT=$(abspath $(BRIDGE_SOURCE_ROOT)) \
+               TARGET_PRIMARY_ARCH=$(TARGET_PRIMARY_ARCH) \
+               CROSS_COMPILE="$(CCACHE) $(KERNEL_CROSS_COMPILE)" \
+               EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \
+               CC=$(KERNEL_CROSS_COMPILE)gcc V=$(V) W=$(W) \
+               CHECK="$(patsubst @%,%,$(CHECK))" $(if $(CHECK),C=1,) \
+               TOP=$(TOP)
+       @for kernel_module in $(addprefix $(TARGET_PRIMARY_OUT)/kbuild/,$(INTERNAL_KBUILD_OBJECTS:.o=.ko)); do \
+               cp $$kernel_module $(TARGET_PRIMARY_OUT); \
+       done
+
+kbuild_clean: kbuild_check $(TARGET_PRIMARY_OUT)/kbuild/Makefile
+       $(if $(V),,@)$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) \
+               M=$(abspath $(TARGET_PRIMARY_OUT)/kbuild) \
+               INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \
+               INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \
+               INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \
+               BRIDGE_SOURCE_ROOT=$(abspath $(BRIDGE_SOURCE_ROOT)) \
+               TARGET_PRIMARY_ARCH=$(TARGET_PRIMARY_ARCH) \
+               CROSS_COMPILE="$(CCACHE) $(KERNEL_CROSS_COMPILE)" \
+               EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \
+               CC=$(KERNEL_CROSS_COMPILE)gcc V=$(V) W=$(W) \
+               TOP=$(TOP) clean
+
+kbuild_install: install
+kbuild: install_script_km
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/host_i386.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/host_i386.mk
new file mode 100644 (file)
index 0000000..b6bb23f
--- /dev/null
@@ -0,0 +1,62 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_HOST_BUILD := true
+
+MODULE_CC := $(HOST_CC) $(HOST_FORCE_32BIT)
+MODULE_CXX := $(HOST_CXX) $(HOST_FORCE_32BIT)
+
+MODULE_CFLAGS   := $(ALL_HOST_CFLAGS) $($(THIS_MODULE)_cflags) $(HOST_FORCE_32BIT)
+MODULE_CXXFLAGS := $(ALL_HOST_CXXFLAGS) $($(THIS_MODULE)_cxxflags) $(HOST_FORCE_32BIT)
+MODULE_LDFLAGS  := $(ALL_HOST_LDFLAGS) -L$(MODULE_OUT) $($(THIS_MODULE)_ldflags) $(HOST_FORCE_32BIT)
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_HOST_CFLAGS) $(ALL_HOST_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/extra_host.mk
+else
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/host_x86_64.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/host_x86_64.mk
new file mode 100644 (file)
index 0000000..4c50c62
--- /dev/null
@@ -0,0 +1,62 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_HOST_BUILD := true
+
+MODULE_CC := $(HOST_CC)
+MODULE_CXX := $(HOST_CXX)
+
+MODULE_CFLAGS   := $(ALL_HOST_CFLAGS) $($(THIS_MODULE)_cflags)
+MODULE_CXXFLAGS := $(ALL_HOST_CXXFLAGS) $($(THIS_MODULE)_cxxflags)
+MODULE_LDFLAGS  := $(ALL_HOST_LDFLAGS) -L$(MODULE_OUT) $($(THIS_MODULE)_ldflags)
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_HOST_CFLAGS) $(ALL_HOST_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/extra_host.mk
+else
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/target_aarch64.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/target_aarch64.mk
new file mode 100644 (file)
index 0000000..f821ed7
--- /dev/null
@@ -0,0 +1,98 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_CC := $(CC)
+MODULE_CXX := $(CXX)
+
+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags)
+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags)
+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags) -L$(MODULE_OUT) -Xlinker -rpath-link=$(MODULE_OUT)
+
+# Since this is a target module, add system-specific include flags.
+MODULE_INCLUDE_FLAGS := $(SYS_INCLUDES) $(MODULE_INCLUDE_FLAGS)
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+_obj := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj
+
+# Linker flags used to find system libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS += \
+ -L$(_obj)/lib \
+ -Xlinker -rpath-link=$(_obj)/lib \
+ -L$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib64 \
+ -Xlinker -rpath-link=$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib64
+
+# Add architecture-specific Android include flags
+MODULE_INCLUDE_FLAGS := \
+ -isystem $(ANDROID_ROOT)/bionic/libc/arch-arm64/include \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/uapi/asm-arm64 \
+ -isystem $(ANDROID_ROOT)/bionic/libm/include/arm64 \
+ $(MODULE_INCLUDE_FLAGS)
+
+MODULE_LDFLAGS += $(MODULE_SYSTEM_LIBRARY_DIR_FLAGS)
+
+MODULE_EXE_LDFLAGS := \
+ -Bdynamic -nostdlib -Wl,-dynamic-linker,/system/bin/linker64 \
+ -lc -ldl -lcutils
+MODULE_LIB_LDFLAGS := $(MODULE_EXE_LDFLAGS)
+
+MODULE_EXE_CRTBEGIN := $(_obj)/lib/crtbegin_dynamic.o
+MODULE_EXE_CRTEND := $(_obj)/lib/crtend_android.o
+
+MODULE_LIB_CRTBEGIN := $(_obj)/lib/crtbegin_so.o
+MODULE_LIB_CRTEND := $(_obj)/lib/crtend_so.o
+
+MODULE_LIBGCC := $(LIBGCC)
+endif
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_CFLAGS) $(ALL_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+MODULE_ARCH_BITNESS := 64
+
+# Neutrino qcc requires "-Wc," prefix for compiler flags
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/modify_moduledefs.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/target_armv7-a.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/target_armv7-a.mk
new file mode 100644 (file)
index 0000000..ede0050
--- /dev/null
@@ -0,0 +1,103 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_CC := $(CC_SECONDARY) -march=armv7-a -mfloat-abi=softfp
+MODULE_CXX := $(CXX_SECONDARY) -march=armv7-a -mfloat-abi=softfp
+
+ifneq ($(BUILD),debug)
+MODULE_CC := $(MODULE_CC) -mthumb
+MODULE_CXX := $(MODULE_CXX) -mthumb
+endif
+
+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags)
+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags)
+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags) -L$(MODULE_OUT) -Xlinker -rpath-link=$(MODULE_OUT)
+
+# Since this is a target module, add system-specific include flags.
+MODULE_INCLUDE_FLAGS := $(SYS_INCLUDES) $(MODULE_INCLUDE_FLAGS)
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+_obj := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj$(if $(MULTIARCH),_arm,)
+
+# Linker flags used to find system libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS += \
+ -L$(_obj)/lib \
+ -Xlinker -rpath-link=$(_obj)/lib \
+ -L$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib \
+ -Xlinker -rpath-link=$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib
+
+# Add architecture-specific Android include flags
+MODULE_INCLUDE_FLAGS := \
+ -isystem $(ANDROID_ROOT)/bionic/libc/arch-arm/include \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/uapi/asm-arm \
+ -isystem $(ANDROID_ROOT)/bionic/libm/include/arm \
+ $(MODULE_INCLUDE_FLAGS)
+
+MODULE_LDFLAGS += $(MODULE_SYSTEM_LIBRARY_DIR_FLAGS)
+
+MODULE_EXE_LDFLAGS := \
+ -Bdynamic -nostdlib -Wl,-dynamic-linker,/system/bin/linker \
+ -lc -ldl -lcutils
+MODULE_LIB_LDFLAGS := $(MODULE_EXE_LDFLAGS)
+
+MODULE_EXE_CRTBEGIN := $(_obj)/lib/crtbegin_dynamic.o
+MODULE_EXE_CRTEND := $(_obj)/lib/crtend_android.o
+
+MODULE_LIB_CRTBEGIN := $(_obj)/lib/crtbegin_so.o
+MODULE_LIB_CRTEND := $(_obj)/lib/crtend_so.o
+
+MODULE_LIBGCC := $(LIBGCC_SECONDARY)
+endif
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_CFLAGS) $(ALL_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+MODULE_ARCH_BITNESS := 32
+
+# Neutrino qcc requires "-Wc," prefix for compiler flags
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/modify_moduledefs.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/target_i686.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/target_i686.mk
new file mode 100644 (file)
index 0000000..bf9ff29
--- /dev/null
@@ -0,0 +1,102 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_CC := $(CC_SECONDARY) $(TARGET_FORCE_32BIT) -march=i686
+MODULE_CXX := $(CXX_SECONDARY) $(TARGET_FORCE_32BIT) -march=i686
+
+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags) $(TARGET_FORCE_32BIT) -march=i686
+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags) $(TARGET_FORCE_32BIT) -march=i686
+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags) -L$(MODULE_OUT) -Xlinker -rpath-link=$(MODULE_OUT) $(TARGET_FORCE_32BIT)
+
+# Since this is a target module, add system-specific include flags.
+MODULE_INCLUDE_FLAGS := $(SYS_INCLUDES) $(MODULE_INCLUDE_FLAGS)
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+_obj := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj$(if $(MULTIARCH),_x86,)
+
+# Linker flags used to find system libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS += \
+ -L$(_obj)/lib \
+ -Xlinker -rpath-link=$(_obj)/lib \
+ -L$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib \
+ -Xlinker -rpath-link=$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib
+
+# Add architecture-specific Android include flags
+MODULE_INCLUDE_FLAGS := \
+ -isystem $(ANDROID_ROOT)/bionic/libc/arch-x86/include \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/uapi/asm-x86 \
+ -isystem $(ANDROID_ROOT)/bionic/libm/include/i387 \
+ $(MODULE_INCLUDE_FLAGS)
+
+MODULE_LDFLAGS += $(MODULE_SYSTEM_LIBRARY_DIR_FLAGS)
+
+MODULE_EXE_LDFLAGS := \
+ -Bdynamic -nostdlib -Wl,-dynamic-linker,/system/bin/linker \
+ -lc -ldl -lcutils
+MODULE_LIB_LDFLAGS := $(MODULE_EXE_LDFLAGS)
+
+MODULE_EXE_CRTBEGIN := $(_obj)/lib/crtbegin_dynamic.o
+MODULE_EXE_CRTEND := $(_obj)/lib/crtend_android.o
+
+MODULE_LIB_CRTBEGIN := $(_obj)/lib/crtbegin_so.o
+MODULE_LIB_CRTEND := $(_obj)/lib/crtend_so.o
+
+MODULE_LIBGCC := $(LIBGCC_SECONDARY)
+else
+# On Linux, we currently don't need to specify any flags to find the system
+# libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS :=
+endif
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_CFLAGS) $(ALL_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+MODULE_ARCH_BITNESS := 32
+
+# Neutrino qcc requires "-Wc," prefix for compiler flags
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/modify_moduledefs.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/target_neutral.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/target_neutral.mk
new file mode 100644 (file)
index 0000000..6b58e5e
--- /dev/null
@@ -0,0 +1,44 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_BISON_FLAGS := $(ALL_BISON_FLAGS) $($(THIS_MODULE)_bisonflags)
+MODULE_FLEX_FLAGS := $(ALL_FLEX_FLAGS) $($(THIS_MODULE)_flexflags)
+MODULE_FLEXXX_FLAGS := $(ALL_FLEXXX_FLAGS) $($(THIS_MODULE)_flexxxflags)
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs/target_x86_64.mk b/drivers/gpu/rogue_m/build/linux/moduledefs/target_x86_64.mk
new file mode 100644 (file)
index 0000000..ab9d5b2
--- /dev/null
@@ -0,0 +1,100 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_CC := $(CC) -march=x86-64
+MODULE_CXX := $(CXX) -march=x86-64
+
+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags) -march=x86-64
+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags) -march=x86-64
+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags) -L$(MODULE_OUT) -Xlinker -rpath-link=$(MODULE_OUT)
+
+# Since this is a target module, add system-specific include flags.
+MODULE_INCLUDE_FLAGS := $(SYS_INCLUDES) $(MODULE_INCLUDE_FLAGS)
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+# Linker flags used to find system libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS += \
+ -L$(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib \
+ -Xlinker -rpath-link=$(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib \
+ -L$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib64 \
+ -Xlinker -rpath-link=$(TARGET_ROOT)/product/$(TARGET_DEVICE)/system/lib64
+
+# Add architecture-specific Android include flags
+MODULE_INCLUDE_FLAGS := \
+ -isystem $(ANDROID_ROOT)/bionic/libc/arch-x86_64/include \
+ -isystem $(ANDROID_ROOT)/bionic/libc/kernel/uapi/asm-x86 \
+ -isystem $(ANDROID_ROOT)/bionic/libm/include/amd64 \
+ $(MODULE_INCLUDE_FLAGS)
+
+MODULE_LDFLAGS += $(MODULE_SYSTEM_LIBRARY_DIR_FLAGS)
+
+MODULE_EXE_LDFLAGS := \
+ -Bdynamic -nostdlib -Wl,-dynamic-linker,/system/bin/linker64 \
+ -lc -ldl -lcutils
+MODULE_LIB_LDFLAGS := $(MODULE_EXE_LDFLAGS)
+
+MODULE_EXE_CRTBEGIN := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib/crtbegin_dynamic.o
+MODULE_EXE_CRTEND := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib/crtend_android.o
+
+MODULE_LIB_CRTBEGIN := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib/crtbegin_so.o
+MODULE_LIB_CRTEND := $(TARGET_ROOT)/product/$(TARGET_DEVICE)/obj/lib/crtend_so.o
+
+MODULE_LIBGCC := $(LIBGCC)
+else
+# On Linux, we currently don't need to specify any flags to find the system
+# libraries.
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS :=
+endif
+
+ifneq ($(BUILD),debug)
+ifeq ($(USE_LTO),1)
+MODULE_LDFLAGS := \
+ $(sort $(filter-out -W% -D%,$(ALL_CFLAGS) $(ALL_CXXFLAGS))) \
+ $(MODULE_LDFLAGS)
+endif
+endif
+
+MODULE_ARCH_BITNESS := 64
+
+# Neutrino qcc requires "-Wc," prefix for compiler flags
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/modify_moduledefs.mk
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/moduledefs_common.mk b/drivers/gpu/rogue_m/build/linux/moduledefs_common.mk
new file mode 100644 (file)
index 0000000..7a0c2cc
--- /dev/null
@@ -0,0 +1,146 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_OUT := $(RELATIVE_OUT)/$(MODULE_ARCH)
+MODULE_INTERMEDIATES_DIR := $(MODULE_OUT)/intermediates/$(THIS_MODULE)
+
+MODULE_TARGETS :=
+MODULE_HOST_BUILD :=
+MODULE_CLEAN_TARGETS :=
+MODULE_CLOBBER_TARGETS :=
+
+MODULE_CFLAGS :=
+MODULE_CXXFLAGS :=
+MODULE_LDFLAGS :=
+MODULE_BISON_FLAGS :=
+MODULE_FLEX_FLAGS :=
+MODULE_FLEXXX_FLAGS :=
+
+MODULE_ARCH_BITNESS :=
+
+# Only allow cflags that do not affect code generation. This is to ensure
+# proper binary compatibility when LTO (Link-Time Optimization) is enabled.
+# We make exceptions for the below flags which will all fail linkage in
+# non-LTO mode if incorrectly specified.
+#
+# NOTE: Only used by static_library and objects right now. Other module
+# types should not be affected by complex code generation flags w/ LTO.
+# Set MODULE_CHECK_CFLAGS in the module makefile to enable this check.
+MODULE_CHECK_CFLAGS :=
+MODULE_ALLOWED_CFLAGS := -W% -D% -std=% -fPIC -fPIE -pie -m32
+
+# -L flags for library search dirs: these are relative to $(TOP), unless
+# they're absolute paths
+MODULE_LIBRARY_DIR_FLAGS := $(foreach _path,$($(THIS_MODULE)_libpaths),$(if $(filter /%,$(_path)),-L$(call relative-to-top,$(_path)),-L$(_path)))
+# -L options to find system libraries (may be arch-specific)
+MODULE_SYSTEM_LIBRARY_DIR_FLAGS :=
+# -I flags for header search dirs (same rules as for -L)
+MODULE_INCLUDE_FLAGS := $(foreach _path,$($(THIS_MODULE)_includes),$(if $(filter /%,$(_path)),-I$(call relative-to-top,$(_path)),-I$(_path)))
+
+# If the build provides some external khronos include flags, and the module
+# hasn't explicitly opted out of path substitution, prepend the system path
+# to the DDK khronos header include path. This causes the platform headers
+# to override the DDK versions. This is the default behaviour for Android.
+ifneq ($(SYS_KHRONOS_INCLUDES),)
+ifneq ($($(THIS_MODULE)_force_internal_khronos_headers),1)
+MODULE_INCLUDE_FLAGS := $(patsubst -Iinclude/khronos,$(SYS_KHRONOS_INCLUDES) -Iinclude/khronos,$(MODULE_INCLUDE_FLAGS))
+endif
+endif
+
+# These define the rules for finding source files.
+#
+# - If a name begins with a slash, we strip $(TOP) off the front if it
+#   begins with $(TOP). This is so that we don't get really long error
+#   messages from the compiler if the source tree is in a deeply nested
+#   directory, but we still do get absolute paths if you say "make
+#   OUT=/tmp/somewhere"
+#
+# - Otherwise, if a name contains a slash and begins with $(OUT), we leave
+#   it as it is. This is so you can say "module_src :=
+#   $(TARGET_INTERMEDIATES)/something/generated.c"
+#
+# - Otherwise, we assume it's a path referring to somewhere under the
+#   directory containing Linux.mk, and add $(THIS_DIR) to it
+#
+_SOURCES_WITHOUT_SLASH := \
+ $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),,$(_s))))
+_SOURCES_WITH_SLASH := \
+ $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),$(_s),)))
+MODULE_SOURCES := $(addprefix $(THIS_DIR)/,$(_SOURCES_WITHOUT_SLASH))
+MODULE_SOURCES += $(call relative-to-top,$(filter /%,$(_SOURCES_WITH_SLASH)))
+
+_RELATIVE_SOURCES_WITH_SLASH := \
+ $(filter-out /%,$(_SOURCES_WITH_SLASH))
+_OUTDIR_RELATIVE_SOURCES_WITH_SLASH := \
+ $(filter $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH))
+_THISDIR_RELATIVE_SOURCES_WITH_SLASH := \
+ $(filter-out $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH))
+MODULE_SOURCES += $(_OUTDIR_RELATIVE_SOURCES_WITH_SLASH)
+MODULE_SOURCES += $(addprefix $(THIS_DIR)/,$(_THISDIR_RELATIVE_SOURCES_WITH_SLASH))
+
+# Add generated sources
+MODULE_SOURCES += $(addprefix $(MODULE_OUT)/,$($(THIS_MODULE)_src_relative))
+
+# MODULE_LIBRARY_FLAGS contains the flags to link each library. The rules
+# are:
+#
+#  module_staticlibs := mylib
+#  module_libs := mylib
+#    Use -lmylib
+#
+#  module_extlibs := mylib
+#    Use $(libmylib_ldflags) if that variable is defined (empty counts as
+#    defined). Otherwise use -lmylib
+#
+#  module_libs := :mylib
+#    Use -l:mylib.so
+
+MODULE_LIBRARY_FLAGS := \
+ $(addprefix -l, $($(THIS_MODULE)_staticlibs)) \
+ $(addprefix -l, $(filter-out :%, $($(THIS_MODULE)_libs))) \
+ $(addprefix -l, $(addsuffix .so, $(filter :%,$($(THIS_MODULE)_libs)))) \
+ $(foreach _lib,$($(THIS_MODULE)_extlibs),$(if $(filter undefined,$(origin lib$(_lib)_ldflags)),-l$(_lib),$(lib$(_lib)_ldflags)))
+
+# pkg-config integration; primarily used by X.Org
+# We don't support arbitrary CFLAGS yet (just includes)
+$(foreach _package,$($(THIS_MODULE)_packages),\
+ $(eval MODULE_INCLUDE_FLAGS     += `pkg-config --cflags-only-I $(_package)`)\
+ $(eval MODULE_LIBRARY_FLAGS     += `pkg-config --libs-only-l $(_package)`)\
+ $(eval MODULE_LIBRARY_DIR_FLAGS += `pkg-config --libs-only-L $(_package)`))
diff --git a/drivers/gpu/rogue_m/build/linux/modules.mk b/drivers/gpu/rogue_m/build/linux/modules.mk
new file mode 100644 (file)
index 0000000..971f21a
--- /dev/null
@@ -0,0 +1,48 @@
+########################################################################### ###
+#@Title         Module processing
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Bits for processing $(modules) after reading in each Linux.mk
+
+#$(info ---- $(modules) ----)
+
+$(foreach _m,$(modules),$(if $(filter $(_m),$(ALL_MODULES)),$(error In makefile $(THIS_MAKEFILE): Duplicate module $(_m) (first seen in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m))) listed in $$(modules)),$(eval $(call register-module,$(_m)))))
+
+ALL_MODULES += $(modules)
diff --git a/drivers/gpu/rogue_m/build/linux/modules/kernel_module.mk b/drivers/gpu/rogue_m/build/linux/modules/kernel_module.mk
new file mode 100644 (file)
index 0000000..9a2ae69
--- /dev/null
@@ -0,0 +1,92 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Rules for making kernel modules with kbuild. This makefile doesn't define
+# any rules that build the modules, it only copies the kbuild Makefile into
+# the right place and then invokes kbuild to do the actual build
+
+$(call target-build-only,kernel module)
+
+MODULE_KBUILD_DIR := $(MODULE_OUT)/kbuild
+
+# $(THIS_MODULE)_makefile names the kbuild makefile fragment used to build
+# this module's objects
+$(call must-be-nonempty,$(THIS_MODULE)_makefile)
+MODULE_KBUILD_MAKEFILE := $($(THIS_MODULE)_makefile)
+
+# $(THIS_MODULE)_target specifies the name of the kernel module
+$(call must-be-nonempty,$(THIS_MODULE)_target)
+MODULE_TARGETS := $($(THIS_MODULE)_target)
+MODULE_KBUILD_OBJECTS := $($(THIS_MODULE)_target:.ko=.o)
+
+$(call module-info-line,kernel module: $(MODULE_TARGETS))
+
+# Unusually, we define $(THIS_MODULE)_install_path if the user didn't, as we
+# can't use MODULE_INSTALL_PATH in the scripts.mk logic.
+ifeq ($($(THIS_MODULE)_install_path),)
+$(THIS_MODULE)_install_path := \
+ $${MOD_DESTDIR}/$(patsubst $(MODULE_OUT)/%,%,$(MODULE_TARGETS))
+endif
+
+MODULE_INSTALL_PATH := $($(THIS_MODULE)_install_path)
+
+# Here we could maybe include $(MODULE_KBUILD_MAKEFILE) and look at
+# $(MODULE_KBUILD_OBJECTS)-y to see which source files might be built
+
+.PHONY: $(THIS_MODULE)
+$(THIS_MODULE): MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE)
+$(THIS_MODULE): MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS)
+$(THIS_MODULE):
+       @echo "kbuild module '$@'"
+       @echo " MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE)"
+       @echo " MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS)"
+       @echo ' Being built:' $(if $(filter $@,$(KERNEL_COMPONENTS)),"yes (separate module)",$(if $(filter $@,$(EXTRA_PVRSRVKM_COMPONENTS)),"yes (into pvrsrvkm)","no"))
+       @echo "Module $@ is a kbuild module. Run 'make kbuild' to make it"
+       @false
+
+$(MODULE_INTERMEDIATES_DIR)/.install: MODULE_TYPE := $($(THIS_MODULE)_type)
+$(MODULE_INTERMEDIATES_DIR)/.install: MODULE_INSTALL_PATH := $(MODULE_INSTALL_PATH)
+$(MODULE_INTERMEDIATES_DIR)/.install: MODULE_TARGETS := $(patsubst $(MODULE_OUT)/%,%,$(MODULE_TARGETS))
+$(MODULE_INTERMEDIATES_DIR)/.install: $(THIS_MAKEFILE) | $(MODULE_INTERMEDIATES_DIR)
+       @echo 'install_file $(MODULE_TARGETS) $(MODULE_INSTALL_PATH) "$(MODULE_TYPE)" 0644 0:0' >$@
+
+ALL_KBUILD_MODULES += $(THIS_MODULE)
+INTERNAL_KBUILD_MAKEFILE_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_MAKEFILE)
+INTERNAL_KBUILD_OBJECTS_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_OBJECTS)
diff --git a/drivers/gpu/rogue_m/build/linux/pc_android/Makefile b/drivers/gpu/rogue_m/build/linux/pc_android/Makefile
new file mode 100644 (file)
index 0000000..f82bd65
--- /dev/null
@@ -0,0 +1,140 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+include ../config/preconfig.mk
+
+# If a TARGET_PRODUCT is specified but not a TARGET_DEVICE, try to
+# derive the TARGET_DEVICE from TARGET_PRODUCT.
+#
+ifeq ($(TARGET_DEVICE),)
+override TARGET_DEVICE := \
+ $(patsubst mini_%,%,$(patsubst full_%,%,$(TARGET_PRODUCT)))
+endif
+
+ifeq ($(TARGET_DEVICE),)
+override TARGET_DEVICE := pc
+endif
+
+HAL_VARIANT := pc
+
+RGX_BVNC ?= 1.82.4.5
+# TC BONNIE:
+#RGX_BVNC ?= 4.31.4.55
+
+include ../common/android/paths.mk
+include ../common/android/arch.mk
+include ../common/android/features.mk
+
+ifeq ($(SUPPORT_ADF),1)
+ifneq ($(is_at_least_lollipop),1)
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/device/img/pc/adf/libadf/include \
+ -isystem $(ANDROID_ROOT)/device/img/pc/adf/libadfhwc/include
+endif
+endif
+
+ifeq ($(NO_HARDWARE),1)
+ LDM_PLATFORM := 1
+ PVR_SYSTEM := rgx_nohw
+ # If we end up using dc_fbdev, Android always wants to be
+ # triple buffered in when running in pure-software mode.
+ DC_FBDEV_NUM_PREFERRED_BUFFERS := 3
+else
+ ifeq ($(SUPPORT_ADF),1)
+  PVR_LDM_PLATFORM_PRE_REGISTERED := 1
+  LMA := 1
+  LDM_PLATFORM := 1
+  PVR_SYSTEM := rgx_linux_apollo
+  SUPPORT_SYSTEM_INTERRUPT_HANDLING := 1
+  ION_DEFAULT_HEAP_ID_MASK := (1 << (ION_HEAP_TYPE_CUSTOM + 2))
+ else
+  LDM_PCI := 1
+  PVR_SYSTEM := rgx_tc
+  TC_MEMORY_CONFIG := TC_MEMORY_LOCAL
+  SUPPORT_SYSTEM_INTERRUPT_HANDLING := 1
+ endif
+endif
+
+ifeq ($(SUPPORT_ADF),1)
+ ifneq ($(NO_HARDWARE),1)
+  DISPLAY_CONTROLLER ?= adf_pdp
+ endif
+else
+ ifeq ($(NO_HARDWARE),1)
+  DISPLAY_CONTROLLER ?= dc_example
+ else
+  DISPLAY_CONTROLLER ?= dc_pdp
+ endif
+endif
+
+ifeq ($(DISPLAY_CONTROLLER),adf_pdp)
+ADF_PDP_WIDTH ?= 1280
+ADF_PDP_HEIGHT ?= 720
+KERNEL_COMPONENTS += apollo
+endif
+
+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER)
+
+CACHEFLUSH_TYPE ?= CACHEFLUSH_X86
+
+PVR_ANDROID_DEFER_CLEAR ?= 1
+
+ifeq ($(PVR_SYSTEM),rgx_tc)
+ifeq ($(TC_MEMORY_CONFIG),TC_MEMORY_LOCAL)
+LMA := 1
+# Tell ion that we want memory from the test chip local memory
+# heap. The choice of ION_HEAP_TYPE_CUSTOM+1 as the ID is
+# arbitrary, but it has to match the one specified in the
+# TC-specific ion support code.
+ION_DEFAULT_HEAP_ID_MASK := 1 << (ION_HEAP_TYPE_CUSTOM + 1)
+endif
+endif
+
+ifeq ($(DISPLAY_CONTROLLER),dc_pdp)
+DCPDP_WIDTH ?= 1280
+DCPDP_HEIGHT ?= 720
+DCPDP_NO_INTERRUPTS ?= 1
+endif
+
+include ../config/core.mk
+include ../common/android/extra_config.mk
+include ../common/pvrgdb.mk
+include ../common/3rdparty.mk
+include ../common/testchip.mk
diff --git a/drivers/gpu/rogue_m/build/linux/prepare_tree.mk b/drivers/gpu/rogue_m/build/linux/prepare_tree.mk
new file mode 100644 (file)
index 0000000..d593143
--- /dev/null
@@ -0,0 +1,56 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+.PHONY: prepare_tree
+
+prepare_tree:
+
+INTERNAL_INCLUDED_PREPARE_HEADERS :=
+-include build/linux/prepare_headers.mk
+ifneq ($(INTERNAL_INCLUDED_PREPARE_HEADERS),true)
+missing_headers := $(strip $(shell test ! -e include/pvrversion.h && echo true))
+ifdef missing_headers
+$(info )
+$(info ** include/pvrversion.h is missing, and cannot be rebuilt.)
+$(info ** Cannot continue.)
+$(info )
+$(error Missing headers)
+endif
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/pvrversion.mk b/drivers/gpu/rogue_m/build/linux/pvrversion.mk
new file mode 100644 (file)
index 0000000..10c25f3
--- /dev/null
@@ -0,0 +1,57 @@
+########################################################################### ###
+#@Title         Extract info from pvrversion.h
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Version information
+PVRVERSION_H   := $(call if-exists,include/pvrversion.h,$(OUT)/include/pvrversion.h)
+
+ifneq ($(wildcard $(PVRVERSION_H)),)
+
+# scripts.mk uses these to set the install script's version suffix
+PVRVERSION_MAJ        := $(shell perl -ne '/\sPVRVERSION_MAJ\s+(\w+)/          and print $$1' $(PVRVERSION_H))
+PVRVERSION_MIN        := $(shell perl -ne '/\sPVRVERSION_MIN\s+(\w+)/          and print $$1' $(PVRVERSION_H))
+PVRVERSION_FAMILY     := $(shell perl -ne '/\sPVRVERSION_FAMILY\s+"(\S+)"/     and print $$1' $(PVRVERSION_H))
+PVRVERSION_BRANCHNAME := $(shell perl -ne '/\sPVRVERSION_BRANCHNAME\s+"(\S+)"/ and print $$1' $(PVRVERSION_H))
+PVRVERSION_BUILD      := $(shell perl -ne '/\sPVRVERSION_BUILD\s+(\w+)/        and print $$1' $(PVRVERSION_H))
+
+PVRVERSION_NUM := $(PVRVERSION_MAJ).$(PVRVERSION_MIN).$(PVRVERSION_BUILD)
+PVRVERSION := "$(PVRVERSION_FAMILY)_$(PVRVERSION_BRANCHNAME)\@$(PVRVERSION_BUILD)"
+
+endif
diff --git a/drivers/gpu/rogue_m/build/linux/scripts.mk b/drivers/gpu/rogue_m/build/linux/scripts.mk
new file mode 100644 (file)
index 0000000..766a8d7
--- /dev/null
@@ -0,0 +1,352 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifeq ($(SUPPORT_ANDROID_PLATFORM),)
+
+define if-component
+ ifneq ($$(filter $(1),$$(COMPONENTS)),)
+  M4DEFS += $(2)
+ endif
+endef
+
+define if-kernel-component
+ ifneq ($$(filter $(1),$$(KERNEL_COMPONENTS)),)
+  M4DEFS_K += $(2)
+ endif
+endef
+
+# common.m4 lives here
+#
+M4FLAGS := -I$(MAKE_TOP)/scripts
+
+# These defs are required for both KM and UM install script.
+M4DEFS_K := \
+ -DPVRVERSION="$(PVRVERSION)" \
+ -DPVR_BUILD_DIR=$(PVR_BUILD_DIR) \
+ -DPVRSRV_MODNAME=$(PVRSRV_MODNAME)
+
+ifeq ($(SUPPORT_DRM),1)
+ M4DEFS_K += \
+  -DSUPPORT_DRM=1
+endif
+
+ifeq ($(SUPPORT_DRM_DC_MODULE),1)
+ M4DEFS_K += \
+  -DSUPPORT_DRM_DC_MODULE=1
+endif
+
+ifeq ($(PDUMP),1)
+ M4DEFS_K += -DPDUMP=1
+endif
+
+ifneq ($(DISPLAY_CONTROLLER),)
+ $(eval $(call if-kernel-component,$(DISPLAY_CONTROLLER),\
+  -DDISPLAY_CONTROLLER=$(DISPLAY_CONTROLLER)))
+endif
+
+# These defs are not derived from user variables
+#
+M4DEFS := \
+ -DSOLIB_VERSION=$(PVRVERSION_MAJ).$(PVRVERSION_MIN).$(PVRVERSION_BUILD)
+
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+M4DEFS += \
+  -DSUPPORT_KERNEL_SRVINIT=1 \
+  -DFW_DESTDIR=$(FW_DESTDIR) \
+  -DRGX_FW_FILENAME=$(RGX_FW_FILENAME)
+endif
+
+# XOrg support options are convoluted, so don't bother with if-component.
+ifneq ($(filter pvr_video,$(COMPONENTS)),) # This is an X build
+ M4DEFS += -DSUPPORT_LWS=1
+ M4DEFS += -DSUPPORT_XORG=1
+ M4DEFS += -DXORG_EXPLICIT_PVR_SERVICES_LOAD=$(XORG_EXPLICIT_PVR_SERVICES_LOAD)
+
+ ifneq ($(XORG_WAYLAND),1)
+  M4DEFS += -DXORG_WAYLAND=1
+ endif
+
+ ifeq ($(LWS_NATIVE),1)
+  M4DEFS += -DPVR_XORG_DESTDIR=/usr/bin
+  M4DEFS += -DPVR_CONF_DESTDIR=/etc/X11
+  $(eval $(call if-component,opengl_mesa,-DSUPPORT_MESA=1))
+ else
+  M4DEFS += -DLWS_INSTALL_TREE=1
+  M4DEFS += -DPVR_XORG_DESTDIR=$(LWS_PREFIX)/bin
+  M4DEFS += -DPVR_CONF_DESTDIR=$(LWS_PREFIX)/etc/X11
+  $(eval $(call if-component,pvr_input, -DSUPPORT_DDX_INPUT=1))
+  $(eval $(call if-component,opengl_mesa,-DSUPPORT_LIBGL=1 -DSUPPORT_MESA=1))
+ endif
+else # This is a non-X build
+ ifeq ($(WINDOW_SYSTEM),wayland)
+  M4DEFS += -DSUPPORT_LWS=1
+  M4DEFS += -DSUPPORT_WAYLAND=1
+
+  ifeq ($(LWS_NATIVE),1)
+  else
+   M4DEFS += -DLWS_INSTALL_TREE=1
+  endif
+ else # This is a non-X and Wayland build
+  $(eval $(call if-component,opengl,-DSUPPORT_LIBGL=1))
+ endif
+endif
+
+# Map other COMPONENTS on to SUPPORT_ defs
+#
+$(eval $(call if-component,opengles1,\
+ -DSUPPORT_OPENGLES1=1 -DOGLES1_MODULE=$(opengles1_target) \
+ -DSUPPORT_OPENGLES1_V1_ONLY=0))
+$(eval $(call if-component,opengles3,\
+ -DSUPPORT_OPENGLES3=1 -DOGLES3_MODULE=$(opengles3_target)))
+$(eval $(call if-component,egl,\
+ -DSUPPORT_LIBEGL=1 -DEGL_MODULE=$(egl_target)))
+$(eval $(call if-component,glslcompiler,\
+ -DSUPPORT_SOURCE_SHADER=1))
+$(eval $(call if-component,opencl,\
+ -DSUPPORT_OPENCL=1))
+$(eval $(call if-component,liboclcompiler,\
+ -DSUPPORT_OCL_COMPILER=1))
+$(eval $(call if-component,openrl,\
+ -DSUPPORT_OPENRL=1))
+$(eval $(call if-component,renderscript,\
+ -DSUPPORT_RSC=1))
+$(eval $(call if-component,renderscript_sha1,\
+ -DSUPPORT_RSC_SHA1=1))
+$(eval $(call if-component,librscruntime,\
+ -DSUPPORT_RSC_RUNTIME=1))
+$(eval $(call if-component,librsccompiler,\
+ -DSUPPORT_RSC_COMPILER=1))
+$(eval $(call if-component,rscreplay,\
+ -DSUPPORT_RSC_REPLAY=1))
+$(eval $(call if-component,opengl opengl_mesa,\
+ -DSUPPORT_OPENGL=1))
+$(eval $(call if-component,null_ws,\
+ -DSUPPORT_NULL_WS=1))
+$(eval $(call if-component,null_drm_ws,\
+ -DSUPPORT_NULL_DRM_WS=1 \
+ -DSUPPORT_LWS=1 \
+ -DLWS_INSTALL_TREE=1))
+$(eval $(call if-component,null_remote,\
+ -DSUPPORT_NULL_REMOTE=1))
+$(eval $(call if-component,null_adf_ws,\
+ -DSUPPORT_NULL_ADF_WS=1))
+$(eval $(call if-component,ews_ws,\
+ -DSUPPORT_EWS=1))
+$(eval $(call if-component,ews_wm,\
+ -DSUPPORT_LUA=1))
+$(eval $(call if-component,graphicshal,\
+ -DSUPPORT_GRAPHICS_HAL=1))
+$(eval $(call if-component,xeglinfo,\
+ -DSUPPORT_XUNITTESTS=1))
+$(eval $(call if-component,pvrgdb,\
+ -DPVRGDB=1))
+
+ifeq ($(PVR_REMOTE),1)
+ M4DEFS += -DPVR_REMOTE=1
+endif
+
+# Build UM script using old scheme using M4
+define create-install-um-script-m4
+$(RELATIVE_OUT)/$(1)/install_um.sh: $(PVRVERSION_H) $(CONFIG_MK) \
+ $(MAKE_TOP)/scripts/common.m4 \
+ $(MAKE_TOP)/$(PVR_BUILD_DIR)/install_um.sh.m4 \
+ | $(RELATIVE_OUT)/$(1)
+       $$(if $(V),,@echo "  GEN     " $$(call relative-to-top,$$@))
+       $(M4) $(M4FLAGS) $(M4DEFS) $(M4DEFS_K) \
+         $(MAKE_TOP)/scripts/common.m4 \
+         $(MAKE_TOP)/$(PVR_BUILD_DIR)/install_um.sh.m4 > $$@
+install_script: $(RELATIVE_OUT)/$(1)/install_um.sh
+endef
+
+$(foreach _t,$(TARGET_ALL_ARCH),$(eval $(call create-install-um-script-m4,$(_t))))
+
+$(TARGET_PRIMARY_OUT)/rc.pvr: $(PVRVERSION_H) $(CONFIG_MK) $(CONFIG_KERNEL_MK) \
+ $(MAKE_TOP)/scripts/rc.pvr.m4 $(MAKE_TOP)/scripts/common.m4 \
+ $(MAKE_TOP)/$(PVR_BUILD_DIR)/rc.pvr.m4 \
+ | $(TARGET_PRIMARY_OUT)
+       $(if $(V),,@echo "  GEN     " $(call relative-to-top,$@))
+       $(M4) $(M4FLAGS) $(M4DEFS) $(M4DEFS_K) $(MAKE_TOP)/scripts/rc.pvr.m4 \
+               $(MAKE_TOP)/$(PVR_BUILD_DIR)/rc.pvr.m4 > $@
+       $(CHMOD) +x $@
+init_script: $(TARGET_PRIMARY_OUT)/rc.pvr
+
+$(TARGET_PRIMARY_OUT)/udev.pvr: $(CONFIG_KERNEL_MK) \
+ $(MAKE_TOP)/scripts/udev.pvr.m4 \
+ | $(TARGET_PRIMARY_OUT)
+       $(if $(V),,@echo "  GEN     " $(call relative-to-top,$@))
+       $(M4) $(M4FLAGS) $(M4DEFS_K) $(MAKE_TOP)/scripts/udev.pvr.m4 > $@
+udev_rules: $(TARGET_PRIMARY_OUT)/udev.pvr
+
+endif # ifeq ($(SUPPORT_ANDROID_PLATFORM),)
+
+# This code mimics the way Make processes our implicit/explicit goal list.
+# It tries to build up a list of components that were actually built, from
+# whence an install script is generated.
+#
+ifneq ($(MAKECMDGOALS),)
+BUILT_UM := $(MAKECMDGOALS)
+ifneq ($(filter build services_all components,$(MAKECMDGOALS)),)
+BUILT_UM += $(COMPONENTS)
+endif
+BUILT_UM := $(sort $(filter $(ALL_MODULES) xorg wl,$(BUILT_UM)))
+else
+BUILT_UM := $(sort $(COMPONENTS))
+endif
+
+ifneq ($(MAKECMDGOALS),)
+BUILT_KM := $(MAKECMDGOALS)
+ifneq ($(filter build services_all kbuild,$(MAKECMDGOALS)),)
+BUILT_KM += $(KERNEL_COMPONENTS)
+endif
+BUILT_KM := $(sort $(filter $(ALL_MODULES),$(BUILT_KM)))
+else
+BUILT_KM := $(sort $(KERNEL_COMPONENTS))
+endif
+
+INSTALL_UM_MODULES := \
+ $(strip $(foreach _m,$(BUILT_UM),\
+  $(if $(filter doc module_group,$($(_m)_type)),,\
+   $(if $(filter host_%,$($(_m)_arch)),,\
+    $(if $($(_m)_install_path),$(_m),\
+     $(warning WARNING: UM $(_m)_install_path not defined))))))
+
+# Build up a list of installable shared libraries. The shared_library module
+# type is specially guaranteed to define $(_m)_target, even if the Linux.mk
+# itself didn't. The list is formatted with <module>:<target> pairs e.g.
+# "moduleA:libmoduleA.so moduleB:libcustom.so" for later processing.
+ALL_SHARED_INSTALLABLE := \
+ $(sort $(foreach _a,$(ALL_MODULES),\
+  $(if $(filter shared_library,$($(_a)_type)),$(_a):$($(_a)_target),)))
+
+# Handle implicit install dependencies. Executables and shared libraries may
+# be linked against other shared libraries. Avoid requiring the user to
+# specify the program's binary dependencies explicitly with $(m)_install_extra
+INSTALL_UM_MODULES := \
+ $(sort $(INSTALL_UM_MODULES) \
+  $(foreach _a,$(ALL_SHARED_INSTALLABLE),\
+   $(foreach _m,$(INSTALL_UM_MODULES),\
+    $(foreach _l,$($(_m)_libs),\
+     $(if $(filter lib$(_l).so,$(word 2,$(subst :, ,$(_a)))),\
+                               $(word 1,$(subst :, ,$(_a))))))))
+
+# Add explicit dependencies that must be installed 
+INSTALL_UM_MODULES := \
+ $(sort $(INSTALL_UM_MODULES) \
+  $(foreach _m,$(INSTALL_UM_MODULES),\
+   $($(_m)_install_dependencies)))
+
+define calculate-um-fragments
+# Work out which modules are required for this arch.
+INSTALL_UM_MODULES_$(1) := \
+ $$(strip $$(foreach _m,$(INSTALL_UM_MODULES),\
+  $$(if $$(filter $(1),$$(INTERNAL_ARCH_LIST_FOR_$$(_m))),$$(_m))))
+
+INSTALL_UM_FRAGMENTS_$(1) := $$(foreach _m,$$(INSTALL_UM_MODULES_$(1)),$(RELATIVE_OUT)/$(1)/intermediates/$$(_m)/.install)
+
+.PHONY: install_um_$(1)_debug
+install_um_$(1)_debug: $$(INSTALL_UM_FRAGMENTS_$(1))
+       $(CAT) $$^
+endef
+
+$(foreach _t,$(TARGET_ALL_ARCH) target_neutral,$(eval $(call calculate-um-fragments,$(_t))))
+
+INSTALL_KM_FRAGMENTS := \
+ $(strip $(foreach _m,$(BUILT_KM),\
+  $(if $(filter-out kernel_module,$($(_m)_type)),,\
+   $(if $($(_m)_install_path),\
+    $(TARGET_PRIMARY_OUT)/intermediates/$(_m)/.install,\
+     $(warning WARNING: KM $(_m)_install_path not defined)))))
+
+.PHONY: install_km_debug
+install_km_debug: $(INSTALL_KM_FRAGMENTS)
+       $(CAT) $^
+
+ifneq ($(INSTALL_KM_FRAGMENTS),)
+$(TARGET_PRIMARY_OUT)/install_km.sh: $(INSTALL_KM_FRAGMENTS) $(CONFIG_KERNEL_MK) | $(TARGET_PRIMARY_OUT)
+       $(if $(V),,@echo "  GEN     " $(call relative-to-top,$@))
+       $(ECHO) KERNELVERSION=$(KERNEL_ID)                  >  $@
+ifeq ($(SUPPORT_ANDROID_PLATFORM),)
+       $(ECHO) MOD_DESTDIR=/lib/modules/$(KERNEL_ID)/extra >> $@
+endif
+       $(CAT) $(INSTALL_KM_FRAGMENTS)                      >> $@
+install_script_km: $(TARGET_PRIMARY_OUT)/install_km.sh
+endif
+
+# Build UM script using new scheme which does not use M4 for anything
+# (Only works for Android and target_neutral right now.)
+define create-install-um-script
+ifneq ($$(INSTALL_UM_FRAGMENTS_$(1)),)
+$(RELATIVE_OUT)/$(1)/install_um.sh: $$(INSTALL_UM_FRAGMENTS_$(1)) | $(RELATIVE_OUT)/$(1)
+       $(if $(V),,@echo "  GEN     " $$(call relative-to-top,$$@))
+       $(CAT) $$(INSTALL_UM_FRAGMENTS_$(1)) > $$@
+install_script: $(RELATIVE_OUT)/$(1)/install_um.sh
+endif
+endef
+$(eval $(call create-install-um-script,target_neutral))
+
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+$(foreach _t,$(TARGET_ALL_ARCH),$(eval $(call create-install-um-script,$(_t))))
+endif
+
+# Build the top-level install script that drives the install.
+ifneq ($(SUPPORT_ANDROID_PLATFORM),)
+install_sh_template := $(MAKE_TOP)/common/android/install.sh.tpl
+else
+install_sh_template := $(MAKE_TOP)/scripts/install.sh.tpl
+endif
+
+$(RELATIVE_OUT)/install.sh: $(PVRVERSION_H) | $(RELATIVE_OUT)
+# In customer packages only one of config.mk or config_kernel.mk will exist.
+# We can depend on either one, as long as we rebuild the install script when
+# the config options it uses change.
+$(RELATIVE_OUT)/install.sh: $(call if-exists,$(CONFIG_MK),$(CONFIG_KERNEL_MK))
+$(RELATIVE_OUT)/install.sh: $(install_sh_template)
+       $(if $(V),,@echo "  GEN     " $(call relative-to-top,$@))
+       $(ECHO) 's/\[PVRVERSION\]/$(subst /,\/,$(PVRVERSION))/g;'           > $(RELATIVE_OUT)/install.sh.sed
+       $(ECHO) 's/\[PVRBUILD\]/$(BUILD)/g;'                               >> $(RELATIVE_OUT)/install.sh.sed
+       $(ECHO) 's/\[PRIMARY_ARCH\]/$(TARGET_PRIMARY_ARCH)/g;'             >> $(RELATIVE_OUT)/install.sh.sed
+       $(ECHO) 's/\[ARCHITECTURES\]/$(TARGET_ALL_ARCH)/g;' >> $(RELATIVE_OUT)/install.sh.sed
+       $(ECHO) 's/\[LWS_PREFIX\]/$(subst /,\/,$(LWS_PREFIX))/g;'          >> $(RELATIVE_OUT)/install.sh.sed
+       $(ECHO) 's/\[SHLIB_DESTDIR\]/$(subst /,\/,$(SHLIB_DESTDIR))/g;'    >> $(RELATIVE_OUT)/install.sh.sed
+       @sed -f $(RELATIVE_OUT)/install.sh.sed $< > $@
+       $(CHMOD) +x $@
+       $(RM) $(RELATIVE_OUT)/install.sh.sed
+install_script: $(RELATIVE_OUT)/install.sh
+install_script_km: $(RELATIVE_OUT)/install.sh
diff --git a/drivers/gpu/rogue_m/build/linux/sunxi_android/Makefile b/drivers/gpu/rogue_m/build/linux/sunxi_android/Makefile
new file mode 100644 (file)
index 0000000..5f22a0e
--- /dev/null
@@ -0,0 +1,89 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+include ../config/preconfig.mk
+
+# If a TARGET_PRODUCT is specified but not a TARGET_DEVICE, try to
+# derive the TARGET_DEVICE from TARGET_PRODUCT.
+#
+
+ifeq ($(TARGET_DEVICE),)
+override TARGET_DEVICE := \
+ $(patsubst mini_%,%,$(patsubst full_%,%,$(TARGET_PRODUCT)))
+ifneq ($(filter kylin_perf kylin_p1,$(TARGET_DEVICE)),)
+override TARGET_DEVICE := sun9i
+endif
+endif
+
+ifeq ($(TARGET_DEVICE),)
+override TARGET_DEVICE := sun9i
+endif
+
+HAL_VARIANT := sun9i
+PVR_SYSTEM := rgx_sunxi
+LDM_PLATFORM := 1
+SUPPORT_ADF := 1
+
+RGX_BVNC = 1.75.2.30
+
+KERNEL_CROSS_COMPILE ?= arm-eabi-
+
+include ../common/android/paths.mk
+include ../common/android/arch.mk
+include ../common/android/features.mk
+
+ION_DEFAULT_HEAP_ID_MASK := (1 << ION_HEAP_TYPE_DMA)
+ION_FALLBACK_HEAP_ID_MASK := (1 << ION_HEAP_TYPE_CARVEOUT)
+ifneq ($(is_at_least_lollipop),1)
+SYS_INCLUDES += \
+ -isystem $(ANDROID_ROOT)/device/img/sun9i/adf/libadf/include \
+ -isystem $(ANDROID_ROOT)/device/img/sun9i/adf/libadfhwc/include
+endif
+
+DISPLAY_CONTROLLER ?= adf_sunxi
+
+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER)
+
+CACHEFLUSH_TYPE ?= CACHEFLUSH_GENERIC
+
+PDUMP_STREAMBUF_SIZE_MB := 10
+
+include ../config/core.mk
+include ../common/android/extra_config.mk
diff --git a/drivers/gpu/rogue_m/build/linux/this_makefile.mk b/drivers/gpu/rogue_m/build/linux/this_makefile.mk
new file mode 100644 (file)
index 0000000..c312001
--- /dev/null
@@ -0,0 +1,68 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Find out the path of the Linux.mk makefile currently being processed, and
+# set paths used by the build rules
+
+# This magic is used so we can use this_makefile.mk twice: first when reading
+# in each Linux.mk, and then again when generating rules. There we set
+# $(THIS_MAKEFILE), and $(REMAINING_MAKEFILES) should be empty
+ifneq ($(strip $(REMAINING_MAKEFILES)),)
+
+# Absolute path to the Linux.mk being processed
+THIS_MAKEFILE := $(firstword $(REMAINING_MAKEFILES))
+
+# The list of makefiles left to process
+REMAINING_MAKEFILES := $(wordlist 2,$(words $(REMAINING_MAKEFILES)),$(REMAINING_MAKEFILES))
+
+else
+
+# When generating rules, we should have read in every Linux.mk
+$(if $(INTERNAL_INCLUDED_ALL_MAKEFILES),,$(error No makefiles left in $$(REMAINING_MAKEFILES), but $$(INTERNAL_INCLUDED_ALL_MAKEFILES) is not set))
+
+endif
+
+# Path to the directory containing Linux.mk
+THIS_DIR := $(patsubst %/,%,$(dir $(THIS_MAKEFILE)))
+ifeq ($(strip $(THIS_DIR)),)
+$(error Empty $$(THIS_DIR) for makefile "$(THIS_MAKEFILE)")
+endif
+
+modules :=
diff --git a/drivers/gpu/rogue_m/build/linux/tools/cc-check.sh b/drivers/gpu/rogue_m/build/linux/tools/cc-check.sh
new file mode 100644 (file)
index 0000000..773a88f
--- /dev/null
@@ -0,0 +1,120 @@
+#!/bin/sh
+########################################################################### ###
+#@File
+#@Title         Test the nature of the C compiler.
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+LANG=C
+export LANG
+
+usage() {
+       echo "usage: $0 [--64] [--clang] --cc CC [--out OUT] [cflag]"
+       exit 1
+}
+
+check_clang() {
+       $CC -Wp,-dM -E - </dev/null | grep __clang__ >/dev/null 2>&1
+       if [ "$?" = "0" ]; then
+               # Clang must be passed a program with a main() that returns 0.
+               # It will produce an error if main() is improperly specified.
+               IS_CLANG=1
+               TEST_PROGRAM="int main(void){return 0;}"
+       else
+               # If we're not clang, assume we're GCC. GCC needs to be passed
+               # a program with a faulty return in main() so that another
+               # warning (unrelated to the flag being tested) is emitted.
+               # This will cause GCC to warn about the unsupported warning flag.
+               IS_CLANG=0
+               TEST_PROGRAM="int main(void){return;}"
+       fi
+}
+
+do_cc() {
+       echo "$TEST_PROGRAM" 2> /dev/null | $CC -W -Wall $3 -xc -c - -o $1 >$2 2>&1
+}
+
+while [ 1 ]; do
+       if [ "$1" = "--64" ]; then
+               [ -z $CLANG ] && BIT_CHECK=1
+       elif [ "$1" = "--clang" ]; then
+               [ -z $BIT_CHECK ] && CLANG=1
+       elif [ "$1" = "--cc" ]; then
+               [ "x$2" = "x" ] && usage
+               CC="$2" && shift
+       elif [ "$1" = "--out" ]; then
+               [ "x$2" = "x" ] && usage
+               OUT="$2" && shift
+       elif [ "${1#--}" != "$1" ]; then
+               usage
+       else
+               break
+       fi
+       shift
+done
+
+[ "x$CC" = "x" ] && usage
+[ "x$CLANG" = "x" -a "x$OUT" = "x" ] && usage
+ccof=$OUT/cc-sanity-check
+log=${ccof}.log
+
+check_clang
+
+if [ "x$BIT_CHECK" = "x1" ]; then
+       do_cc $ccof $log ""
+       file $ccof | grep 64-bit >/dev/null 2>&1
+       [ "$?" = "0" ] && echo true || echo false
+elif [ "x$CLANG" = "x1" ]; then
+       [ "x$IS_CLANG" = "x1" ] && echo true || echo false
+else
+       [ "x$1" = "x" ] && usage
+       do_cc $ccof $log $1
+       if [ "$?" = "0" ]; then
+               # compile passed, but was the warning unrecognized?
+               if [ "x$IS_CLANG" = "x1" ]; then
+                       grep "^warning: unknown warning option '$1'" $log >/dev/null 2>&1
+               else
+                       grep -E "(^cc1: warning: unrecognized command line option \"$1\"|^cc1: warning: command line option \"$1\" is valid for C\+\+/ObjC\+\+ but not for C|gcc: unrecognized option '$1')" $log >/dev/null 2>&1
+               fi
+               [ "$?" = "1" ] && echo $1
+       fi
+fi
+
+rm -f $ccof $log
+exit 0
diff --git a/drivers/gpu/rogue_m/build/linux/toplevel.mk b/drivers/gpu/rogue_m/build/linux/toplevel.mk
new file mode 100644 (file)
index 0000000..fba84a1
--- /dev/null
@@ -0,0 +1,303 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Define the default goal. This masks a previous definition of the default
+# goal in config/core.mk, which must match this one
+.PHONY: build
+build: components
+
+MAKE_TOP      := build/linux
+THIS_MAKEFILE := (top-level makefiles)
+
+include $(MAKE_TOP)/defs.mk
+
+ifeq ($(OUT),)
+$(error Must specify output directory with OUT=)
+endif
+
+ifeq ($(TOP),)
+$(error Must specify root of source tree with TOP=)
+endif
+$(call directory-must-exist,$(TOP))
+
+# RELATIVE_OUT is relative only if it's under $(TOP)
+RELATIVE_OUT       := $(patsubst $(TOP)/%,%,$(OUT))
+CONFIG_MK          := $(RELATIVE_OUT)/config.mk
+CONFIG_H           := $(RELATIVE_OUT)/config.h
+CONFIG_KERNEL_MK   := $(RELATIVE_OUT)/config_kernel.mk
+CONFIG_KERNEL_H           := $(RELATIVE_OUT)/config_kernel.h
+
+# Convert commas to spaces in $(D). This is so you can say "make
+# D=config-changes,freeze-config" and have $(filter config-changes,$(D))
+# still work.
+comma := ,
+empty :=
+space := $(empty) $(empty)
+override D := $(subst $(comma),$(space),$(D))
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+# Create the out directory
+#
+$(shell mkdir -p $(OUT))
+
+# If these generated files differ from any pre-existing ones,
+# replace them, causing affected parts of the driver to rebuild.
+#
+_want_config_diff := $(filter config-changes,$(D))
+_freeze_config := $(strip $(filter freeze-config,$(D)))
+_updated_config_files := $(shell \
+    $(if $(_want_config_diff),rm -f $(OUT)/config.diff;,) \
+       for file in $(CONFIG_MK) $(CONFIG_H) \
+                               $(CONFIG_KERNEL_MK) $(CONFIG_KERNEL_H); do \
+               diff -U 0 $$file $$file.new \
+                       >>$(if $(_want_config_diff),$(OUT)/config.diff,/dev/null) 2>/dev/null \
+               && rm -f $$file.new \
+               || echo $$file; \
+       done)
+
+ifneq ($(_want_config_diff),)
+# We send the diff to stderr so it isn't captured by $(shell)
+$(shell [ -s $(OUT)/config.diff ] && echo >&2 "Configuration changed in $(RELATIVE_OUT):" && cat >&2 $(OUT)/config.diff)
+endif
+
+ifneq ($(_freeze_config),)
+$(if $(_updated_config_files),$(error Configuration change in $(RELATIVE_OUT) prevented by D=freeze-config),)
+endif
+
+# Update the config, if changed
+$(foreach _f,$(_updated_config_files), \
+       $(shell mv -f $(_f).new $(_f) >/dev/null 2>/dev/null))
+
+endif # INTERNAL_CLOBBER_ONLY
+
+MAKEFLAGS := -Rr --no-print-directory
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+
+# This is so you can say "find $(TOP) -name Linux.mk > /tmp/something; export
+# ALL_MAKEFILES=/tmp/something; make" and avoid having to run find. This is
+# handy if your source tree is mounted over NFS or something
+override ALL_MAKEFILES := $(call relative-to-top,$(if $(strip $(ALL_MAKEFILES)),$(shell cat $(ALL_MAKEFILES)),$(shell find $(TOP) -type f -name Linux.mk -print -o -type d -name '.*' -prune)))
+ifeq ($(strip $(ALL_MAKEFILES)),)
+$(info ** Unable to find any Linux.mk files under $$(TOP). This could mean that)
+$(info ** there are no makefiles, or that ALL_MAKEFILES is set in the environment)
+$(info ** and points to a nonexistent or empty file.)
+$(error No makefiles)
+endif
+
+else # clobber-only
+ALL_MAKEFILES :=
+endif
+
+unexport ALL_MAKEFILES
+
+REMAINING_MAKEFILES := $(ALL_MAKEFILES)
+ALL_MODULES :=
+INTERNAL_INCLUDED_ALL_MAKEFILES :=
+
+ALL_LDFLAGS :=
+
+# Please do not change the format of the following lines
+-include $(CONFIG_MK)
+-include $(CONFIG_KERNEL_MK)
+# OK to change now
+
+# If we haven't set host/target archs, set some sensible defaults now.
+# This allows things like prune.sh to work
+ifeq ($(HOST_PRIMARY_ARCH),)
+ifneq ($(FORCE_ARCH),)
+HOST_PRIMARY_ARCH := host_x86_64
+HOST_32BIT_ARCH := host_i386
+
+_ALL_ARCHS := \
+ $(filter-out %target_neutral.mk,$(wildcard $(MAKE_TOP)/moduledefs/target_*.mk))
+TARGET_PRIMARY_ARCH := \
+ $(patsubst $(MAKE_TOP)/moduledefs/%.mk,%,$(word 1, $(_ALL_ARCHS)))
+
+TARGET_ALL_ARCH := $(TARGET_PRIMARY_ARCH)
+endif
+endif
+
+# Output directory for configuration, object code,
+# final programs/libraries, and install/rc scripts.
+HOST_OUT             := $(RELATIVE_OUT)/$(HOST_PRIMARY_ARCH)
+HOST_32BIT_OUT       := $(RELATIVE_OUT)/$(HOST_32BIT_ARCH)
+TARGET_OUT           := $(RELATIVE_OUT)/$(TARGET_PRIMARY_ARCH)
+TARGET_PRIMARY_OUT   := $(RELATIVE_OUT)/$(TARGET_PRIMARY_ARCH)
+TARGET_NEUTRAL_OUT   := $(RELATIVE_OUT)/target_neutral
+BRIDGE_SOURCE_ROOT   := $(call if-exists,$(TOP)/generated,$(TARGET_NEUTRAL_OUT)/intermediates)
+GENERATED_CODE_OUT   := $(TARGET_NEUTRAL_OUT)/intermediates
+DOCS_OUT             := $(RELATIVE_OUT)/doc
+
+#
+# neutrino/subst_makefiles.mk must be included after Output directories have been defined,
+# because it overrides BRIDGE_SOURCE_ROOT of bridges to be built. If we include this makefile
+# earlier, the value of BRIDGE_SOURCE_ROOT set in neutrino/subst_makefiles.mk will be overwritten.
+ifeq ($(SUPPORT_NEUTRINO_PLATFORM),1)
+include $(MAKE_TOP)/common/neutrino/subst_makefiles.mk
+# neutrino/subst_makefiles.mk overrides ALL_MAKEFILES.
+# Set REMAINING_MAKEFILES to the new value of ALL_MAKEFILES
+REMAINING_MAKEFILES := $(ALL_MAKEFILES)
+endif
+
+# Mark subdirectories of $(OUT) as secondary, and provide rules to create
+# them.
+OUT_SUBDIRS := $(addprefix $(RELATIVE_OUT)/,$(TARGET_ALL_ARCH)) \
+ $(TARGET_NEUTRAL_OUT) $(DOCS_OUT) $(if $(HOST_PRIMARY_ARCH),$(sort $(HOST_OUT) $(HOST_32BIT_OUT)))
+.SECONDARY: $(OUT_SUBDIRS)
+$(OUT_SUBDIRS):
+       $(make-directory)
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+-include $(MAKE_TOP)/pvrversion.mk
+ifeq ($(SUPPORT_BUILD_LWS),1)
+-include $(MAKE_TOP)/lwsconf.mk
+endif
+-include $(MAKE_TOP)/llvm.mk
+-include $(MAKE_TOP)/common/bridges.mk
+endif
+
+include $(MAKE_TOP)/commands.mk
+include $(MAKE_TOP)/buildvars.mk
+
+HOST_INTERMEDIATES := $(HOST_OUT)/intermediates
+TARGET_INTERMEDIATES := $(TARGET_OUT)/intermediates
+
+ifneq ($(KERNEL_COMPONENTS),)
+build: kbuild
+endif
+
+# "make bridges" makes all the modules which are bridges. This is used by
+# builds which ship pregenerated bridge headers.
+.PHONY: bridges
+bridges: $(BRIDGES) $(DIRECT_BRIDGES)
+
+# Include each Linux.mk, then include modules.mk to save some information
+# about each module
+include $(foreach _Linux.mk,$(ALL_MAKEFILES),$(MAKE_TOP)/this_makefile.mk $(_Linux.mk) $(MAKE_TOP)/modules.mk)
+
+ifeq ($(strip $(REMAINING_MAKEFILES)),)
+INTERNAL_INCLUDED_ALL_MAKEFILES := true
+else
+$(error Impossible: $(words $(REMAINING_MAKEFILES)) makefiles were mysteriously ignored when reading $$(ALL_MAKEFILES))
+endif
+
+# At this point, all Linux.mks have been included. Now generate rules to build
+# each module: for each module in $(ALL_MODULES), set per-makefile variables
+$(foreach _m,$(ALL_MODULES),$(eval $(call process-module,$(_m))))
+
+.PHONY: kbuild install
+kbuild install:
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+-include $(MAKE_TOP)/scripts.mk
+-include $(MAKE_TOP)/kbuild/kbuild.mk
+endif
+# We won't depend on 'build' here so that people can build subsets of
+# components and still have the install script attempt to install the
+# subset.
+install:
+       @if [ ! -d "$(DISCIMAGE)" ]; then \
+               echo; \
+               echo "** DISCIMAGE was not set or does not point to a valid directory."; \
+               echo "** Cannot continue with install."; \
+               echo; \
+               exit 1; \
+       fi
+       @if [ ! -f $(RELATIVE_OUT)/install.sh ]; then \
+               echo; \
+               echo "** install.sh not found in $(RELATIVE_OUT)."; \
+               echo "** Cannot continue with install."; \
+               echo; \
+               exit 1; \
+       fi
+       @cd $(RELATIVE_OUT) && ./install.sh
+
+.PHONY: uninstall
+uninstall: install_script
+uninstall:
+       @if [ ! -d "$(DISCIMAGE)" ]; then \
+               echo; \
+               echo "** DISCIMAGE was not set or does not point to a valid directory."; \
+               echo "** Cannot continue with uninstall."; \
+               echo; \
+               exit 1; \
+       fi
+       @if [ ! -f $(RELATIVE_OUT)/install.sh ]; then \
+               echo; \
+               echo "** install.sh not found in $(RELATIVE_OUT)."; \
+               echo "** Cannot continue with uninstall."; \
+               echo; \
+               exit 1; \
+       fi
+       @cd $(RELATIVE_OUT) && ./install.sh -u
+
+# You can say 'make all_modules' to attempt to make everything, or 'make
+# components' to only make the things which are listed (in the per-build
+# makefiles) as components of the build.
+.PHONY: all_modules all_docs components
+all_modules: $(ALL_MODULES)
+all_docs: ;
+components: $(COMPONENTS)
+
+# Cleaning
+.PHONY: clean clobber
+clean: MODULE_DIRS_TO_REMOVE := $(OUT_SUBDIRS)
+clean:
+       $(clean-dirs)
+clobber: MODULE_DIRS_TO_REMOVE := $(OUT)
+clobber:
+       $(clean-dirs)
+
+# Saying 'make clean-MODULE' removes the intermediates for MODULE.
+# clobber-MODULE deletes the output files as well
+clean-%:
+       $(if $(V),,@echo "  RM      " $(call relative-to-top,$(INTERNAL_CLEAN_TARGETS_FOR_$*)))
+       $(RM) -rf $(INTERNAL_CLEAN_TARGETS_FOR_$*)
+clobber-%:
+       $(if $(V),,@echo "  RM      " $(call relative-to-top,$(INTERNAL_CLOBBER_TARGETS_FOR_$*)))
+       $(RM) -rf $(INTERNAL_CLOBBER_TARGETS_FOR_$*)
+
+include $(MAKE_TOP)/bits.mk
+
+# D=nobuild stops the build before any recipes are run. This line should
+# come at the end of this makefile.
+$(if $(filter nobuild,$(D)),$(error D=nobuild given),)
diff --git a/drivers/gpu/rogue_m/config_kernel.h b/drivers/gpu/rogue_m/config_kernel.h
new file mode 100644 (file)
index 0000000..6303347
--- /dev/null
@@ -0,0 +1,38 @@
+#define SUPPORT_ION 
+#define PVR_ANDROID_ION_HEADER "../drivers/staging/android/ion/ion.h"
+#define PVR_ANDROID_ION_PRIV_HEADER "../drivers/staging/android/ion/ion_priv.h"
+#define PVR_ANDROID_ION_USE_SG_LENGTH 
+#define PVR_ANDROID_SYNC_HEADER "../drivers/staging/android/sync.h"
+#define LINUX 
+#define PVR_BUILD_DIR "generic_arm_android"
+#define PVR_BUILD_TYPE "release"
+#define PVRSRV_MODNAME "pvrsrvkm"
+#define SUPPORT_RGX 1
+#define RELEASE 
+#define RGX_BVNC_CORE_KM_HEADER "cores/rgxcore_km_5.9.1.46.h" 
+#define RGX_BNC_CONFIG_KM_HEADER "configs/rgxconfig_km_5.V.1.46.h" 
+#define SUPPORT_DBGDRV_EVENT_OBJECTS 
+#define PDUMP_STREAMBUF_MAX_SIZE_MB 16
+#define SYS_USING_INTERRUPTS 
+#define CACHEFLUSH_TYPE CACHEFLUSH_GENERIC
+#define SUPPORT_SECURE_EXPORT 
+#define SUPPORT_GPUTRACE_EVENTS 
+#define GPUVIRT_VALIDATION_NUM_OS 8
+#define SUPPORT_LINUX_X86_WRITECOMBINE 
+#define SUPPORT_LINUX_X86_PAT 
+#define PVR_LINUX_USING_WORKQUEUES 
+#define PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE 
+#define PVR_LINUX_TIMERS_USING_WORKQUEUES 
+#define PVR_LDM_PLATFORM_PRE_REGISTERED 
+#define PVR_LDM_DRIVER_REGISTRATION_NAME "pvrsrvkm"
+#define LDM_PLATFORM 
+#define PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN 256
+#define SUPPORT_PERCONTEXT_FREELIST 
+#define PVRSRV_ENABLE_PROCESS_STATS 
+#define PVR_LINUX_PHYSMEM_MAX_POOL_PAGES 10240
+#define PVR_LINUX_ARM_PAGEALLOC_FLUSH_THRESHOLD  256
+#define PVR_LINUX_PHYSMEM_MIN_NUM_PAGES  256 
+#define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER  2 
+#define PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD  16384 
+#define ANDROID 
+#define SUPPORT_NATIVE_FENCE_SYNC 
diff --git a/drivers/gpu/rogue_m/config_kernel.mk b/drivers/gpu/rogue_m/config_kernel.mk
new file mode 100644 (file)
index 0000000..482440c
--- /dev/null
@@ -0,0 +1,26 @@
+override HOST_PRIMARY_ARCH := host_x86_64
+override HOST_32BIT_ARCH := host_i386
+override HOST_FORCE_32BIT := -m32
+override TARGET_PRIMARY_ARCH := target_aarch64
+override TARGET_SECONDARY_ARCH := target_armv7-a
+override TARGET_ALL_ARCH :=  target_aarch64 target_armv7-a
+override TARGET_FORCE_32BIT := 
+override KERNELDIR := /work/zxl/project/rk3368_6.0/kernel
+override KERNEL_ID := 3.10.0
+override KERNEL_COMPONENTS := srvkm
+override KERNEL_CROSS_COMPILE := aarch64-linux-android-
+override SUPPORT_ION := 1
+override PVRSRV_MODNAME := pvrsrvkm
+override PVR_BUILD_DIR := generic_arm_android
+override PVR_BUILD_TYPE := release
+override PVR_SYSTEM := rk3368
+override PVR_LOADER := 
+override BUILD := release
+override DEBUGLINK := 1
+override CACHEFLUSH_TYPE := CACHEFLUSH_GENERIC
+override SUPPORT_SECURE_EXPORT := 1
+override SUPPORT_GPUTRACE_EVENTS := 1
+override OPTIM := -O2
+override PVR_HANDLE_BACKEND := idr
+override SUPPORT_ANDROID_PLATFORM := 1
+override SUPPORT_NATIVE_FENCE_SYNC := 1
diff --git a/drivers/gpu/rogue_m/generated/breakpoint_bridge/common_breakpoint_bridge.h b/drivers/gpu/rogue_m/generated/breakpoint_bridge/common_breakpoint_bridge.h
new file mode 100644 (file)
index 0000000..835666d
--- /dev/null
@@ -0,0 +1,158 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for breakpoint
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for breakpoint
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_BREAKPOINT_BRIDGE_H
+#define COMMON_BREAKPOINT_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+
+#define PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST                     0
+#define PVRSRV_BRIDGE_BREAKPOINT_RGXSETBREAKPOINT                      PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+0
+#define PVRSRV_BRIDGE_BREAKPOINT_RGXCLEARBREAKPOINT                    PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+1
+#define PVRSRV_BRIDGE_BREAKPOINT_RGXENABLEBREAKPOINT                   PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+2
+#define PVRSRV_BRIDGE_BREAKPOINT_RGXDISABLEBREAKPOINT                  PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+3
+#define PVRSRV_BRIDGE_BREAKPOINT_RGXOVERALLOCATEBPREGISTERS                    PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+4
+#define PVRSRV_BRIDGE_BREAKPOINT_CMD_LAST                      (PVRSRV_BRIDGE_BREAKPOINT_CMD_FIRST+4)
+
+
+/*******************************************
+            RGXSetBreakpoint          
+ *******************************************/
+
+/* Bridge in structure for RGXSetBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_HANDLE hPrivData;
+       IMG_UINT32 eFWDataMaster;
+       IMG_UINT32 ui32BreakpointAddr;
+       IMG_UINT32 ui32HandlerAddr;
+       IMG_UINT32 ui32DM;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT;
+
+
+/* Bridge out structure for RGXSetBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT;
+
+/*******************************************
+            RGXClearBreakpoint          
+ *******************************************/
+
+/* Bridge in structure for RGXClearBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT;
+
+
+/* Bridge out structure for RGXClearBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT;
+
+/*******************************************
+            RGXEnableBreakpoint          
+ *******************************************/
+
+/* Bridge in structure for RGXEnableBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT;
+
+
+/* Bridge out structure for RGXEnableBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT;
+
+/*******************************************
+            RGXDisableBreakpoint          
+ *******************************************/
+
+/* Bridge in structure for RGXDisableBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT;
+
+
+/* Bridge out structure for RGXDisableBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT;
+
+/*******************************************
+            RGXOverallocateBPRegisters          
+ *******************************************/
+
+/* Bridge in structure for RGXOverallocateBPRegisters */
+typedef struct PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32TempRegs;
+       IMG_UINT32 ui32SharedRegs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS;
+
+
+/* Bridge out structure for RGXOverallocateBPRegisters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS;
+
+#endif /* COMMON_BREAKPOINT_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/breakpoint_bridge/server_breakpoint_bridge.c b/drivers/gpu/rogue_m/generated/breakpoint_bridge/server_breakpoint_bridge.c
new file mode 100644 (file)
index 0000000..e376604
--- /dev/null
@@ -0,0 +1,392 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for breakpoint
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for breakpoint
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxbreakpoint.h"
+
+
+#include "common_breakpoint_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXSetBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT *psRGXSetBreakpointIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT *psRGXSetBreakpointOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXSetBreakpointIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXSetBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetBreakpoint_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXSetBreakpointIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXSetBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetBreakpoint_exit;
+                                       }
+                               }
+
+
+       psRGXSetBreakpointOUT->eError =
+               PVRSRVRGXSetBreakpointKM(
+                                       hDevNodeInt,
+                                       hPrivDataInt,
+                                       psRGXSetBreakpointIN->eFWDataMaster,
+                                       psRGXSetBreakpointIN->ui32BreakpointAddr,
+                                       psRGXSetBreakpointIN->ui32HandlerAddr,
+                                       psRGXSetBreakpointIN->ui32DM);
+
+
+
+
+RGXSetBreakpoint_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXClearBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT *psRGXClearBreakpointIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT *psRGXClearBreakpointOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXClearBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXClearBreakpointIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXClearBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXClearBreakpoint_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXClearBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXClearBreakpointIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXClearBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXClearBreakpoint_exit;
+                                       }
+                               }
+
+
+       psRGXClearBreakpointOUT->eError =
+               PVRSRVRGXClearBreakpointKM(
+                                       hDevNodeInt,
+                                       hPrivDataInt);
+
+
+
+
+RGXClearBreakpoint_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXEnableBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT *psRGXEnableBreakpointIN,
+                                         PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT *psRGXEnableBreakpointOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXEnableBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXEnableBreakpointIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXEnableBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXEnableBreakpoint_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXEnableBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXEnableBreakpointIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXEnableBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXEnableBreakpoint_exit;
+                                       }
+                               }
+
+
+       psRGXEnableBreakpointOUT->eError =
+               PVRSRVRGXEnableBreakpointKM(
+                                       hDevNodeInt,
+                                       hPrivDataInt);
+
+
+
+
+RGXEnableBreakpoint_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDisableBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXDisableBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXDisableBreakpointIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXDisableBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXDisableBreakpoint_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXDisableBreakpointOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXDisableBreakpointIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXDisableBreakpointOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXDisableBreakpoint_exit;
+                                       }
+                               }
+
+
+       psRGXDisableBreakpointOUT->eError =
+               PVRSRVRGXDisableBreakpointKM(
+                                       hDevNodeInt,
+                                       hPrivDataInt);
+
+
+
+
+RGXDisableBreakpoint_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXOverallocateBPRegisters(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS *psRGXOverallocateBPRegistersIN,
+                                         PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS *psRGXOverallocateBPRegistersOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXOverallocateBPRegistersOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXOverallocateBPRegistersIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXOverallocateBPRegistersOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXOverallocateBPRegisters_exit;
+                                       }
+                               }
+
+
+       psRGXOverallocateBPRegistersOUT->eError =
+               PVRSRVRGXOverallocateBPRegistersKM(
+                                       hDevNodeInt,
+                                       psRGXOverallocateBPRegistersIN->ui32TempRegs,
+                                       psRGXOverallocateBPRegistersIN->ui32SharedRegs);
+
+
+
+
+RGXOverallocateBPRegisters_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitBREAKPOINTBridge(IMG_VOID);
+PVRSRV_ERROR DeinitBREAKPOINTBridge(IMG_VOID);
+
+/*
+ * Register all BREAKPOINT functions with services
+ */
+PVRSRV_ERROR InitBREAKPOINTBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_BREAKPOINT, PVRSRV_BRIDGE_BREAKPOINT_RGXSETBREAKPOINT, PVRSRVBridgeRGXSetBreakpoint,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_BREAKPOINT, PVRSRV_BRIDGE_BREAKPOINT_RGXCLEARBREAKPOINT, PVRSRVBridgeRGXClearBreakpoint,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_BREAKPOINT, PVRSRV_BRIDGE_BREAKPOINT_RGXENABLEBREAKPOINT, PVRSRVBridgeRGXEnableBreakpoint,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_BREAKPOINT, PVRSRV_BRIDGE_BREAKPOINT_RGXDISABLEBREAKPOINT, PVRSRVBridgeRGXDisableBreakpoint,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_BREAKPOINT, PVRSRV_BRIDGE_BREAKPOINT_RGXOVERALLOCATEBPREGISTERS, PVRSRVBridgeRGXOverallocateBPRegisters,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all breakpoint functions with services
+ */
+PVRSRV_ERROR DeinitBREAKPOINTBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/cachegeneric_bridge/common_cachegeneric_bridge.h b/drivers/gpu/rogue_m/generated/cachegeneric_bridge/common_cachegeneric_bridge.h
new file mode 100644 (file)
index 0000000..8d3fd02
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for cachegeneric
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for cachegeneric
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_CACHEGENERIC_BRIDGE_H
+#define COMMON_CACHEGENERIC_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "cache_external.h"
+
+
+#define PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST                   0
+#define PVRSRV_BRIDGE_CACHEGENERIC_CACHEOPQUEUE                        PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST+0
+#define PVRSRV_BRIDGE_CACHEGENERIC_CMD_LAST                    (PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST+0)
+
+
+/*******************************************
+            CacheOpQueue          
+ *******************************************/
+
+/* Bridge in structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPQUEUE_TAG
+{
+       PVRSRV_CACHE_OP iuCacheOp;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPQUEUE;
+
+
+/* Bridge out structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPQUEUE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPQUEUE;
+
+#endif /* COMMON_CACHEGENERIC_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/cachegeneric_bridge/server_cachegeneric_bridge.c b/drivers/gpu/rogue_m/generated/cachegeneric_bridge/server_cachegeneric_bridge.c
new file mode 100644 (file)
index 0000000..359074a
--- /dev/null
@@ -0,0 +1,131 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for cachegeneric
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for cachegeneric
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "cache_generic.h"
+
+
+#include "common_cachegeneric_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeCacheOpQueue(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_CACHEOPQUEUE *psCacheOpQueueIN,
+                                         PVRSRV_BRIDGE_OUT_CACHEOPQUEUE *psCacheOpQueueOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+       psCacheOpQueueOUT->eError =
+               CacheOpQueue(
+                                       psCacheOpQueueIN->iuCacheOp);
+
+
+
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitCACHEGENERICBridge(IMG_VOID);
+PVRSRV_ERROR DeinitCACHEGENERICBridge(IMG_VOID);
+
+/*
+ * Register all CACHEGENERIC functions with services
+ */
+PVRSRV_ERROR InitCACHEGENERICBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_CACHEGENERIC, PVRSRV_BRIDGE_CACHEGENERIC_CACHEOPQUEUE, PVRSRVBridgeCacheOpQueue,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all cachegeneric functions with services
+ */
+PVRSRV_ERROR DeinitCACHEGENERICBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/cmm_bridge/common_cmm_bridge.h b/drivers/gpu/rogue_m/generated/cmm_bridge/common_cmm_bridge.h
new file mode 100644 (file)
index 0000000..c0ec88d
--- /dev/null
@@ -0,0 +1,115 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for cmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for cmm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_CMM_BRIDGE_H
+#define COMMON_CMM_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_CMM_CMD_FIRST                    0
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTCTXEXPORT                   PVRSRV_BRIDGE_CMM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTCTXUNEXPORT                 PVRSRV_BRIDGE_CMM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTCTXIMPORT                   PVRSRV_BRIDGE_CMM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_CMM_CMD_LAST                     (PVRSRV_BRIDGE_CMM_CMD_FIRST+2)
+
+
+/*******************************************
+            DevmemIntCtxExport          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxExport */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXEXPORT_TAG
+{
+       IMG_HANDLE hDevMemServerContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXEXPORT;
+
+
+/* Bridge out structure for DevmemIntCtxExport */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXEXPORT_TAG
+{
+       IMG_HANDLE hDevMemIntCtxExport;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXEXPORT;
+
+/*******************************************
+            DevmemIntCtxUnexport          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxUnexport */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXUNEXPORT_TAG
+{
+       IMG_HANDLE hDevMemIntCtxExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXUNEXPORT;
+
+
+/* Bridge out structure for DevmemIntCtxUnexport */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXUNEXPORT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXUNEXPORT;
+
+/*******************************************
+            DevmemIntCtxImport          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxImport */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXIMPORT_TAG
+{
+       IMG_HANDLE hDevMemIntCtxExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXIMPORT;
+
+
+/* Bridge out structure for DevmemIntCtxImport */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXIMPORT_TAG
+{
+       IMG_HANDLE hDevMemServerContext;
+       IMG_HANDLE hPrivData;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXIMPORT;
+
+#endif /* COMMON_CMM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/cmm_bridge/server_cmm_bridge.c b/drivers/gpu/rogue_m/generated/cmm_bridge/server_cmm_bridge.c
new file mode 100644 (file)
index 0000000..5c3fe15
--- /dev/null
@@ -0,0 +1,393 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for cmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for cmm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "pmr.h"
+#include "devicemem_server.h"
+
+
+#include "common_cmm_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+static PVRSRV_ERROR ReleaseDevMemIntCtxExport(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeDevmemIntCtxExport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTCTXEXPORT *psDevmemIntCtxExportIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTCTXEXPORT *psDevmemIntCtxExportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX * psDevMemServerContextInt = IMG_NULL;
+       DEVMEMINT_CTX_EXPORT * psDevMemIntCtxExportInt = IMG_NULL;
+       IMG_HANDLE hDevMemIntCtxExportInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntCtxExportOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevMemServerContextInt,
+                                                                                       psDevmemIntCtxExportIN->hDevMemServerContext,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+                                       if(psDevmemIntCtxExportOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntCtxExport_exit;
+                                       }
+                               }
+
+
+       psDevmemIntCtxExportOUT->eError =
+               DevmemIntCtxExport(
+                                       psDevMemServerContextInt,
+                                       &psDevMemIntCtxExportInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntCtxExportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxExport_exit;
+       }
+
+
+       /*
+        * For cases where we need a cross process handle we actually allocate two.
+        * 
+        * The first one is a connection specific handle and it gets given the real
+        * release function. This handle does *NOT* get returned to the caller. It's
+        * purpose is to release any leaked resources when we either have a bad or
+        * abnormally terminated client. If we didn't do this then the resource
+        * wouldn't be freed until driver unload. If the resource is freed normally,
+        * this handle can be looked up via the cross process handle and then
+        * released accordingly.
+        * 
+        * The second one is a cross process handle and it gets given a noop release
+        * function. This handle does get returned to the caller.
+        */
+       psDevmemIntCtxExportOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &hDevMemIntCtxExportInt,
+                                                       (IMG_VOID *) psDevMemIntCtxExportInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntCtxUnexport);
+       if (psDevmemIntCtxExportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxExport_exit;
+       }
+
+       psDevmemIntCtxExportOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+                                                       &psDevmemIntCtxExportOUT->hDevMemIntCtxExport,
+                                                       (IMG_VOID *) psDevMemIntCtxExportInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+                                                       (PFN_HANDLE_RELEASE)&ReleaseDevMemIntCtxExport);
+       if (psDevmemIntCtxExportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxExport_exit;
+       }
+
+
+
+DevmemIntCtxExport_exit:
+       if (psDevmemIntCtxExportOUT->eError != PVRSRV_OK)
+       {
+               if (psDevmemIntCtxExportOUT->hDevMemIntCtxExport)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                               (IMG_HANDLE) psDevmemIntCtxExportOUT->hDevMemIntCtxExport,
+                                               PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+               }
+
+               if (hDevMemIntCtxExportInt)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               hDevMemIntCtxExportInt,
+                                               PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psDevMemIntCtxExportInt = IMG_NULL;
+               }
+
+               if (psDevMemIntCtxExportInt)
+               {
+                       DevmemIntCtxUnexport(psDevMemIntCtxExportInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntCtxUnexport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTCTXUNEXPORT *psDevmemIntCtxUnexportIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTCTXUNEXPORT *psDevmemIntCtxUnexportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX_EXPORT * psDevMemIntCtxExportInt = IMG_NULL;
+       IMG_HANDLE hDevMemIntCtxExportInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+
+       psDevmemIntCtxUnexportOUT->eError =
+               PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_VOID **) &psDevMemIntCtxExportInt,
+                                       (IMG_HANDLE) psDevmemIntCtxUnexportIN->hDevMemIntCtxExport,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+       PVR_ASSERT(psDevmemIntCtxUnexportOUT->eError == PVRSRV_OK);
+
+       /*
+        * Find the connection specific handle that represents the same data
+        * as the cross process handle as releasing it will actually call the
+        * data's real release function (see the function where the cross
+        * process handle is allocated for more details).
+        */
+       psDevmemIntCtxUnexportOUT->eError =
+               PVRSRVFindHandle(psConnection->psHandleBase,
+                                       &hDevMemIntCtxExportInt,
+                                       psDevMemIntCtxExportInt,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+       PVR_ASSERT(psDevmemIntCtxUnexportOUT->eError == PVRSRV_OK);
+
+       psDevmemIntCtxUnexportOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       hDevMemIntCtxExportInt,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+       PVR_ASSERT((psDevmemIntCtxUnexportOUT->eError == PVRSRV_OK) || (psDevmemIntCtxUnexportOUT->eError == PVRSRV_ERROR_RETRY));
+
+       psDevmemIntCtxUnexportOUT->eError =
+               PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_HANDLE) psDevmemIntCtxUnexportIN->hDevMemIntCtxExport,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+       if ((psDevmemIntCtxUnexportOUT->eError != PVRSRV_OK) && (psDevmemIntCtxUnexportOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto DevmemIntCtxUnexport_exit;
+       }
+
+
+
+DevmemIntCtxUnexport_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntCtxImport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTCTXIMPORT *psDevmemIntCtxImportIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTCTXIMPORT *psDevmemIntCtxImportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX_EXPORT * psDevMemIntCtxExportInt = IMG_NULL;
+       DEVMEMINT_CTX * psDevMemServerContextInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+       psDevmemIntCtxImportOUT->hDevMemServerContext = IMG_NULL;
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntCtxImportOUT->eError =
+                                               PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+                                                                                       (IMG_VOID **) &psDevMemIntCtxExportInt,
+                                                                                       psDevmemIntCtxImportIN->hDevMemIntCtxExport,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
+                                       if(psDevmemIntCtxImportOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntCtxImport_exit;
+                                       }
+                               }
+
+
+       psDevmemIntCtxImportOUT->eError =
+               DevmemIntCtxImport(
+                                       psDevMemIntCtxExportInt,
+                                       &psDevMemServerContextInt,
+                                       &hPrivDataInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntCtxImportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxImport_exit;
+       }
+
+
+       psDevmemIntCtxImportOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntCtxImportOUT->hDevMemServerContext,
+                                                       (IMG_VOID *) psDevMemServerContextInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntCtxDestroy);
+       if (psDevmemIntCtxImportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxImport_exit;
+       }
+
+
+       psDevmemIntCtxImportOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntCtxImportOUT->hPrivData,
+                                                       (IMG_VOID *) hPrivDataInt,
+                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,psDevmemIntCtxImportOUT->hDevMemServerContext);
+       if (psDevmemIntCtxImportOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxImport_exit;
+       }
+
+
+
+
+DevmemIntCtxImport_exit:
+       if (psDevmemIntCtxImportOUT->eError != PVRSRV_OK)
+       {
+               if (psDevmemIntCtxImportOUT->hDevMemServerContext)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               (IMG_HANDLE) psDevmemIntCtxImportOUT->hDevMemServerContext,
+                                               PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psDevMemServerContextInt = IMG_NULL;
+               }
+
+
+               if (psDevMemServerContextInt)
+               {
+                       DevmemIntCtxDestroy(psDevMemServerContextInt);
+               }
+       }
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitCMMBridge(IMG_VOID);
+PVRSRV_ERROR DeinitCMMBridge(IMG_VOID);
+
+/*
+ * Register all CMM functions with services
+ */
+PVRSRV_ERROR InitCMMBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTCTXEXPORT, PVRSRVBridgeDevmemIntCtxExport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTCTXUNEXPORT, PVRSRVBridgeDevmemIntCtxUnexport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_CMM, PVRSRV_BRIDGE_CMM_DEVMEMINTCTXIMPORT, PVRSRVBridgeDevmemIntCtxImport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all cmm functions with services
+ */
+PVRSRV_ERROR DeinitCMMBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c b/drivers/gpu/rogue_m/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c
new file mode 100644 (file)
index 0000000..21225f7
--- /dev/null
@@ -0,0 +1,88 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for devicememhistory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_devicememhistory_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "img_types.h"
+#include "mm_common.h"
+
+#include "devicemem_history_server.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMap(IMG_HANDLE hBridge,
+                                                                IMG_DEV_VIRTADDR sDevVAddr,
+                                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                                const IMG_CHAR *puiText)
+{
+       PVRSRV_ERROR eError;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+       eError =
+               DevicememHistoryMapKM(
+                                       sDevVAddr,
+                                       uiSize,
+                                       puiText);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge,
+                                                                  IMG_DEV_VIRTADDR sDevVAddr,
+                                                                  IMG_DEVMEM_SIZE_T uiSize,
+                                                                  const IMG_CHAR *puiText)
+{
+       PVRSRV_ERROR eError;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+       eError =
+               DevicememHistoryUnmapKM(
+                                       sDevVAddr,
+                                       uiSize,
+                                       puiText);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/debugmisc_bridge/common_debugmisc_bridge.h b/drivers/gpu/rogue_m/generated/debugmisc_bridge/common_debugmisc_bridge.h
new file mode 100644 (file)
index 0000000..ef103fb
--- /dev/null
@@ -0,0 +1,139 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for debugmisc
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for debugmisc
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_DEBUGMISC_BRIDGE_H
+#define COMMON_DEBUGMISC_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "rgx_bridge.h"
+#include "pvrsrv_memallocflags.h"
+
+
+#define PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST                      0
+#define PVRSRV_BRIDGE_DEBUGMISC_DEBUGMISCSLCSETBYPASSSTATE                     PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETFWLOG                   PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+1
+#define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCDUMPFREELISTPAGELIST                       PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DEBUGMISC_PHYSMEMIMPORTSECBUF                    PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+3
+#define PVRSRV_BRIDGE_DEBUGMISC_CMD_LAST                       (PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+3)
+
+
+/*******************************************
+            DebugMiscSLCSetBypassState          
+ *******************************************/
+
+/* Bridge in structure for DebugMiscSLCSetBypassState */
+typedef struct PVRSRV_BRIDGE_IN_DEBUGMISCSLCSETBYPASSSTATE_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32Flags;
+       IMG_BOOL bIsBypassed;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEBUGMISCSLCSETBYPASSSTATE;
+
+
+/* Bridge out structure for DebugMiscSLCSetBypassState */
+typedef struct PVRSRV_BRIDGE_OUT_DEBUGMISCSLCSETBYPASSSTATE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEBUGMISCSLCSETBYPASSSTATE;
+
+/*******************************************
+            RGXDebugMiscSetFWLog          
+ *******************************************/
+
+/* Bridge in structure for RGXDebugMiscSetFWLog */
+typedef struct PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETFWLOG_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32RGXFWLogType;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETFWLOG;
+
+
+/* Bridge out structure for RGXDebugMiscSetFWLog */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETFWLOG_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETFWLOG;
+
+/*******************************************
+            RGXDebugMiscDumpFreelistPageList          
+ *******************************************/
+
+/* Bridge in structure for RGXDebugMiscDumpFreelistPageList */
+typedef struct PVRSRV_BRIDGE_IN_RGXDEBUGMISCDUMPFREELISTPAGELIST_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDEBUGMISCDUMPFREELISTPAGELIST;
+
+
+/* Bridge out structure for RGXDebugMiscDumpFreelistPageList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDEBUGMISCDUMPFREELISTPAGELIST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDEBUGMISCDUMPFREELISTPAGELIST;
+
+/*******************************************
+            PhysmemImportSecBuf          
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportSecBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_UINT32 ui32Log2PageSize;
+       PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF;
+
+
+/* Bridge out structure for PhysmemImportSecBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSECBUF_TAG
+{
+       IMG_HANDLE hPMRPtr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSECBUF;
+
+#endif /* COMMON_DEBUGMISC_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/debugmisc_bridge/server_debugmisc_bridge.c b/drivers/gpu/rogue_m/generated/debugmisc_bridge/server_debugmisc_bridge.c
new file mode 100644 (file)
index 0000000..09dbc01
--- /dev/null
@@ -0,0 +1,314 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for debugmisc
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for debugmisc
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "devicemem_server.h"
+#include "debugmisc_server.h"
+#include "pmr.h"
+#include "physmem_osmem.h"
+
+
+#include "common_debugmisc_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeDebugMiscSLCSetBypassState(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEBUGMISCSLCSETBYPASSSTATE *psDebugMiscSLCSetBypassStateIN,
+                                         PVRSRV_BRIDGE_OUT_DEBUGMISCSLCSETBYPASSSTATE *psDebugMiscSLCSetBypassStateOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDebugMiscSLCSetBypassStateOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psDebugMiscSLCSetBypassStateIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psDebugMiscSLCSetBypassStateOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DebugMiscSLCSetBypassState_exit;
+                                       }
+                               }
+
+
+       psDebugMiscSLCSetBypassStateOUT->eError =
+               PVRSRVDebugMiscSLCSetBypassStateKM(
+                                       hDevNodeInt,
+                                       psDebugMiscSLCSetBypassStateIN->ui32Flags,
+                                       psDebugMiscSLCSetBypassStateIN->bIsBypassed);
+
+
+
+
+DebugMiscSLCSetBypassState_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDebugMiscSetFWLog(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETFWLOG *psRGXDebugMiscSetFWLogIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETFWLOG *psRGXDebugMiscSetFWLogOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXDebugMiscSetFWLogOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXDebugMiscSetFWLogIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXDebugMiscSetFWLogOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXDebugMiscSetFWLog_exit;
+                                       }
+                               }
+
+
+       psRGXDebugMiscSetFWLogOUT->eError =
+               PVRSRVRGXDebugMiscSetFWLogKM(
+                                       hDevNodeInt,
+                                       psRGXDebugMiscSetFWLogIN->ui32RGXFWLogType);
+
+
+
+
+RGXDebugMiscSetFWLog_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDebugMiscDumpFreelistPageList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDEBUGMISCDUMPFREELISTPAGELIST *psRGXDebugMiscDumpFreelistPageListIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDEBUGMISCDUMPFREELISTPAGELIST *psRGXDebugMiscDumpFreelistPageListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXDebugMiscDumpFreelistPageListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXDebugMiscDumpFreelistPageListIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXDebugMiscDumpFreelistPageListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXDebugMiscDumpFreelistPageList_exit;
+                                       }
+                               }
+
+
+       psRGXDebugMiscDumpFreelistPageListOUT->eError =
+               PVRSRVRGXDebugMiscDumpFreelistPageListKM(
+                                       hDevNodeInt);
+
+
+
+
+RGXDebugMiscDumpFreelistPageList_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePhysmemImportSecBuf(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF *psPhysmemImportSecBufIN,
+                                         PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSECBUF *psPhysmemImportSecBufOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       PMR * psPMRPtrInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPhysmemImportSecBufOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psPhysmemImportSecBufIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PhysmemImportSecBuf_exit;
+                                       }
+                               }
+
+
+       psPhysmemImportSecBufOUT->eError =
+               PhysmemNewTDSecureBufPMR(
+                                       hDevNodeInt,
+                                       psPhysmemImportSecBufIN->uiSize,
+                                       psPhysmemImportSecBufIN->ui32Log2PageSize,
+                                       psPhysmemImportSecBufIN->uiFlags,
+                                       &psPMRPtrInt);
+       /* Exit early if bridged call fails */
+       if(psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
+       {
+               goto PhysmemImportSecBuf_exit;
+       }
+
+
+       psPhysmemImportSecBufOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPhysmemImportSecBufOUT->hPMRPtr,
+                                                       (IMG_VOID *) psPMRPtrInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
+       {
+               goto PhysmemImportSecBuf_exit;
+       }
+
+
+
+
+PhysmemImportSecBuf_exit:
+       if (psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
+       {
+               if (psPMRPtrInt)
+               {
+                       PMRUnrefPMR(psPMRPtrInt);
+               }
+       }
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitDEBUGMISCBridge(IMG_VOID);
+PVRSRV_ERROR DeinitDEBUGMISCBridge(IMG_VOID);
+
+/*
+ * Register all DEBUGMISC functions with services
+ */
+PVRSRV_ERROR InitDEBUGMISCBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_DEBUGMISCSLCSETBYPASSSTATE, PVRSRVBridgeDebugMiscSLCSetBypassState,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETFWLOG, PVRSRVBridgeRGXDebugMiscSetFWLog,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCDUMPFREELISTPAGELIST, PVRSRVBridgeRGXDebugMiscDumpFreelistPageList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_PHYSMEMIMPORTSECBUF, PVRSRVBridgePhysmemImportSecBuf,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all debugmisc functions with services
+ */
+PVRSRV_ERROR DeinitDEBUGMISCBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/devicememhistory_bridge/client_devicememhistory_bridge.h b/drivers/gpu/rogue_m/generated/devicememhistory_bridge/client_devicememhistory_bridge.h
new file mode 100644 (file)
index 0000000..c5ae4f7
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************/ /*!
+@File
+@Title          Client bridge header for devicememhistory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exports the client bridge functions for devicememhistory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_DEVICEMEMHISTORY_BRIDGE_H
+#define CLIENT_DEVICEMEMHISTORY_BRIDGE_H
+
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+
+#include "common_devicememhistory_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMap(IMG_HANDLE hBridge,
+                                                                IMG_DEV_VIRTADDR sDevVAddr,
+                                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                                const IMG_CHAR *puiText);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge,
+                                                                  IMG_DEV_VIRTADDR sDevVAddr,
+                                                                  IMG_DEVMEM_SIZE_T uiSize,
+                                                                  const IMG_CHAR *puiText);
+
+
+#endif /* CLIENT_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/devicememhistory_bridge/common_devicememhistory_bridge.h b/drivers/gpu/rogue_m/generated/devicememhistory_bridge/common_devicememhistory_bridge.h
new file mode 100644 (file)
index 0000000..62ee411
--- /dev/null
@@ -0,0 +1,99 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for devicememhistory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for devicememhistory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_DEVICEMEMHISTORY_BRIDGE_H
+#define COMMON_DEVICEMEMHISTORY_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "img_types.h"
+#include "mm_common.h"
+
+
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST                       0
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP                     PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP                   PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST                        (PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1)
+
+
+/*******************************************
+            DevicememHistoryMap          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryMap */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP_TAG
+{
+       IMG_DEV_VIRTADDR sDevVAddr;
+       IMG_DEVMEM_SIZE_T uiSize;
+       const IMG_CHAR * puiText;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP;
+
+
+/* Bridge out structure for DevicememHistoryMap */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP;
+
+/*******************************************
+            DevicememHistoryUnmap          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryUnmap */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP_TAG
+{
+       IMG_DEV_VIRTADDR sDevVAddr;
+       IMG_DEVMEM_SIZE_T uiSize;
+       const IMG_CHAR * puiText;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP;
+
+
+/* Bridge out structure for DevicememHistoryUnmap */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP;
+
+#endif /* COMMON_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/devicememhistory_bridge/server_devicememhistory_bridge.c b/drivers/gpu/rogue_m/generated/devicememhistory_bridge/server_devicememhistory_bridge.c
new file mode 100644 (file)
index 0000000..95a19e7
--- /dev/null
@@ -0,0 +1,217 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for devicememhistory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for devicememhistory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "devicemem_history_server.h"
+
+
+#include "common_devicememhistory_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+#include "lock.h"
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeDevicememHistoryMap(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *psDevicememHistoryMapIN,
+                                         PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *psDevicememHistoryMapOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_CHAR *uiTextInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+       
+       {
+               uiTextInt = OSAllocMem(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR));
+               if (!uiTextInt)
+               {
+                       psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto DevicememHistoryMap_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevicememHistoryMapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapIN->puiText,
+                               DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto DevicememHistoryMap_exit;
+                       }
+
+
+
+       psDevicememHistoryMapOUT->eError =
+               DevicememHistoryMapKM(
+                                       psDevicememHistoryMapIN->sDevVAddr,
+                                       psDevicememHistoryMapIN->uiSize,
+                                       uiTextInt);
+
+
+
+
+DevicememHistoryMap_exit:
+       if (uiTextInt)
+               OSFreeMem(uiTextInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevicememHistoryUnmap(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapIN,
+                                         PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_CHAR *uiTextInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+       
+       {
+               uiTextInt = OSAllocMem(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR));
+               if (!uiTextInt)
+               {
+                       psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto DevicememHistoryUnmap_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevicememHistoryUnmapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapIN->puiText,
+                               DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto DevicememHistoryUnmap_exit;
+                       }
+
+
+
+       psDevicememHistoryUnmapOUT->eError =
+               DevicememHistoryUnmapKM(
+                                       psDevicememHistoryUnmapIN->sDevVAddr,
+                                       psDevicememHistoryUnmapIN->uiSize,
+                                       uiTextInt);
+
+
+
+
+DevicememHistoryUnmap_exit:
+       if (uiTextInt)
+               OSFreeMem(uiTextInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static POS_LOCK pDEVICEMEMHISTORYBridgeLock;
+static IMG_BYTE pbyDEVICEMEMHISTORYBridgeBuffer[56 +  4];
+
+PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(IMG_VOID);
+PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(IMG_VOID);
+
+/*
+ * Register all DEVICEMEMHISTORY functions with services
+ */
+PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(IMG_VOID)
+{
+       PVR_LOGR_IF_ERROR(OSLockCreate(&pDEVICEMEMHISTORYBridgeLock, LOCK_TYPE_PASSIVE), "OSLockCreate");
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP, PVRSRVBridgeDevicememHistoryMap,
+                                       pDEVICEMEMHISTORYBridgeLock, pbyDEVICEMEMHISTORYBridgeBuffer,
+                                       56,  4);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP, PVRSRVBridgeDevicememHistoryUnmap,
+                                       pDEVICEMEMHISTORYBridgeLock, pbyDEVICEMEMHISTORYBridgeBuffer,
+                                       56,  4);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all devicememhistory functions with services
+ */
+PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(IMG_VOID)
+{
+       PVR_LOGR_IF_ERROR(OSLockDestroy(pDEVICEMEMHISTORYBridgeLock), "OSLockDestroy");
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dmabuf_bridge/common_dmabuf_bridge.h b/drivers/gpu/rogue_m/generated/dmabuf_bridge/common_dmabuf_bridge.h
new file mode 100644 (file)
index 0000000..a2fa1d1
--- /dev/null
@@ -0,0 +1,80 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for dmabuf
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for dmabuf
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_DMABUF_BRIDGE_H
+#define COMMON_DMABUF_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_memallocflags.h"
+
+
+#define PVRSRV_BRIDGE_DMABUF_CMD_FIRST                 0
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF                       PVRSRV_BRIDGE_DMABUF_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DMABUF_CMD_LAST                  (PVRSRV_BRIDGE_DMABUF_CMD_FIRST+0)
+
+
+/*******************************************
+            PhysmemImportDmaBuf          
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportDmaBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF_TAG
+{
+       IMG_INT ifd;
+       PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF;
+
+
+/* Bridge out structure for PhysmemImportDmaBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF_TAG
+{
+       IMG_HANDLE hPMRPtr;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_DEVMEM_ALIGN_T sAlign;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF;
+
+#endif /* COMMON_DMABUF_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/dmabuf_bridge/server_dmabuf_bridge.c b/drivers/gpu/rogue_m/generated/dmabuf_bridge/server_dmabuf_bridge.c
new file mode 100644 (file)
index 0000000..f8d8100
--- /dev/null
@@ -0,0 +1,162 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for dmabuf
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for dmabuf
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "physmem_dmabuf.h"
+#include "pmr.h"
+
+
+#include "common_dmabuf_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePhysmemImportDmaBuf(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF *psPhysmemImportDmaBufIN,
+                                         PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF *psPhysmemImportDmaBufOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRPtrInt = IMG_NULL;
+
+
+
+
+
+
+
+       psPhysmemImportDmaBufOUT->eError =
+               PhysmemImportDmaBuf(psConnection,
+                                       psPhysmemImportDmaBufIN->ifd,
+                                       psPhysmemImportDmaBufIN->uiFlags,
+                                       &psPMRPtrInt,
+                                       &psPhysmemImportDmaBufOUT->uiSize,
+                                       &psPhysmemImportDmaBufOUT->sAlign);
+       /* Exit early if bridged call fails */
+       if(psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
+       {
+               goto PhysmemImportDmaBuf_exit;
+       }
+
+
+       psPhysmemImportDmaBufOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPhysmemImportDmaBufOUT->hPMRPtr,
+                                                       (IMG_VOID *) psPMRPtrInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
+       {
+               goto PhysmemImportDmaBuf_exit;
+       }
+
+
+
+
+PhysmemImportDmaBuf_exit:
+       if (psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
+       {
+               if (psPMRPtrInt)
+               {
+                       PMRUnrefPMR(psPMRPtrInt);
+               }
+       }
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitDMABUFBridge(IMG_VOID);
+PVRSRV_ERROR DeinitDMABUFBridge(IMG_VOID);
+
+/*
+ * Register all DMABUF functions with services
+ */
+PVRSRV_ERROR InitDMABUFBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF, PVRSRVBridgePhysmemImportDmaBuf,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all dmabuf functions with services
+ */
+PVRSRV_ERROR DeinitDMABUFBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.c b/drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.c
new file mode 100644 (file)
index 0000000..47ab7c1
--- /dev/null
@@ -0,0 +1,555 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for mm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_mm_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_typedefs.h"
+
+#include "devicemem_server.h"
+#include "pmr.h"
+#include "devicemem_heapcfg.h"
+#include "physmem.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRExportPMR(IMG_HANDLE hBridge,
+                                                         IMG_HANDLE hPMR,
+                                                         IMG_HANDLE *phPMRExport,
+                                                         IMG_UINT64 *pui64Size,
+                                                         IMG_UINT32 *pui32Log2Contig,
+                                                         IMG_UINT64 *pui64Password)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PMR_EXPORT * psPMRExportInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRExportPMR(
+                                       psPMRInt,
+                                       &psPMRExportInt,
+                                       pui64Size,
+                                       pui32Log2Contig,
+                                       pui64Password);
+
+       *phPMRExport = psPMRExportInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnexportPMR(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hPMRExport)
+{
+       PVRSRV_ERROR eError;
+       PMR_EXPORT * psPMRExportInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRExportInt = (PMR_EXPORT *) hPMRExport;
+
+       eError =
+               PMRUnexportPMR(
+                                       psPMRExportInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRGetUID(IMG_HANDLE hBridge,
+                                                      IMG_HANDLE hPMR,
+                                                      IMG_UINT64 *pui64UID)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRGetUID(
+                                       psPMRInt,
+                                       pui64UID);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRMakeServerExportClientExport(IMG_HANDLE hBridge,
+                                                                            DEVMEM_SERVER_EXPORTCOOKIE hPMRServerExport,
+                                                                            IMG_HANDLE *phPMRExportOut,
+                                                                            IMG_UINT64 *pui64Size,
+                                                                            IMG_UINT32 *pui32Log2Contig,
+                                                                            IMG_UINT64 *pui64Password)
+{
+       PVRSRV_ERROR eError;
+       DEVMEM_EXPORTCOOKIE * psPMRServerExportInt;
+       PMR_EXPORT * psPMRExportOutInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRServerExportInt = (DEVMEM_EXPORTCOOKIE *) hPMRServerExport;
+
+       eError =
+               PMRMakeServerExportClientExport(
+                                       psPMRServerExportInt,
+                                       &psPMRExportOutInt,
+                                       pui64Size,
+                                       pui32Log2Contig,
+                                       pui64Password);
+
+       *phPMRExportOut = psPMRExportOutInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnmakeServerExportClientExport(IMG_HANDLE hBridge,
+                                                                              IMG_HANDLE hPMRExport)
+{
+       PVRSRV_ERROR eError;
+       PMR_EXPORT * psPMRExportInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRExportInt = (PMR_EXPORT *) hPMRExport;
+
+       eError =
+               PMRUnmakeServerExportClientExport(
+                                       psPMRExportInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRImportPMR(IMG_HANDLE hBridge,
+                                                         IMG_HANDLE hPMRExport,
+                                                         IMG_UINT64 ui64uiPassword,
+                                                         IMG_UINT64 ui64uiSize,
+                                                         IMG_UINT32 ui32uiLog2Contig,
+                                                         IMG_HANDLE *phPMR)
+{
+       PVRSRV_ERROR eError;
+       PMR_EXPORT * psPMRExportInt;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRExportInt = (PMR_EXPORT *) hPMRExport;
+
+       eError =
+               PMRImportPMR(
+                                       psPMRExportInt,
+                                       ui64uiPassword,
+                                       ui64uiSize,
+                                       ui32uiLog2Contig,
+                                       &psPMRInt);
+
+       *phPMR = psPMRInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hDeviceNode,
+                                                               IMG_HANDLE *phDevMemServerContext,
+                                                               IMG_HANDLE *phPrivData)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       DEVMEMINT_CTX * psDevMemServerContextInt;
+       IMG_HANDLE hPrivDataInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               DevmemIntCtxCreate(
+                                       hDeviceNodeInt,
+                                       &psDevMemServerContextInt,
+                                       &hPrivDataInt);
+
+       *phDevMemServerContext = psDevMemServerContextInt;
+       *phPrivData = hPrivDataInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hDevmemServerContext)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_CTX * psDevmemServerContextInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemServerContextInt = (DEVMEMINT_CTX *) hDevmemServerContext;
+
+       eError =
+               DevmemIntCtxDestroy(
+                                       psDevmemServerContextInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hDevmemCtx,
+                                                                IMG_DEV_VIRTADDR sHeapBaseAddr,
+                                                                IMG_DEVMEM_SIZE_T uiHeapLength,
+                                                                IMG_UINT32 ui32Log2DataPageSize,
+                                                                IMG_HANDLE *phDevmemHeapPtr)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_CTX * psDevmemCtxInt;
+       DEVMEMINT_HEAP * psDevmemHeapPtrInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+       eError =
+               DevmemIntHeapCreate(
+                                       psDevmemCtxInt,
+                                       sHeapBaseAddr,
+                                       uiHeapLength,
+                                       ui32Log2DataPageSize,
+                                       &psDevmemHeapPtrInt);
+
+       *phDevmemHeapPtr = psDevmemHeapPtrInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hDevmemHeap)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_HEAP * psDevmemHeapInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemHeapInt = (DEVMEMINT_HEAP *) hDevmemHeap;
+
+       eError =
+               DevmemIntHeapDestroy(
+                                       psDevmemHeapInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntMapPMR(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hDevmemServerHeap,
+                                                            IMG_HANDLE hReservation,
+                                                            IMG_HANDLE hPMR,
+                                                            PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+                                                            IMG_HANDLE *phMapping)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_HEAP * psDevmemServerHeapInt;
+       DEVMEMINT_RESERVATION * psReservationInt;
+       PMR * psPMRInt;
+       DEVMEMINT_MAPPING * psMappingInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap;
+       psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               DevmemIntMapPMR(
+                                       psDevmemServerHeapInt,
+                                       psReservationInt,
+                                       psPMRInt,
+                                       uiMapFlags,
+                                       &psMappingInt);
+
+       *phMapping = psMappingInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hMapping)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_MAPPING * psMappingInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psMappingInt = (DEVMEMINT_MAPPING *) hMapping;
+
+       eError =
+               DevmemIntUnmapPMR(
+                                       psMappingInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntReserveRange(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDevmemServerHeap,
+                                                                  IMG_DEV_VIRTADDR sAddress,
+                                                                  IMG_DEVMEM_SIZE_T uiLength,
+                                                                  IMG_HANDLE *phReservation)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_HEAP * psDevmemServerHeapInt;
+       DEVMEMINT_RESERVATION * psReservationInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap;
+
+       eError =
+               DevmemIntReserveRange(
+                                       psDevmemServerHeapInt,
+                                       sAddress,
+                                       uiLength,
+                                       &psReservationInt);
+
+       *phReservation = psReservationInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge,
+                                                                    IMG_HANDLE hReservation)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_RESERVATION * psReservationInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+
+       eError =
+               DevmemIntUnreserveRange(
+                                       psReservationInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hDeviceNode,
+                                                                   IMG_DEVMEM_SIZE_T uiSize,
+                                                                   IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                                   IMG_UINT32 ui32NumPhysChunks,
+                                                                   IMG_UINT32 ui32NumVirtChunks,
+                                                                   IMG_BOOL *pbMappingTable,
+                                                                   IMG_UINT32 ui32Log2PageSize,
+                                                                   PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                                   IMG_HANDLE *phPMRPtr)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PMR * psPMRPtrInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               PhysmemNewRamBackedPMR(
+                                       hDeviceNodeInt,
+                                       uiSize,
+                                       uiChunkSize,
+                                       ui32NumPhysChunks,
+                                       ui32NumVirtChunks,
+                                       pbMappingTable,
+                                       ui32Log2PageSize,
+                                       uiFlags,
+                                       &psPMRPtrInt);
+
+       *phPMRPtr = psPMRPtrInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRLocalImportPMR(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hExtHandle,
+                                                              IMG_HANDLE *phPMR,
+                                                              IMG_DEVMEM_SIZE_T *puiSize,
+                                                              IMG_DEVMEM_ALIGN_T *psAlign)
+{
+       PVRSRV_ERROR eError;
+       PMR * psExtHandleInt;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psExtHandleInt = (PMR *) hExtHandle;
+
+       eError =
+               PMRLocalImportPMR(
+                                       psExtHandleInt,
+                                       &psPMRInt,
+                                       puiSize,
+                                       psAlign);
+
+       *phPMR = psPMRInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnrefPMR(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hPMR)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRUnrefPMR(
+                                       psPMRInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemSLCFlushInvalRequest(IMG_HANDLE hBridge,
+                                                                       IMG_HANDLE hDeviceNode,
+                                                                       IMG_HANDLE hPmr)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PMR * psPmrInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+       psPmrInt = (PMR *) hPmr;
+
+       eError =
+               DevmemSLCFlushInvalRequest(
+                                       hDeviceNodeInt,
+                                       psPmrInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDevmemCtx,
+                                                                  IMG_DEV_VIRTADDR sAddress)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_CTX * psDevmemCtxInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+       eError =
+               DevmemIntIsVDevAddrValid(
+                                       psDevmemCtxInt,
+                                       sAddress);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hDeviceNode,
+                                                                   IMG_UINT32 *pui32NumHeapConfigs)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               HeapCfgHeapConfigCount(
+                                       hDeviceNodeInt,
+                                       pui32NumHeapConfigs);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapCount(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hDeviceNode,
+                                                             IMG_UINT32 ui32HeapConfigIndex,
+                                                             IMG_UINT32 *pui32NumHeaps)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               HeapCfgHeapCount(
+                                       hDeviceNodeInt,
+                                       ui32HeapConfigIndex,
+                                       pui32NumHeaps);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDeviceNode,
+                                                                  IMG_UINT32 ui32HeapConfigIndex,
+                                                                  IMG_UINT32 ui32HeapConfigNameBufSz,
+                                                                  IMG_CHAR *puiHeapConfigName)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               HeapCfgHeapConfigName(
+                                       hDeviceNodeInt,
+                                       ui32HeapConfigIndex,
+                                       ui32HeapConfigNameBufSz,
+                                       puiHeapConfigName);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hDeviceNode,
+                                                               IMG_UINT32 ui32HeapConfigIndex,
+                                                               IMG_UINT32 ui32HeapIndex,
+                                                               IMG_UINT32 ui32HeapNameBufSz,
+                                                               IMG_CHAR *puiHeapNameOut,
+                                                               IMG_DEV_VIRTADDR *psDevVAddrBase,
+                                                               IMG_DEVMEM_SIZE_T *puiHeapLength,
+                                                               IMG_UINT32 *pui32Log2DataPageSizeOut,
+                                                               IMG_UINT32 *pui32Log2ImportAlignmentOut)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDeviceNodeInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
+
+       eError =
+               HeapCfgHeapDetails(
+                                       hDeviceNodeInt,
+                                       ui32HeapConfigIndex,
+                                       ui32HeapIndex,
+                                       ui32HeapNameBufSz,
+                                       puiHeapNameOut,
+                                       psDevVAddrBase,
+                                       puiHeapLength,
+                                       pui32Log2DataPageSizeOut,
+                                       pui32Log2ImportAlignmentOut);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.h b/drivers/gpu/rogue_m/generated/dmm_bridge/client_mm_bridge.h
new file mode 100644 (file)
index 0000000..f9d847b
--- /dev/null
@@ -0,0 +1,170 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge header for mm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_MM_BRIDGE_H
+#define CLIENT_MM_BRIDGE_H
+
+#include "common_mm_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRExportPMR(IMG_HANDLE hBridge,
+                                                         IMG_HANDLE hPMR,
+                                                         IMG_HANDLE *phPMRExport,
+                                                         IMG_UINT64 *pui64Size,
+                                                         IMG_UINT32 *pui32Log2Contig,
+                                                         IMG_UINT64 *pui64Password);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnexportPMR(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hPMRExport);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRGetUID(IMG_HANDLE hBridge,
+                                                      IMG_HANDLE hPMR,
+                                                      IMG_UINT64 *pui64UID);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRMakeServerExportClientExport(IMG_HANDLE hBridge,
+                                                                            DEVMEM_SERVER_EXPORTCOOKIE hPMRServerExport,
+                                                                            IMG_HANDLE *phPMRExportOut,
+                                                                            IMG_UINT64 *pui64Size,
+                                                                            IMG_UINT32 *pui32Log2Contig,
+                                                                            IMG_UINT64 *pui64Password);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnmakeServerExportClientExport(IMG_HANDLE hBridge,
+                                                                              IMG_HANDLE hPMRExport);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRImportPMR(IMG_HANDLE hBridge,
+                                                         IMG_HANDLE hPMRExport,
+                                                         IMG_UINT64 ui64uiPassword,
+                                                         IMG_UINT64 ui64uiSize,
+                                                         IMG_UINT32 ui32uiLog2Contig,
+                                                         IMG_HANDLE *phPMR);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hDeviceNode,
+                                                               IMG_HANDLE *phDevMemServerContext,
+                                                               IMG_HANDLE *phPrivData);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hDevmemServerContext);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hDevmemCtx,
+                                                                IMG_DEV_VIRTADDR sHeapBaseAddr,
+                                                                IMG_DEVMEM_SIZE_T uiHeapLength,
+                                                                IMG_UINT32 ui32Log2DataPageSize,
+                                                                IMG_HANDLE *phDevmemHeapPtr);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hDevmemHeap);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntMapPMR(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hDevmemServerHeap,
+                                                            IMG_HANDLE hReservation,
+                                                            IMG_HANDLE hPMR,
+                                                            PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+                                                            IMG_HANDLE *phMapping);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hMapping);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntReserveRange(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDevmemServerHeap,
+                                                                  IMG_DEV_VIRTADDR sAddress,
+                                                                  IMG_DEVMEM_SIZE_T uiLength,
+                                                                  IMG_HANDLE *phReservation);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge,
+                                                                    IMG_HANDLE hReservation);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hDeviceNode,
+                                                                   IMG_DEVMEM_SIZE_T uiSize,
+                                                                   IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                                   IMG_UINT32 ui32NumPhysChunks,
+                                                                   IMG_UINT32 ui32NumVirtChunks,
+                                                                   IMG_BOOL *pbMappingTable,
+                                                                   IMG_UINT32 ui32Log2PageSize,
+                                                                   PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                                   IMG_HANDLE *phPMRPtr);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRLocalImportPMR(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hExtHandle,
+                                                              IMG_HANDLE *phPMR,
+                                                              IMG_DEVMEM_SIZE_T *puiSize,
+                                                              IMG_DEVMEM_ALIGN_T *psAlign);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRUnrefPMR(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemSLCFlushInvalRequest(IMG_HANDLE hBridge,
+                                                                       IMG_HANDLE hDeviceNode,
+                                                                       IMG_HANDLE hPmr);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDevmemCtx,
+                                                                  IMG_DEV_VIRTADDR sAddress);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hDeviceNode,
+                                                                   IMG_UINT32 *pui32NumHeapConfigs);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapCount(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hDeviceNode,
+                                                             IMG_UINT32 ui32HeapConfigIndex,
+                                                             IMG_UINT32 *pui32NumHeaps);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge,
+                                                                  IMG_HANDLE hDeviceNode,
+                                                                  IMG_UINT32 ui32HeapConfigIndex,
+                                                                  IMG_UINT32 ui32HeapConfigNameBufSz,
+                                                                  IMG_CHAR *puiHeapConfigName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hDeviceNode,
+                                                               IMG_UINT32 ui32HeapConfigIndex,
+                                                               IMG_UINT32 ui32HeapIndex,
+                                                               IMG_UINT32 ui32HeapNameBufSz,
+                                                               IMG_CHAR *puiHeapNameOut,
+                                                               IMG_DEV_VIRTADDR *psDevVAddrBase,
+                                                               IMG_DEVMEM_SIZE_T *puiHeapLength,
+                                                               IMG_UINT32 *pui32Log2DataPageSizeOut,
+                                                               IMG_UINT32 *pui32Log2ImportAlignmentOut);
+
+
+#endif /* CLIENT_MM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/dpdumpmm_bridge/client_pdumpmm_bridge.c b/drivers/gpu/rogue_m/generated/dpdumpmm_bridge/client_pdumpmm_bridge.c
new file mode 100644 (file)
index 0000000..a6dc4d0
--- /dev/null
@@ -0,0 +1,256 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for pdumpmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_pdumpmm_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_typedefs.h"
+
+#include "devicemem_server.h"
+#include "pmr.h"
+#include "physmem.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMem(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hPMR,
+                                                            IMG_DEVMEM_OFFSET_T uiOffset,
+                                                            IMG_DEVMEM_SIZE_T uiSize,
+                                                            IMG_UINT32 ui32PDumpFlags,
+                                                            IMG_BOOL bbZero)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpLoadMem(
+                                       psPMRInt,
+                                       uiOffset,
+                                       uiSize,
+                                       ui32PDumpFlags,
+                                       bbZero);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMemValue32(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hPMR,
+                                                                   IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                   IMG_UINT32 ui32Value,
+                                                                   IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpLoadMemValue32(
+                                       psPMRInt,
+                                       uiOffset,
+                                       ui32Value,
+                                       ui32PDumpFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMemValue64(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hPMR,
+                                                                   IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                   IMG_UINT64 ui64Value,
+                                                                   IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpLoadMemValue64(
+                                       psPMRInt,
+                                       uiOffset,
+                                       ui64Value,
+                                       ui32PDumpFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpSaveToFile(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hPMR,
+                                                               IMG_DEVMEM_OFFSET_T uiOffset,
+                                                               IMG_DEVMEM_SIZE_T uiSize,
+                                                               IMG_UINT32 ui32ArraySize,
+                                                               const IMG_CHAR *puiFileName)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpSaveToFile(
+                                       psPMRInt,
+                                       uiOffset,
+                                       uiSize,
+                                       ui32ArraySize,
+                                       puiFileName);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpSymbolicAddr(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hPMR,
+                                                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                 IMG_UINT32 ui32MemspaceNameLen,
+                                                                 IMG_CHAR *puiMemspaceName,
+                                                                 IMG_UINT32 ui32SymbolicAddrLen,
+                                                                 IMG_CHAR *puiSymbolicAddr,
+                                                                 IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                                                                 IMG_DEVMEM_OFFSET_T *puiNextSymName)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMR_PDumpSymbolicAddr(
+                                       psPMRInt,
+                                       uiOffset,
+                                       ui32MemspaceNameLen,
+                                       puiMemspaceName,
+                                       ui32SymbolicAddrLen,
+                                       puiSymbolicAddr,
+                                       puiNewOffset,
+                                       puiNextSymName);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpPol32(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hPMR,
+                                                          IMG_DEVMEM_OFFSET_T uiOffset,
+                                                          IMG_UINT32 ui32Value,
+                                                          IMG_UINT32 ui32Mask,
+                                                          PDUMP_POLL_OPERATOR eOperator,
+                                                          IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpPol32(
+                                       psPMRInt,
+                                       uiOffset,
+                                       ui32Value,
+                                       ui32Mask,
+                                       eOperator,
+                                       ui32PDumpFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpCBP(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hPMR,
+                                                        IMG_DEVMEM_OFFSET_T uiReadOffset,
+                                                        IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                                                        IMG_DEVMEM_SIZE_T uiPacketSize,
+                                                        IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRInt = (PMR *) hPMR;
+
+       eError =
+               PMRPDumpCBP(
+                                       psPMRInt,
+                                       uiReadOffset,
+                                       uiWriteOffset,
+                                       uiPacketSize,
+                                       uiBufferSize);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntPDumpSaveToFileVirtual(IMG_HANDLE hBridge,
+                                                                            IMG_HANDLE hDevmemServerContext,
+                                                                            IMG_DEV_VIRTADDR sAddress,
+                                                                            IMG_DEVMEM_SIZE_T uiSize,
+                                                                            IMG_UINT32 ui32ArraySize,
+                                                                            const IMG_CHAR *puiFileName,
+                                                                            IMG_UINT32 ui32FileOffset,
+                                                                            IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       DEVMEMINT_CTX * psDevmemServerContextInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psDevmemServerContextInt = (DEVMEMINT_CTX *) hDevmemServerContext;
+
+       eError =
+               DevmemIntPDumpSaveToFileVirtual(
+                                       psDevmemServerContextInt,
+                                       sAddress,
+                                       uiSize,
+                                       ui32ArraySize,
+                                       puiFileName,
+                                       ui32FileOffset,
+                                       ui32PDumpFlags);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dpvrtl_bridge/client_pvrtl_bridge.c b/drivers/gpu/rogue_m/generated/dpvrtl_bridge/client_pvrtl_bridge.c
new file mode 100644 (file)
index 0000000..252deee
--- /dev/null
@@ -0,0 +1,154 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for pvrtl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_pvrtl_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "devicemem_typedefs.h"
+#include "pvr_tl.h"
+
+#include "tlserver.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLConnect(IMG_HANDLE hBridge)
+{
+       PVRSRV_ERROR eError;
+
+
+       eError =
+               TLServerConnectKM(hBridge
+                                       );
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLDisconnect(IMG_HANDLE hBridge)
+{
+       PVRSRV_ERROR eError;
+
+
+       eError =
+               TLServerDisconnectKM(hBridge
+                                       );
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLOpenStream(IMG_HANDLE hBridge,
+                                                         IMG_CHAR *puiName,
+                                                         IMG_UINT32 ui32Mode,
+                                                         IMG_HANDLE *phSD,
+                                                         DEVMEM_SERVER_EXPORTCOOKIE *phClientBUFExportCookie)
+{
+       PVRSRV_ERROR eError;
+       TL_STREAM_DESC * psSDInt;
+       DEVMEM_EXPORTCOOKIE * psClientBUFExportCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+       eError =
+               TLServerOpenStreamKM(
+                                       puiName,
+                                       ui32Mode,
+                                       &psSDInt,
+                                       &psClientBUFExportCookieInt);
+
+       *phSD = psSDInt;
+       *phClientBUFExportCookie = psClientBUFExportCookieInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLCloseStream(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD)
+{
+       PVRSRV_ERROR eError;
+       TL_STREAM_DESC * psSDInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSDInt = (TL_STREAM_DESC *) hSD;
+
+       eError =
+               TLServerCloseStreamKM(
+                                       psSDInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLAcquireData(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD,
+                                                          IMG_UINT32 *pui32ReadOffset,
+                                                          IMG_UINT32 *pui32ReadLen)
+{
+       PVRSRV_ERROR eError;
+       TL_STREAM_DESC * psSDInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSDInt = (TL_STREAM_DESC *) hSD;
+
+       eError =
+               TLServerAcquireDataKM(
+                                       psSDInt,
+                                       pui32ReadOffset,
+                                       pui32ReadLen);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLReleaseData(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD,
+                                                          IMG_UINT32 ui32ReadOffset,
+                                                          IMG_UINT32 ui32ReadLen)
+{
+       PVRSRV_ERROR eError;
+       TL_STREAM_DESC * psSDInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSDInt = (TL_STREAM_DESC *) hSD;
+
+       eError =
+               TLServerReleaseDataKM(
+                                       psSDInt,
+                                       ui32ReadOffset,
+                                       ui32ReadLen);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dri_bridge/client_ri_bridge.c b/drivers/gpu/rogue_m/generated/dri_bridge/client_ri_bridge.c
new file mode 100644 (file)
index 0000000..1ef8edd
--- /dev/null
@@ -0,0 +1,181 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for ri
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_ri_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "ri_typedefs.h"
+
+#include "ri_server.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIWritePMREntry(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hPMRHandle,
+                                                            IMG_UINT32 ui32TextASize,
+                                                            const IMG_CHAR *puiTextA,
+                                                            IMG_UINT64 ui64LogicalSize)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRHandleInt = (PMR *) hPMRHandle;
+
+       eError =
+               RIWritePMREntryKM(
+                                       psPMRHandleInt,
+                                       ui32TextASize,
+                                       puiTextA,
+                                       ui64LogicalSize);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hPMRHandle,
+                                                                IMG_UINT32 ui32TextBSize,
+                                                                const IMG_CHAR *puiTextB,
+                                                                IMG_UINT64 ui64Offset,
+                                                                IMG_UINT64 ui64Size,
+                                                                IMG_BOOL bIsImport,
+                                                                IMG_BOOL bIsExportable,
+                                                                IMG_HANDLE *phRIHandle)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRHandleInt;
+       RI_HANDLE psRIHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRHandleInt = (PMR *) hPMRHandle;
+
+       eError =
+               RIWriteMEMDESCEntryKM(
+                                       psPMRHandleInt,
+                                       ui32TextBSize,
+                                       puiTextB,
+                                       ui64Offset,
+                                       ui64Size,
+                                       bIsImport,
+                                       bIsExportable,
+                                       &psRIHandleInt);
+
+       *phRIHandle = psRIHandleInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hRIHandle,
+                                                                IMG_DEV_VIRTADDR sAddr)
+{
+       PVRSRV_ERROR eError;
+       RI_HANDLE psRIHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psRIHandleInt = (RI_HANDLE) hRIHandle;
+
+       eError =
+               RIUpdateMEMDESCAddrKM(
+                                       psRIHandleInt,
+                                       sAddr);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hRIHandle)
+{
+       PVRSRV_ERROR eError;
+       RI_HANDLE psRIHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psRIHandleInt = (RI_HANDLE) hRIHandle;
+
+       eError =
+               RIDeleteMEMDESCEntryKM(
+                                       psRIHandleInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpList(IMG_HANDLE hBridge,
+                                                       IMG_HANDLE hPMRHandle)
+{
+       PVRSRV_ERROR eError;
+       PMR * psPMRHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psPMRHandleInt = (PMR *) hPMRHandle;
+
+       eError =
+               RIDumpListKM(
+                                       psPMRHandleInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpAll(IMG_HANDLE hBridge)
+{
+       PVRSRV_ERROR eError;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+       eError =
+               RIDumpAllKM(
+                                       );
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpProcess(IMG_HANDLE hBridge,
+                                                          IMG_PID ui32Pid)
+{
+       PVRSRV_ERROR eError;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+       eError =
+               RIDumpProcessKM(
+                                       ui32Pid);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.c b/drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.c
new file mode 100644 (file)
index 0000000..36e7574
--- /dev/null
@@ -0,0 +1,492 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for sync
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_sync_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "devicemem_typedefs.h"
+
+#include "sync_server.h"
+#include "pdump.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge,
+                                                                    IMG_HANDLE hDevNode,
+                                                                    IMG_HANDLE *phSyncHandle,
+                                                                    IMG_UINT32 *pui32SyncPrimVAddr,
+                                                                    IMG_UINT32 *pui32SyncPrimBlockSize,
+                                                                    DEVMEM_SERVER_EXPORTCOOKIE *phExportCookie)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDevNodeInt;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       DEVMEM_EXPORTCOOKIE * psExportCookieInt;
+
+       hDevNodeInt = (IMG_HANDLE) hDevNode;
+
+       eError =
+               PVRSRVAllocSyncPrimitiveBlockKM(hBridge
+               ,
+                                       hDevNodeInt,
+                                       &psSyncHandleInt,
+                                       pui32SyncPrimVAddr,
+                                       pui32SyncPrimBlockSize,
+                                       &psExportCookieInt);
+
+       *phSyncHandle = psSyncHandleInt;
+       *phExportCookie = psExportCookieInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hSyncHandle)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVFreeSyncPrimitiveBlockKM(
+                                       psSyncHandleInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimSet(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hSyncHandle,
+                                                        IMG_UINT32 ui32Index,
+                                                        IMG_UINT32 ui32Value)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVSyncPrimSetKM(
+                                       psSyncHandleInt,
+                                       ui32Index,
+                                       ui32Value);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncPrimSet(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hSyncHandle,
+                                                              IMG_UINT32 ui32Value)
+{
+       PVRSRV_ERROR eError;
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SERVER_SYNC_PRIMITIVE *) hSyncHandle;
+
+       eError =
+               PVRSRVServerSyncPrimSetKM(
+                                       psSyncHandleInt,
+                                       ui32Value);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
+                                                                     IMG_HANDLE hhRecord)
+{
+       PVRSRV_ERROR eError;
+       SYNC_RECORD_HANDLE pshRecordInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       pshRecordInt = (SYNC_RECORD_HANDLE) hhRecord;
+
+       eError =
+               PVRSRVSyncRecordRemoveByHandleKM(
+                                       pshRecordInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE *phhRecord,
+                                                          IMG_HANDLE hhServerSyncPrimBlock,
+                                                          IMG_UINT32 ui32ui32FwBlockAddr,
+                                                          IMG_UINT32 ui32ui32SyncOffset,
+                                                          IMG_BOOL bbServerSync,
+                                                          IMG_UINT32 ui32ClassNameSize,
+                                                          const IMG_CHAR *puiClassName)
+{
+       PVRSRV_ERROR eError;
+       SYNC_RECORD_HANDLE pshRecordInt;
+       SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       pshServerSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK *) hhServerSyncPrimBlock;
+
+       eError =
+               PVRSRVSyncRecordAddKM(
+                                       &pshRecordInt,
+                                       pshServerSyncPrimBlockInt,
+                                       ui32ui32FwBlockAddr,
+                                       ui32ui32SyncOffset,
+                                       bbServerSync,
+                                       ui32ClassNameSize,
+                                       puiClassName);
+
+       *phhRecord = pshRecordInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncAlloc(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hDevNode,
+                                                            IMG_HANDLE *phSyncHandle,
+                                                            IMG_UINT32 *pui32SyncPrimVAddr,
+                                                            IMG_UINT32 ui32ClassNameSize,
+                                                            const IMG_CHAR *puiClassName)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hDevNodeInt;
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       hDevNodeInt = (IMG_HANDLE) hDevNode;
+
+       eError =
+               PVRSRVServerSyncAllocKM(
+                                       hDevNodeInt,
+                                       &psSyncHandleInt,
+                                       pui32SyncPrimVAddr,
+                                       ui32ClassNameSize,
+                                       puiClassName);
+
+       *phSyncHandle = psSyncHandleInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncFree(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hSyncHandle)
+{
+       PVRSRV_ERROR eError;
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SERVER_SYNC_PRIMITIVE *) hSyncHandle;
+
+       eError =
+               PVRSRVServerSyncFreeKM(
+                                       psSyncHandleInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncQueueHWOp(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hSyncHandle,
+                                                                IMG_BOOL bbUpdate,
+                                                                IMG_UINT32 *pui32FenceValue,
+                                                                IMG_UINT32 *pui32UpdateValue)
+{
+       PVRSRV_ERROR eError;
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SERVER_SYNC_PRIMITIVE *) hSyncHandle;
+
+       eError =
+               PVRSRVServerSyncQueueHWOpKM(
+                                       psSyncHandleInt,
+                                       bbUpdate,
+                                       pui32FenceValue,
+                                       pui32UpdateValue);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncGetStatus(IMG_HANDLE hBridge,
+                                                                IMG_UINT32 ui32SyncCount,
+                                                                IMG_HANDLE *phSyncHandle,
+                                                                IMG_UINT32 *pui32UID,
+                                                                IMG_UINT32 *pui32FWAddr,
+                                                                IMG_UINT32 *pui32CurrentOp,
+                                                                IMG_UINT32 *pui32NextOp)
+{
+       PVRSRV_ERROR eError;
+       SERVER_SYNC_PRIMITIVE * *psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SERVER_SYNC_PRIMITIVE **) phSyncHandle;
+
+       eError =
+               PVRSRVServerSyncGetStatusKM(
+                                       ui32SyncCount,
+                                       psSyncHandleInt,
+                                       pui32UID,
+                                       pui32FWAddr,
+                                       pui32CurrentOp,
+                                       pui32NextOp);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpCreate(IMG_HANDLE hBridge,
+                                                             IMG_UINT32 ui32SyncBlockCount,
+                                                             IMG_HANDLE *phBlockList,
+                                                             IMG_UINT32 ui32ClientSyncCount,
+                                                             IMG_UINT32 *pui32SyncBlockIndex,
+                                                             IMG_UINT32 *pui32Index,
+                                                             IMG_UINT32 ui32ServerSyncCount,
+                                                             IMG_HANDLE *phServerSync,
+                                                             IMG_HANDLE *phServerCookie)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * *psBlockListInt;
+       SERVER_SYNC_PRIMITIVE * *psServerSyncInt;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psBlockListInt = (SYNC_PRIMITIVE_BLOCK **) phBlockList;
+       psServerSyncInt = (SERVER_SYNC_PRIMITIVE **) phServerSync;
+
+       eError =
+               PVRSRVSyncPrimOpCreateKM(
+                                       ui32SyncBlockCount,
+                                       psBlockListInt,
+                                       ui32ClientSyncCount,
+                                       pui32SyncBlockIndex,
+                                       pui32Index,
+                                       ui32ServerSyncCount,
+                                       psServerSyncInt,
+                                       &psServerCookieInt);
+
+       *phServerCookie = psServerCookieInt;
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpTake(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hServerCookie,
+                                                           IMG_UINT32 ui32ClientSyncCount,
+                                                           IMG_UINT32 *pui32Flags,
+                                                           IMG_UINT32 *pui32FenceValue,
+                                                           IMG_UINT32 *pui32UpdateValue,
+                                                           IMG_UINT32 ui32ServerSyncCount,
+                                                           IMG_UINT32 *pui32ServerFlags)
+{
+       PVRSRV_ERROR eError;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psServerCookieInt = (SERVER_OP_COOKIE *) hServerCookie;
+
+       eError =
+               PVRSRVSyncPrimOpTakeKM(
+                                       psServerCookieInt,
+                                       ui32ClientSyncCount,
+                                       pui32Flags,
+                                       pui32FenceValue,
+                                       pui32UpdateValue,
+                                       ui32ServerSyncCount,
+                                       pui32ServerFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpReady(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hServerCookie,
+                                                            IMG_BOOL *pbReady)
+{
+       PVRSRV_ERROR eError;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psServerCookieInt = (SERVER_OP_COOKIE *) hServerCookie;
+
+       eError =
+               PVRSRVSyncPrimOpReadyKM(
+                                       psServerCookieInt,
+                                       pbReady);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpComplete(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hServerCookie)
+{
+       PVRSRV_ERROR eError;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psServerCookieInt = (SERVER_OP_COOKIE *) hServerCookie;
+
+       eError =
+               PVRSRVSyncPrimOpCompleteKM(
+                                       psServerCookieInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpDestroy(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hServerCookie)
+{
+       PVRSRV_ERROR eError;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psServerCookieInt = (SERVER_OP_COOKIE *) hServerCookie;
+
+       eError =
+               PVRSRVSyncPrimOpDestroyKM(
+                                       psServerCookieInt);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDump(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSyncHandle,
+                                                          IMG_UINT32 ui32Offset)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVSyncPrimPDumpKM(
+                                       psSyncHandleInt,
+                                       ui32Offset);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hSyncHandle,
+                                                               IMG_UINT32 ui32Offset,
+                                                               IMG_UINT32 ui32Value)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVSyncPrimPDumpValueKM(
+                                       psSyncHandleInt,
+                                       ui32Offset,
+                                       ui32Value);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hSyncHandle,
+                                                             IMG_UINT32 ui32Offset,
+                                                             IMG_UINT32 ui32Value,
+                                                             IMG_UINT32 ui32Mask,
+                                                             PDUMP_POLL_OPERATOR eOperator,
+                                                             PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVSyncPrimPDumpPolKM(
+                                       psSyncHandleInt,
+                                       ui32Offset,
+                                       ui32Value,
+                                       ui32Mask,
+                                       eOperator,
+                                       uiPDumpFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpPDumpPol(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hServerCookie,
+                                                               PDUMP_POLL_OPERATOR eOperator,
+                                                               PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       SERVER_OP_COOKIE * psServerCookieInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psServerCookieInt = (SERVER_OP_COOKIE *) hServerCookie;
+
+       eError =
+               PVRSRVSyncPrimOpPDumpPolKM(
+                                       psServerCookieInt,
+                                       eOperator,
+                                       uiPDumpFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hSyncHandle,
+                                                             IMG_UINT32 ui32Offset,
+                                                             IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                                                             IMG_DEVMEM_SIZE_T uiPacketSize,
+                                                             IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVRSRV_ERROR eError;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
+       PVR_UNREFERENCED_PARAMETER(hBridge);
+
+       psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+       eError =
+               PVRSRVSyncPrimPDumpCBPKM(
+                                       psSyncHandleInt,
+                                       ui32Offset,
+                                       uiWriteOffset,
+                                       uiPacketSize,
+                                       uiBufferSize);
+
+       return eError;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.h b/drivers/gpu/rogue_m/generated/dsync_bridge/client_sync_bridge.h
new file mode 100644 (file)
index 0000000..e80501c
--- /dev/null
@@ -0,0 +1,161 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge header for sync
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_SYNC_BRIDGE_H
+#define CLIENT_SYNC_BRIDGE_H
+
+#include "common_sync_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge,
+                                                                    IMG_HANDLE hDevNode,
+                                                                    IMG_HANDLE *phSyncHandle,
+                                                                    IMG_UINT32 *pui32SyncPrimVAddr,
+                                                                    IMG_UINT32 *pui32SyncPrimBlockSize,
+                                                                    DEVMEM_SERVER_EXPORTCOOKIE *phExportCookie);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hSyncHandle);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimSet(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hSyncHandle,
+                                                        IMG_UINT32 ui32Index,
+                                                        IMG_UINT32 ui32Value);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncPrimSet(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hSyncHandle,
+                                                              IMG_UINT32 ui32Value);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
+                                                                     IMG_HANDLE hhRecord);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE *phhRecord,
+                                                          IMG_HANDLE hhServerSyncPrimBlock,
+                                                          IMG_UINT32 ui32ui32FwBlockAddr,
+                                                          IMG_UINT32 ui32ui32SyncOffset,
+                                                          IMG_BOOL bbServerSync,
+                                                          IMG_UINT32 ui32ClassNameSize,
+                                                          const IMG_CHAR *puiClassName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncAlloc(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hDevNode,
+                                                            IMG_HANDLE *phSyncHandle,
+                                                            IMG_UINT32 *pui32SyncPrimVAddr,
+                                                            IMG_UINT32 ui32ClassNameSize,
+                                                            const IMG_CHAR *puiClassName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncFree(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hSyncHandle);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncQueueHWOp(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hSyncHandle,
+                                                                IMG_BOOL bbUpdate,
+                                                                IMG_UINT32 *pui32FenceValue,
+                                                                IMG_UINT32 *pui32UpdateValue);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncGetStatus(IMG_HANDLE hBridge,
+                                                                IMG_UINT32 ui32SyncCount,
+                                                                IMG_HANDLE *phSyncHandle,
+                                                                IMG_UINT32 *pui32UID,
+                                                                IMG_UINT32 *pui32FWAddr,
+                                                                IMG_UINT32 *pui32CurrentOp,
+                                                                IMG_UINT32 *pui32NextOp);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpCreate(IMG_HANDLE hBridge,
+                                                             IMG_UINT32 ui32SyncBlockCount,
+                                                             IMG_HANDLE *phBlockList,
+                                                             IMG_UINT32 ui32ClientSyncCount,
+                                                             IMG_UINT32 *pui32SyncBlockIndex,
+                                                             IMG_UINT32 *pui32Index,
+                                                             IMG_UINT32 ui32ServerSyncCount,
+                                                             IMG_HANDLE *phServerSync,
+                                                             IMG_HANDLE *phServerCookie);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpTake(IMG_HANDLE hBridge,
+                                                           IMG_HANDLE hServerCookie,
+                                                           IMG_UINT32 ui32ClientSyncCount,
+                                                           IMG_UINT32 *pui32Flags,
+                                                           IMG_UINT32 *pui32FenceValue,
+                                                           IMG_UINT32 *pui32UpdateValue,
+                                                           IMG_UINT32 ui32ServerSyncCount,
+                                                           IMG_UINT32 *pui32ServerFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpReady(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hServerCookie,
+                                                            IMG_BOOL *pbReady);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpComplete(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hServerCookie);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpDestroy(IMG_HANDLE hBridge,
+                                                              IMG_HANDLE hServerCookie);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDump(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSyncHandle,
+                                                          IMG_UINT32 ui32Offset);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hSyncHandle,
+                                                               IMG_UINT32 ui32Offset,
+                                                               IMG_UINT32 ui32Value);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hSyncHandle,
+                                                             IMG_UINT32 ui32Offset,
+                                                             IMG_UINT32 ui32Value,
+                                                             IMG_UINT32 ui32Mask,
+                                                             PDUMP_POLL_OPERATOR eOperator,
+                                                             PDUMP_FLAGS_T uiPDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpPDumpPol(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hServerCookie,
+                                                               PDUMP_POLL_OPERATOR eOperator,
+                                                               PDUMP_FLAGS_T uiPDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge,
+                                                             IMG_HANDLE hSyncHandle,
+                                                             IMG_UINT32 ui32Offset,
+                                                             IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                                                             IMG_DEVMEM_SIZE_T uiPacketSize,
+                                                             IMG_DEVMEM_SIZE_T uiBufferSize);
+
+
+#endif /* CLIENT_SYNC_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/mm_bridge/common_mm_bridge.h b/drivers/gpu/rogue_m/generated/mm_bridge/common_mm_bridge.h
new file mode 100644 (file)
index 0000000..0f35c46
--- /dev/null
@@ -0,0 +1,530 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for mm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for mm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_MM_BRIDGE_H
+#define COMMON_MM_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_MM_CMD_FIRST                     0
+#define PVRSRV_BRIDGE_MM_PMREXPORTPMR                  PVRSRV_BRIDGE_MM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR                        PVRSRV_BRIDGE_MM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_MM_PMRGETUID                     PVRSRV_BRIDGE_MM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_MM_PMRMAKESERVEREXPORTCLIENTEXPORT                       PVRSRV_BRIDGE_MM_CMD_FIRST+3
+#define PVRSRV_BRIDGE_MM_PMRUNMAKESERVEREXPORTCLIENTEXPORT                     PVRSRV_BRIDGE_MM_CMD_FIRST+4
+#define PVRSRV_BRIDGE_MM_PMRIMPORTPMR                  PVRSRV_BRIDGE_MM_CMD_FIRST+5
+#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE                    PVRSRV_BRIDGE_MM_CMD_FIRST+6
+#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY                   PVRSRV_BRIDGE_MM_CMD_FIRST+7
+#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE                   PVRSRV_BRIDGE_MM_CMD_FIRST+8
+#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY                  PVRSRV_BRIDGE_MM_CMD_FIRST+9
+#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR                       PVRSRV_BRIDGE_MM_CMD_FIRST+10
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR                     PVRSRV_BRIDGE_MM_CMD_FIRST+11
+#define PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE                 PVRSRV_BRIDGE_MM_CMD_FIRST+12
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE                       PVRSRV_BRIDGE_MM_CMD_FIRST+13
+#define PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR                        PVRSRV_BRIDGE_MM_CMD_FIRST+14
+#define PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR                     PVRSRV_BRIDGE_MM_CMD_FIRST+15
+#define PVRSRV_BRIDGE_MM_PMRUNREFPMR                   PVRSRV_BRIDGE_MM_CMD_FIRST+16
+#define PVRSRV_BRIDGE_MM_DEVMEMSLCFLUSHINVALREQUEST                    PVRSRV_BRIDGE_MM_CMD_FIRST+17
+#define PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID                 PVRSRV_BRIDGE_MM_CMD_FIRST+18
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT                        PVRSRV_BRIDGE_MM_CMD_FIRST+19
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT                      PVRSRV_BRIDGE_MM_CMD_FIRST+20
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME                 PVRSRV_BRIDGE_MM_CMD_FIRST+21
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS                    PVRSRV_BRIDGE_MM_CMD_FIRST+22
+#define PVRSRV_BRIDGE_MM_CMD_LAST                      (PVRSRV_BRIDGE_MM_CMD_FIRST+22)
+
+
+/*******************************************
+            PMRExportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRExportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMREXPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMREXPORTPMR;
+
+
+/* Bridge out structure for PMRExportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMREXPORTPMR_TAG
+{
+       IMG_HANDLE hPMRExport;
+       IMG_UINT64 ui64Size;
+       IMG_UINT32 ui32Log2Contig;
+       IMG_UINT64 ui64Password;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMREXPORTPMR;
+
+/*******************************************
+            PMRUnexportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRUnexportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR_TAG
+{
+       IMG_HANDLE hPMRExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR;
+
+
+/* Bridge out structure for PMRUnexportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR;
+
+/*******************************************
+            PMRGetUID          
+ *******************************************/
+
+/* Bridge in structure for PMRGetUID */
+typedef struct PVRSRV_BRIDGE_IN_PMRGETUID_TAG
+{
+       IMG_HANDLE hPMR;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRGETUID;
+
+
+/* Bridge out structure for PMRGetUID */
+typedef struct PVRSRV_BRIDGE_OUT_PMRGETUID_TAG
+{
+       IMG_UINT64 ui64UID;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRGETUID;
+
+/*******************************************
+            PMRMakeServerExportClientExport          
+ *******************************************/
+
+/* Bridge in structure for PMRMakeServerExportClientExport */
+typedef struct PVRSRV_BRIDGE_IN_PMRMAKESERVEREXPORTCLIENTEXPORT_TAG
+{
+       DEVMEM_SERVER_EXPORTCOOKIE hPMRServerExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRMAKESERVEREXPORTCLIENTEXPORT;
+
+
+/* Bridge out structure for PMRMakeServerExportClientExport */
+typedef struct PVRSRV_BRIDGE_OUT_PMRMAKESERVEREXPORTCLIENTEXPORT_TAG
+{
+       IMG_HANDLE hPMRExportOut;
+       IMG_UINT64 ui64Size;
+       IMG_UINT32 ui32Log2Contig;
+       IMG_UINT64 ui64Password;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRMAKESERVEREXPORTCLIENTEXPORT;
+
+/*******************************************
+            PMRUnmakeServerExportClientExport          
+ *******************************************/
+
+/* Bridge in structure for PMRUnmakeServerExportClientExport */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNMAKESERVEREXPORTCLIENTEXPORT_TAG
+{
+       IMG_HANDLE hPMRExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRUNMAKESERVEREXPORTCLIENTEXPORT;
+
+
+/* Bridge out structure for PMRUnmakeServerExportClientExport */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNMAKESERVEREXPORTCLIENTEXPORT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRUNMAKESERVEREXPORTCLIENTEXPORT;
+
+/*******************************************
+            PMRImportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRImportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRIMPORTPMR_TAG
+{
+       IMG_HANDLE hPMRExport;
+       IMG_UINT64 ui64uiPassword;
+       IMG_UINT64 ui64uiSize;
+       IMG_UINT32 ui32uiLog2Contig;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRIMPORTPMR;
+
+
+/* Bridge out structure for PMRImportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRIMPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRIMPORTPMR;
+
+/*******************************************
+            DevmemIntCtxCreate          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxCreate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE_TAG
+{
+       IMG_HANDLE hDeviceNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE;
+
+
+/* Bridge out structure for DevmemIntCtxCreate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE_TAG
+{
+       IMG_HANDLE hDevMemServerContext;
+       IMG_HANDLE hPrivData;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE;
+
+/*******************************************
+            DevmemIntCtxDestroy          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxDestroy */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY_TAG
+{
+       IMG_HANDLE hDevmemServerContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY;
+
+
+/* Bridge out structure for DevmemIntCtxDestroy */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY;
+
+/*******************************************
+            DevmemIntHeapCreate          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntHeapCreate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE_TAG
+{
+       IMG_HANDLE hDevmemCtx;
+       IMG_DEV_VIRTADDR sHeapBaseAddr;
+       IMG_DEVMEM_SIZE_T uiHeapLength;
+       IMG_UINT32 ui32Log2DataPageSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE;
+
+
+/* Bridge out structure for DevmemIntHeapCreate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE_TAG
+{
+       IMG_HANDLE hDevmemHeapPtr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE;
+
+/*******************************************
+            DevmemIntHeapDestroy          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntHeapDestroy */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY_TAG
+{
+       IMG_HANDLE hDevmemHeap;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY;
+
+
+/* Bridge out structure for DevmemIntHeapDestroy */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY;
+
+/*******************************************
+            DevmemIntMapPMR          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntMapPMR */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR_TAG
+{
+       IMG_HANDLE hDevmemServerHeap;
+       IMG_HANDLE hReservation;
+       IMG_HANDLE hPMR;
+       PVRSRV_MEMALLOCFLAGS_T uiMapFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR;
+
+
+/* Bridge out structure for DevmemIntMapPMR */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR_TAG
+{
+       IMG_HANDLE hMapping;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR;
+
+/*******************************************
+            DevmemIntUnmapPMR          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnmapPMR */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR_TAG
+{
+       IMG_HANDLE hMapping;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR;
+
+
+/* Bridge out structure for DevmemIntUnmapPMR */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR;
+
+/*******************************************
+            DevmemIntReserveRange          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntReserveRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE_TAG
+{
+       IMG_HANDLE hDevmemServerHeap;
+       IMG_DEV_VIRTADDR sAddress;
+       IMG_DEVMEM_SIZE_T uiLength;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE;
+
+
+/* Bridge out structure for DevmemIntReserveRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE_TAG
+{
+       IMG_HANDLE hReservation;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE;
+
+/*******************************************
+            DevmemIntUnreserveRange          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnreserveRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE_TAG
+{
+       IMG_HANDLE hReservation;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE;
+
+
+/* Bridge out structure for DevmemIntUnreserveRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE;
+
+/*******************************************
+            PhysmemNewRamBackedPMR          
+ *******************************************/
+
+/* Bridge in structure for PhysmemNewRamBackedPMR */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_DEVMEM_SIZE_T uiChunkSize;
+       IMG_UINT32 ui32NumPhysChunks;
+       IMG_UINT32 ui32NumVirtChunks;
+       IMG_BOOL * pbMappingTable;
+       IMG_UINT32 ui32Log2PageSize;
+       PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR;
+
+
+/* Bridge out structure for PhysmemNewRamBackedPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR_TAG
+{
+       IMG_HANDLE hPMRPtr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR;
+
+/*******************************************
+            PMRLocalImportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRLocalImportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR_TAG
+{
+       IMG_HANDLE hExtHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR;
+
+
+/* Bridge out structure for PMRLocalImportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_DEVMEM_ALIGN_T sAlign;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR;
+
+/*******************************************
+            PMRUnrefPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRUnrefPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNREFPMR_TAG
+{
+       IMG_HANDLE hPMR;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRUNREFPMR;
+
+
+/* Bridge out structure for PMRUnrefPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNREFPMR_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRUNREFPMR;
+
+/*******************************************
+            DevmemSLCFlushInvalRequest          
+ *******************************************/
+
+/* Bridge in structure for DevmemSLCFlushInvalRequest */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_HANDLE hPmr;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST;
+
+
+/* Bridge out structure for DevmemSLCFlushInvalRequest */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST;
+
+/*******************************************
+            DevmemIsVDevAddrValid          
+ *******************************************/
+
+/* Bridge in structure for DevmemIsVDevAddrValid */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID_TAG
+{
+       IMG_HANDLE hDevmemCtx;
+       IMG_DEV_VIRTADDR sAddress;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID;
+
+
+/* Bridge out structure for DevmemIsVDevAddrValid */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID;
+
+/*******************************************
+            HeapCfgHeapConfigCount          
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapConfigCount */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT_TAG
+{
+       IMG_HANDLE hDeviceNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT;
+
+
+/* Bridge out structure for HeapCfgHeapConfigCount */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT_TAG
+{
+       IMG_UINT32 ui32NumHeapConfigs;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT;
+
+/*******************************************
+            HeapCfgHeapCount          
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapCount */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_UINT32 ui32HeapConfigIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT;
+
+
+/* Bridge out structure for HeapCfgHeapCount */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT_TAG
+{
+       IMG_UINT32 ui32NumHeaps;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT;
+
+/*******************************************
+            HeapCfgHeapConfigName          
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapConfigName */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_UINT32 ui32HeapConfigIndex;
+       IMG_UINT32 ui32HeapConfigNameBufSz;
+       /* Output pointer puiHeapConfigName is also an implied input */
+       IMG_CHAR * puiHeapConfigName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME;
+
+
+/* Bridge out structure for HeapCfgHeapConfigName */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME_TAG
+{
+       IMG_CHAR * puiHeapConfigName;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME;
+
+/*******************************************
+            HeapCfgHeapDetails          
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapDetails */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_UINT32 ui32HeapConfigIndex;
+       IMG_UINT32 ui32HeapIndex;
+       IMG_UINT32 ui32HeapNameBufSz;
+       /* Output pointer puiHeapNameOut is also an implied input */
+       IMG_CHAR * puiHeapNameOut;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS;
+
+
+/* Bridge out structure for HeapCfgHeapDetails */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS_TAG
+{
+       IMG_CHAR * puiHeapNameOut;
+       IMG_DEV_VIRTADDR sDevVAddrBase;
+       IMG_DEVMEM_SIZE_T uiHeapLength;
+       IMG_UINT32 ui32Log2DataPageSizeOut;
+       IMG_UINT32 ui32Log2ImportAlignmentOut;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS;
+
+#endif /* COMMON_MM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/mm_bridge/server_mm_bridge.c b/drivers/gpu/rogue_m/generated/mm_bridge/server_mm_bridge.c
new file mode 100644 (file)
index 0000000..03e3e33
--- /dev/null
@@ -0,0 +1,1699 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for mm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for mm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "devicemem_server.h"
+#include "pmr.h"
+#include "devicemem_heapcfg.h"
+#include "physmem.h"
+
+
+#include "common_mm_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+static PVRSRV_ERROR ReleasePMRExport(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+static PVRSRV_ERROR ReleasePMRExportOut(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePMRExportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMREXPORTPMR *psPMRExportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMREXPORTPMR *psPMRExportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+       PMR_EXPORT * psPMRExportInt = IMG_NULL;
+       IMG_HANDLE hPMRExportInt = IMG_NULL;
+
+
+
+
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRExportPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRExportPMRIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRExportPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PMRExportPMR_exit;
+                                       }
+                               }
+
+
+       psPMRExportPMROUT->eError =
+               PMRExportPMR(
+                                       psPMRInt,
+                                       &psPMRExportInt,
+                                       &psPMRExportPMROUT->ui64Size,
+                                       &psPMRExportPMROUT->ui32Log2Contig,
+                                       &psPMRExportPMROUT->ui64Password);
+       /* Exit early if bridged call fails */
+       if(psPMRExportPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PMRExportPMR_exit;
+       }
+       PMRUnlock();
+
+
+       /*
+        * For cases where we need a cross process handle we actually allocate two.
+        * 
+        * The first one is a connection specific handle and it gets given the real
+        * release function. This handle does *NOT* get returned to the caller. It's
+        * purpose is to release any leaked resources when we either have a bad or
+        * abnormally terminated client. If we didn't do this then the resource
+        * wouldn't be freed until driver unload. If the resource is freed normally,
+        * this handle can be looked up via the cross process handle and then
+        * released accordingly.
+        * 
+        * The second one is a cross process handle and it gets given a noop release
+        * function. This handle does get returned to the caller.
+        */
+       psPMRExportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &hPMRExportInt,
+                                                       (IMG_VOID *) psPMRExportInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnexportPMR);
+       if (psPMRExportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRExportPMR_exit;
+       }
+
+       psPMRExportPMROUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+                                                       &psPMRExportPMROUT->hPMRExport,
+                                                       (IMG_VOID *) psPMRExportInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+                                                       (PFN_HANDLE_RELEASE)&ReleasePMRExport);
+       if (psPMRExportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRExportPMR_exit;
+       }
+
+
+
+PMRExportPMR_exit:
+       if (psPMRExportPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMRExportPMROUT->hPMRExport)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                               (IMG_HANDLE) psPMRExportPMROUT->hPMRExport,
+                                               PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+               }
+
+               if (hPMRExportInt)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               hPMRExportInt,
+                                               PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psPMRExportInt = IMG_NULL;
+               }
+
+               if (psPMRExportInt)
+               {
+                       PMRUnexportPMR(psPMRExportInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRUnexportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR *psPMRUnexportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR *psPMRUnexportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR_EXPORT * psPMRExportInt = IMG_NULL;
+       IMG_HANDLE hPMRExportInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+       PMRLock();
+
+
+
+       psPMRUnexportPMROUT->eError =
+               PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_VOID **) &psPMRExportInt,
+                                       (IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK);
+
+       /*
+        * Find the connection specific handle that represents the same data
+        * as the cross process handle as releasing it will actually call the
+        * data's real release function (see the function where the cross
+        * process handle is allocated for more details).
+        */
+       psPMRUnexportPMROUT->eError =
+               PVRSRVFindHandle(psConnection->psHandleBase,
+                                       &hPMRExportInt,
+                                       psPMRExportInt,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK);
+
+       psPMRUnexportPMROUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       hPMRExportInt,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT((psPMRUnexportPMROUT->eError == PVRSRV_OK) || (psPMRUnexportPMROUT->eError == PVRSRV_ERROR_RETRY));
+
+       psPMRUnexportPMROUT->eError =
+               PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       if ((psPMRUnexportPMROUT->eError != PVRSRV_OK) && (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               PMRUnlock();
+               goto PMRUnexportPMR_exit;
+       }
+
+       PMRUnlock();
+
+
+PMRUnexportPMR_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRGetUID(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRGETUID *psPMRGetUIDIN,
+                                         PVRSRV_BRIDGE_OUT_PMRGETUID *psPMRGetUIDOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRGetUIDOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRGetUIDIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRGetUIDOUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PMRGetUID_exit;
+                                       }
+                               }
+
+
+       psPMRGetUIDOUT->eError =
+               PMRGetUID(
+                                       psPMRInt,
+                                       &psPMRGetUIDOUT->ui64UID);
+       PMRUnlock();
+
+
+
+
+PMRGetUID_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRMakeServerExportClientExport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRMAKESERVEREXPORTCLIENTEXPORT *psPMRMakeServerExportClientExportIN,
+                                         PVRSRV_BRIDGE_OUT_PMRMAKESERVEREXPORTCLIENTEXPORT *psPMRMakeServerExportClientExportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEM_EXPORTCOOKIE * psPMRServerExportInt = IMG_NULL;
+       PMR_EXPORT * psPMRExportOutInt = IMG_NULL;
+       IMG_HANDLE hPMRExportOutInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRMakeServerExportClientExportOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRServerExportInt,
+                                                                                       psPMRMakeServerExportClientExportIN->hPMRServerExport,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+                                       if(psPMRMakeServerExportClientExportOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRMakeServerExportClientExport_exit;
+                                       }
+                               }
+
+
+       psPMRMakeServerExportClientExportOUT->eError =
+               PMRMakeServerExportClientExport(
+                                       psPMRServerExportInt,
+                                       &psPMRExportOutInt,
+                                       &psPMRMakeServerExportClientExportOUT->ui64Size,
+                                       &psPMRMakeServerExportClientExportOUT->ui32Log2Contig,
+                                       &psPMRMakeServerExportClientExportOUT->ui64Password);
+       /* Exit early if bridged call fails */
+       if(psPMRMakeServerExportClientExportOUT->eError != PVRSRV_OK)
+       {
+               goto PMRMakeServerExportClientExport_exit;
+       }
+
+
+       /*
+        * For cases where we need a cross process handle we actually allocate two.
+        * 
+        * The first one is a connection specific handle and it gets given the real
+        * release function. This handle does *NOT* get returned to the caller. It's
+        * purpose is to release any leaked resources when we either have a bad or
+        * abnormally terminated client. If we didn't do this then the resource
+        * wouldn't be freed until driver unload. If the resource is freed normally,
+        * this handle can be looked up via the cross process handle and then
+        * released accordingly.
+        * 
+        * The second one is a cross process handle and it gets given a noop release
+        * function. This handle does get returned to the caller.
+        */
+       psPMRMakeServerExportClientExportOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &hPMRExportOutInt,
+                                                       (IMG_VOID *) psPMRExportOutInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnmakeServerExportClientExport);
+       if (psPMRMakeServerExportClientExportOUT->eError != PVRSRV_OK)
+       {
+               goto PMRMakeServerExportClientExport_exit;
+       }
+
+       psPMRMakeServerExportClientExportOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+                                                       &psPMRMakeServerExportClientExportOUT->hPMRExportOut,
+                                                       (IMG_VOID *) psPMRExportOutInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+                                                       (PFN_HANDLE_RELEASE)&ReleasePMRExportOut);
+       if (psPMRMakeServerExportClientExportOUT->eError != PVRSRV_OK)
+       {
+               goto PMRMakeServerExportClientExport_exit;
+       }
+
+
+
+PMRMakeServerExportClientExport_exit:
+       if (psPMRMakeServerExportClientExportOUT->eError != PVRSRV_OK)
+       {
+               if (psPMRMakeServerExportClientExportOUT->hPMRExportOut)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                               (IMG_HANDLE) psPMRMakeServerExportClientExportOUT->hPMRExportOut,
+                                               PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+               }
+
+               if (hPMRExportOutInt)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               hPMRExportOutInt,
+                                               PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psPMRExportOutInt = IMG_NULL;
+               }
+
+               if (psPMRExportOutInt)
+               {
+                       PMRUnmakeServerExportClientExport(psPMRExportOutInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRUnmakeServerExportClientExport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRUNMAKESERVEREXPORTCLIENTEXPORT *psPMRUnmakeServerExportClientExportIN,
+                                         PVRSRV_BRIDGE_OUT_PMRUNMAKESERVEREXPORTCLIENTEXPORT *psPMRUnmakeServerExportClientExportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR_EXPORT * psPMRExportInt = IMG_NULL;
+       IMG_HANDLE hPMRExportInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+
+       psPMRUnmakeServerExportClientExportOUT->eError =
+               PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_VOID **) &psPMRExportInt,
+                                       (IMG_HANDLE) psPMRUnmakeServerExportClientExportIN->hPMRExport,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT(psPMRUnmakeServerExportClientExportOUT->eError == PVRSRV_OK);
+
+       /*
+        * Find the connection specific handle that represents the same data
+        * as the cross process handle as releasing it will actually call the
+        * data's real release function (see the function where the cross
+        * process handle is allocated for more details).
+        */
+       psPMRUnmakeServerExportClientExportOUT->eError =
+               PVRSRVFindHandle(psConnection->psHandleBase,
+                                       &hPMRExportInt,
+                                       psPMRExportInt,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT(psPMRUnmakeServerExportClientExportOUT->eError == PVRSRV_OK);
+
+       psPMRUnmakeServerExportClientExportOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       hPMRExportInt,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       PVR_ASSERT((psPMRUnmakeServerExportClientExportOUT->eError == PVRSRV_OK) || (psPMRUnmakeServerExportClientExportOUT->eError == PVRSRV_ERROR_RETRY));
+
+       psPMRUnmakeServerExportClientExportOUT->eError =
+               PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+                                       (IMG_HANDLE) psPMRUnmakeServerExportClientExportIN->hPMRExport,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+       if ((psPMRUnmakeServerExportClientExportOUT->eError != PVRSRV_OK) && (psPMRUnmakeServerExportClientExportOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto PMRUnmakeServerExportClientExport_exit;
+       }
+
+
+
+PMRUnmakeServerExportClientExport_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRImportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRIMPORTPMR *psPMRImportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRIMPORTPMR *psPMRImportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR_EXPORT * psPMRExportInt = IMG_NULL;
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+#if defined (SUPPORT_AUTH)
+       psPMRImportPMROUT->eError = OSCheckAuthentication(psConnection, 1);
+       if (psPMRImportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRImportPMR_exit;
+       }
+#endif
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRImportPMROUT->eError =
+                                               PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+                                                                                       (IMG_VOID **) &psPMRExportInt,
+                                                                                       psPMRImportPMRIN->hPMRExport,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+                                       if(psPMRImportPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PMRImportPMR_exit;
+                                       }
+                               }
+
+
+       psPMRImportPMROUT->eError =
+               PMRImportPMR(
+                                       psPMRExportInt,
+                                       psPMRImportPMRIN->ui64uiPassword,
+                                       psPMRImportPMRIN->ui64uiSize,
+                                       psPMRImportPMRIN->ui32uiLog2Contig,
+                                       &psPMRInt);
+       /* Exit early if bridged call fails */
+       if(psPMRImportPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PMRImportPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psPMRImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPMRImportPMROUT->hPMR,
+                                                       (IMG_VOID *) psPMRInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPMRImportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRImportPMR_exit;
+       }
+
+
+
+
+PMRImportPMR_exit:
+       if (psPMRImportPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMRInt)
+               {
+                       PMRUnrefPMR(psPMRInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntCtxCreate(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE *psDevmemIntCtxCreateIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE *psDevmemIntCtxCreateOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       DEVMEMINT_CTX * psDevMemServerContextInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+
+
+       psDevmemIntCtxCreateOUT->hDevMemServerContext = IMG_NULL;
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntCtxCreateOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psDevmemIntCtxCreateIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntCtxCreate_exit;
+                                       }
+                               }
+
+
+       psDevmemIntCtxCreateOUT->eError =
+               DevmemIntCtxCreate(
+                                       hDeviceNodeInt,
+                                       &psDevMemServerContextInt,
+                                       &hPrivDataInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxCreate_exit;
+       }
+
+
+       psDevmemIntCtxCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntCtxCreateOUT->hDevMemServerContext,
+                                                       (IMG_VOID *) psDevMemServerContextInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntCtxDestroy);
+       if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxCreate_exit;
+       }
+
+
+       psDevmemIntCtxCreateOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntCtxCreateOUT->hPrivData,
+                                                       (IMG_VOID *) hPrivDataInt,
+                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,psDevmemIntCtxCreateOUT->hDevMemServerContext);
+       if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntCtxCreate_exit;
+       }
+
+
+
+
+DevmemIntCtxCreate_exit:
+       if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
+       {
+               if (psDevmemIntCtxCreateOUT->hDevMemServerContext)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               (IMG_HANDLE) psDevmemIntCtxCreateOUT->hDevMemServerContext,
+                                               PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psDevMemServerContextInt = IMG_NULL;
+               }
+
+
+               if (psDevMemServerContextInt)
+               {
+                       DevmemIntCtxDestroy(psDevMemServerContextInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntCtxDestroy(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY *psDevmemIntCtxDestroyIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY *psDevmemIntCtxDestroyOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psDevmemIntCtxDestroyOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psDevmemIntCtxDestroyIN->hDevmemServerContext,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+       if ((psDevmemIntCtxDestroyOUT->eError != PVRSRV_OK) && (psDevmemIntCtxDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto DevmemIntCtxDestroy_exit;
+       }
+
+
+
+DevmemIntCtxDestroy_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntHeapCreate(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX * psDevmemCtxInt = IMG_NULL;
+       DEVMEMINT_HEAP * psDevmemHeapPtrInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntHeapCreateOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemCtxInt,
+                                                                                       psDevmemIntHeapCreateIN->hDevmemCtx,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+                                       if(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntHeapCreate_exit;
+                                       }
+                               }
+
+
+       psDevmemIntHeapCreateOUT->eError =
+               DevmemIntHeapCreate(
+                                       psDevmemCtxInt,
+                                       psDevmemIntHeapCreateIN->sHeapBaseAddr,
+                                       psDevmemIntHeapCreateIN->uiHeapLength,
+                                       psDevmemIntHeapCreateIN->ui32Log2DataPageSize,
+                                       &psDevmemHeapPtrInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntHeapCreate_exit;
+       }
+
+
+       psDevmemIntHeapCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntHeapCreateOUT->hDevmemHeapPtr,
+                                                       (IMG_VOID *) psDevmemHeapPtrInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntHeapDestroy);
+       if (psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntHeapCreate_exit;
+       }
+
+
+
+
+DevmemIntHeapCreate_exit:
+       if (psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
+       {
+               if (psDevmemHeapPtrInt)
+               {
+                       DevmemIntHeapDestroy(psDevmemHeapPtrInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntHeapDestroy(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY *psDevmemIntHeapDestroyIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY *psDevmemIntHeapDestroyOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psDevmemIntHeapDestroyOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psDevmemIntHeapDestroyIN->hDevmemHeap,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+       if ((psDevmemIntHeapDestroyOUT->eError != PVRSRV_OK) && (psDevmemIntHeapDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto DevmemIntHeapDestroy_exit;
+       }
+
+
+
+DevmemIntHeapDestroy_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntMapPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR *psDevmemIntMapPMRIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR *psDevmemIntMapPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_HEAP * psDevmemServerHeapInt = IMG_NULL;
+       DEVMEMINT_RESERVATION * psReservationInt = IMG_NULL;
+       PMR * psPMRInt = IMG_NULL;
+       DEVMEMINT_MAPPING * psMappingInt = IMG_NULL;
+
+
+
+
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntMapPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemServerHeapInt,
+                                                                                       psDevmemIntMapPMRIN->hDevmemServerHeap,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+                                       if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto DevmemIntMapPMR_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntMapPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psReservationInt,
+                                                                                       psDevmemIntMapPMRIN->hReservation,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+                                       if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto DevmemIntMapPMR_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntMapPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psDevmemIntMapPMRIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto DevmemIntMapPMR_exit;
+                                       }
+                               }
+
+
+       psDevmemIntMapPMROUT->eError =
+               DevmemIntMapPMR(
+                                       psDevmemServerHeapInt,
+                                       psReservationInt,
+                                       psPMRInt,
+                                       psDevmemIntMapPMRIN->uiMapFlags,
+                                       &psMappingInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto DevmemIntMapPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psDevmemIntMapPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntMapPMROUT->hMapping,
+                                                       (IMG_VOID *) psMappingInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntUnmapPMR);
+       if (psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntMapPMR_exit;
+       }
+
+
+
+
+DevmemIntMapPMR_exit:
+       if (psDevmemIntMapPMROUT->eError != PVRSRV_OK)
+       {
+               if (psMappingInt)
+               {
+                       DevmemIntUnmapPMR(psMappingInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntUnmapPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR *psDevmemIntUnmapPMRIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR *psDevmemIntUnmapPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+       PMRLock();
+
+
+
+
+       psDevmemIntUnmapPMROUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psDevmemIntUnmapPMRIN->hMapping,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
+       if ((psDevmemIntUnmapPMROUT->eError != PVRSRV_OK) && (psDevmemIntUnmapPMROUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               PMRUnlock();
+               goto DevmemIntUnmapPMR_exit;
+       }
+
+       PMRUnlock();
+
+
+DevmemIntUnmapPMR_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntReserveRange(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_HEAP * psDevmemServerHeapInt = IMG_NULL;
+       DEVMEMINT_RESERVATION * psReservationInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntReserveRangeOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemServerHeapInt,
+                                                                                       psDevmemIntReserveRangeIN->hDevmemServerHeap,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+                                       if(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntReserveRange_exit;
+                                       }
+                               }
+
+
+       psDevmemIntReserveRangeOUT->eError =
+               DevmemIntReserveRange(
+                                       psDevmemServerHeapInt,
+                                       psDevmemIntReserveRangeIN->sAddress,
+                                       psDevmemIntReserveRangeIN->uiLength,
+                                       &psReservationInt);
+       /* Exit early if bridged call fails */
+       if(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntReserveRange_exit;
+       }
+
+
+       psDevmemIntReserveRangeOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psDevmemIntReserveRangeOUT->hReservation,
+                                                       (IMG_VOID *) psReservationInt,
+                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&DevmemIntUnreserveRange);
+       if (psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
+       {
+               goto DevmemIntReserveRange_exit;
+       }
+
+
+
+
+DevmemIntReserveRange_exit:
+       if (psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
+       {
+               if (psReservationInt)
+               {
+                       DevmemIntUnreserveRange(psReservationInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntUnreserveRange(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE *psDevmemIntUnreserveRangeIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE *psDevmemIntUnreserveRangeOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psDevmemIntUnreserveRangeOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psDevmemIntUnreserveRangeIN->hReservation,
+                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+       if ((psDevmemIntUnreserveRangeOUT->eError != PVRSRV_OK) && (psDevmemIntUnreserveRangeOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto DevmemIntUnreserveRange_exit;
+       }
+
+
+
+DevmemIntUnreserveRange_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePhysmemNewRamBackedPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR *psPhysmemNewRamBackedPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR *psPhysmemNewRamBackedPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       IMG_BOOL *bMappingTableInt = IMG_NULL;
+       PMR * psPMRPtrInt = IMG_NULL;
+
+
+
+
+       if (psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks != 0)
+       {
+               bMappingTableInt = OSAllocMem(psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks * sizeof(IMG_BOOL));
+               if (!bMappingTableInt)
+               {
+                       psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto PhysmemNewRamBackedPMR_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPhysmemNewRamBackedPMRIN->pbMappingTable, psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks * sizeof(IMG_BOOL))
+                               || (OSCopyFromUser(NULL, bMappingTableInt, psPhysmemNewRamBackedPMRIN->pbMappingTable,
+                               psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks * sizeof(IMG_BOOL)) != PVRSRV_OK) )
+                       {
+                               psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto PhysmemNewRamBackedPMR_exit;
+                       }
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPhysmemNewRamBackedPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psPhysmemNewRamBackedPMRIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PhysmemNewRamBackedPMR_exit;
+                                       }
+                               }
+
+
+       psPhysmemNewRamBackedPMROUT->eError =
+               PhysmemNewRamBackedPMR(
+                                       hDeviceNodeInt,
+                                       psPhysmemNewRamBackedPMRIN->uiSize,
+                                       psPhysmemNewRamBackedPMRIN->uiChunkSize,
+                                       psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks,
+                                       psPhysmemNewRamBackedPMRIN->ui32NumVirtChunks,
+                                       bMappingTableInt,
+                                       psPhysmemNewRamBackedPMRIN->ui32Log2PageSize,
+                                       psPhysmemNewRamBackedPMRIN->uiFlags,
+                                       &psPMRPtrInt);
+       /* Exit early if bridged call fails */
+       if(psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PhysmemNewRamBackedPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psPhysmemNewRamBackedPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPhysmemNewRamBackedPMROUT->hPMRPtr,
+                                                       (IMG_VOID *) psPMRPtrInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
+       {
+               goto PhysmemNewRamBackedPMR_exit;
+       }
+
+
+
+
+PhysmemNewRamBackedPMR_exit:
+       if (psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMRPtrInt)
+               {
+                       PMRUnrefPMR(psPMRPtrInt);
+               }
+       }
+
+       if (bMappingTableInt)
+               OSFreeMem(bMappingTableInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRLocalImportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR *psPMRLocalImportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR *psPMRLocalImportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psExtHandleInt = IMG_NULL;
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRLocalImportPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psExtHandleInt,
+                                                                                       psPMRLocalImportPMRIN->hExtHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT);
+                                       if(psPMRLocalImportPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PMRLocalImportPMR_exit;
+                                       }
+                               }
+
+
+       psPMRLocalImportPMROUT->eError =
+               PMRLocalImportPMR(
+                                       psExtHandleInt,
+                                       &psPMRInt,
+                                       &psPMRLocalImportPMROUT->uiSize,
+                                       &psPMRLocalImportPMROUT->sAlign);
+       /* Exit early if bridged call fails */
+       if(psPMRLocalImportPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PMRLocalImportPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psPMRLocalImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPMRLocalImportPMROUT->hPMR,
+                                                       (IMG_VOID *) psPMRInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPMRLocalImportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRLocalImportPMR_exit;
+       }
+
+
+
+
+PMRLocalImportPMR_exit:
+       if (psPMRLocalImportPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMRInt)
+               {
+                       PMRUnrefPMR(psPMRInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRUnrefPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRUNREFPMR *psPMRUnrefPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRUNREFPMR *psPMRUnrefPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+       PMRLock();
+
+
+
+
+       psPMRUnrefPMROUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psPMRUnrefPMRIN->hPMR,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+       if ((psPMRUnrefPMROUT->eError != PVRSRV_OK) && (psPMRUnrefPMROUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               PMRUnlock();
+               goto PMRUnrefPMR_exit;
+       }
+
+       PMRUnlock();
+
+
+PMRUnrefPMR_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemSLCFlushInvalRequest(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST *psDevmemSLCFlushInvalRequestIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST *psDevmemSLCFlushInvalRequestOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       PMR * psPmrInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemSLCFlushInvalRequestOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psDevmemSLCFlushInvalRequestIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psDevmemSLCFlushInvalRequestOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemSLCFlushInvalRequest_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemSLCFlushInvalRequestOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPmrInt,
+                                                                                       psDevmemSLCFlushInvalRequestIN->hPmr,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psDevmemSLCFlushInvalRequestOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemSLCFlushInvalRequest_exit;
+                                       }
+                               }
+
+
+       psDevmemSLCFlushInvalRequestOUT->eError =
+               DevmemSLCFlushInvalRequest(
+                                       hDeviceNodeInt,
+                                       psPmrInt);
+
+
+
+
+DevmemSLCFlushInvalRequest_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIsVDevAddrValid(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX * psDevmemCtxInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIsVDevAddrValidOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemCtxInt,
+                                                                                       psDevmemIsVDevAddrValidIN->hDevmemCtx,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+                                       if(psDevmemIsVDevAddrValidOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIsVDevAddrValid_exit;
+                                       }
+                               }
+
+
+       psDevmemIsVDevAddrValidOUT->eError =
+               DevmemIntIsVDevAddrValid(
+                                       psDevmemCtxInt,
+                                       psDevmemIsVDevAddrValidIN->sAddress);
+
+
+
+
+DevmemIsVDevAddrValid_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeHeapCfgHeapConfigCount(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT *psHeapCfgHeapConfigCountIN,
+                                         PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT *psHeapCfgHeapConfigCountOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psHeapCfgHeapConfigCountOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psHeapCfgHeapConfigCountIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psHeapCfgHeapConfigCountOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto HeapCfgHeapConfigCount_exit;
+                                       }
+                               }
+
+
+       psHeapCfgHeapConfigCountOUT->eError =
+               HeapCfgHeapConfigCount(
+                                       hDeviceNodeInt,
+                                       &psHeapCfgHeapConfigCountOUT->ui32NumHeapConfigs);
+
+
+
+
+HeapCfgHeapConfigCount_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeHeapCfgHeapCount(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT *psHeapCfgHeapCountIN,
+                                         PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT *psHeapCfgHeapCountOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psHeapCfgHeapCountOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psHeapCfgHeapCountIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psHeapCfgHeapCountOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto HeapCfgHeapCount_exit;
+                                       }
+                               }
+
+
+       psHeapCfgHeapCountOUT->eError =
+               HeapCfgHeapCount(
+                                       hDeviceNodeInt,
+                                       psHeapCfgHeapCountIN->ui32HeapConfigIndex,
+                                       &psHeapCfgHeapCountOUT->ui32NumHeaps);
+
+
+
+
+HeapCfgHeapCount_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeHeapCfgHeapConfigName(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME *psHeapCfgHeapConfigNameIN,
+                                         PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME *psHeapCfgHeapConfigNameOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       IMG_CHAR *puiHeapConfigNameInt = IMG_NULL;
+
+
+       psHeapCfgHeapConfigNameOUT->puiHeapConfigName = psHeapCfgHeapConfigNameIN->puiHeapConfigName;
+
+
+       if (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz != 0)
+       {
+               puiHeapConfigNameInt = OSAllocMem(psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR));
+               if (!puiHeapConfigNameInt)
+               {
+                       psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto HeapCfgHeapConfigName_exit;
+               }
+       }
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psHeapCfgHeapConfigNameOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psHeapCfgHeapConfigNameIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psHeapCfgHeapConfigNameOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto HeapCfgHeapConfigName_exit;
+                                       }
+                               }
+
+
+       psHeapCfgHeapConfigNameOUT->eError =
+               HeapCfgHeapConfigName(
+                                       hDeviceNodeInt,
+                                       psHeapCfgHeapConfigNameIN->ui32HeapConfigIndex,
+                                       psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz,
+                                       puiHeapConfigNameInt);
+
+
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psHeapCfgHeapConfigNameOUT->puiHeapConfigName, (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR))) 
+               || (OSCopyToUser(NULL, psHeapCfgHeapConfigNameOUT->puiHeapConfigName, puiHeapConfigNameInt,
+               (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+       {
+               psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto HeapCfgHeapConfigName_exit;
+       }
+
+
+HeapCfgHeapConfigName_exit:
+       if (puiHeapConfigNameInt)
+               OSFreeMem(puiHeapConfigNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeHeapCfgHeapDetails(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS *psHeapCfgHeapDetailsIN,
+                                         PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS *psHeapCfgHeapDetailsOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       IMG_CHAR *puiHeapNameOutInt = IMG_NULL;
+
+
+       psHeapCfgHeapDetailsOUT->puiHeapNameOut = psHeapCfgHeapDetailsIN->puiHeapNameOut;
+
+
+       if (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz != 0)
+       {
+               puiHeapNameOutInt = OSAllocMem(psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR));
+               if (!puiHeapNameOutInt)
+               {
+                       psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto HeapCfgHeapDetails_exit;
+               }
+       }
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psHeapCfgHeapDetailsOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psHeapCfgHeapDetailsIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psHeapCfgHeapDetailsOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto HeapCfgHeapDetails_exit;
+                                       }
+                               }
+
+
+       psHeapCfgHeapDetailsOUT->eError =
+               HeapCfgHeapDetails(
+                                       hDeviceNodeInt,
+                                       psHeapCfgHeapDetailsIN->ui32HeapConfigIndex,
+                                       psHeapCfgHeapDetailsIN->ui32HeapIndex,
+                                       psHeapCfgHeapDetailsIN->ui32HeapNameBufSz,
+                                       puiHeapNameOutInt,
+                                       &psHeapCfgHeapDetailsOUT->sDevVAddrBase,
+                                       &psHeapCfgHeapDetailsOUT->uiHeapLength,
+                                       &psHeapCfgHeapDetailsOUT->ui32Log2DataPageSizeOut,
+                                       &psHeapCfgHeapDetailsOUT->ui32Log2ImportAlignmentOut);
+
+
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psHeapCfgHeapDetailsOUT->puiHeapNameOut, (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR))) 
+               || (OSCopyToUser(NULL, psHeapCfgHeapDetailsOUT->puiHeapNameOut, puiHeapNameOutInt,
+               (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+       {
+               psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto HeapCfgHeapDetails_exit;
+       }
+
+
+HeapCfgHeapDetails_exit:
+       if (puiHeapNameOutInt)
+               OSFreeMem(puiHeapNameOutInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitMMBridge(IMG_VOID);
+PVRSRV_ERROR DeinitMMBridge(IMG_VOID);
+
+/*
+ * Register all MM functions with services
+ */
+PVRSRV_ERROR InitMMBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMREXPORTPMR, PVRSRVBridgePMRExportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR, PVRSRVBridgePMRUnexportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRGETUID, PVRSRVBridgePMRGetUID,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRMAKESERVEREXPORTCLIENTEXPORT, PVRSRVBridgePMRMakeServerExportClientExport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNMAKESERVEREXPORTCLIENTEXPORT, PVRSRVBridgePMRUnmakeServerExportClientExport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRIMPORTPMR, PVRSRVBridgePMRImportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE, PVRSRVBridgeDevmemIntCtxCreate,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY, PVRSRVBridgeDevmemIntCtxDestroy,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE, PVRSRVBridgeDevmemIntHeapCreate,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY, PVRSRVBridgeDevmemIntHeapDestroy,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR, PVRSRVBridgeDevmemIntMapPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR, PVRSRVBridgeDevmemIntUnmapPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE, PVRSRVBridgeDevmemIntReserveRange,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE, PVRSRVBridgeDevmemIntUnreserveRange,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR, PVRSRVBridgePhysmemNewRamBackedPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR, PVRSRVBridgePMRLocalImportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_PMRUNREFPMR, PVRSRVBridgePMRUnrefPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMSLCFLUSHINVALREQUEST, PVRSRVBridgeDevmemSLCFlushInvalRequest,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID, PVRSRVBridgeDevmemIsVDevAddrValid,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT, PVRSRVBridgeHeapCfgHeapConfigCount,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT, PVRSRVBridgeHeapCfgHeapCount,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME, PVRSRVBridgeHeapCfgHeapConfigName,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS, PVRSRVBridgeHeapCfgHeapDetails,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all mm functions with services
+ */
+PVRSRV_ERROR DeinitMMBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/pdump_bridge/common_pdump_bridge.h b/drivers/gpu/rogue_m/generated/pdump_bridge/common_pdump_bridge.h
new file mode 100644 (file)
index 0000000..816c04c
--- /dev/null
@@ -0,0 +1,125 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for pdump
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for pdump
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_PDUMP_BRIDGE_H
+#define COMMON_PDUMP_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "pdumpdefs.h"
+
+
+#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST                  0
+#define PVRSRV_BRIDGE_PDUMP_DEVMEMPDUMPBITMAP                  PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0
+#define PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPCOMMENT                 PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1
+#define PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPSETFRAME                        PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST                   (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2)
+
+
+/*******************************************
+            DevmemPDumpBitmap          
+ *******************************************/
+
+/* Bridge in structure for DevmemPDumpBitmap */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMPDUMPBITMAP_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_CHAR * puiFileName;
+       IMG_UINT32 ui32FileOffset;
+       IMG_UINT32 ui32Width;
+       IMG_UINT32 ui32Height;
+       IMG_UINT32 ui32StrideInBytes;
+       IMG_DEV_VIRTADDR sDevBaseAddr;
+       IMG_HANDLE hDevmemCtx;
+       IMG_UINT32 ui32Size;
+       PDUMP_PIXEL_FORMAT ePixelFormat;
+       IMG_UINT32 ui32AddrMode;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMPDUMPBITMAP;
+
+
+/* Bridge out structure for DevmemPDumpBitmap */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMPDUMPBITMAP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMPDUMPBITMAP;
+
+/*******************************************
+            PVRSRVPDumpComment          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpComment */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT_TAG
+{
+       IMG_CHAR * puiComment;
+       IMG_UINT32 ui32Flags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT;
+
+
+/* Bridge out structure for PVRSRVPDumpComment */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT;
+
+/*******************************************
+            PVRSRVPDumpSetFrame          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpSetFrame */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME_TAG
+{
+       IMG_UINT32 ui32Frame;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME;
+
+
+/* Bridge out structure for PVRSRVPDumpSetFrame */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME;
+
+#endif /* COMMON_PDUMP_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pdump_bridge/server_pdump_bridge.c b/drivers/gpu/rogue_m/generated/pdump_bridge/server_pdump_bridge.c
new file mode 100644 (file)
index 0000000..1454dd9
--- /dev/null
@@ -0,0 +1,278 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for pdump
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for pdump
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "devicemem_server.h"
+#include "pdump_km.h"
+
+
+#include "common_pdump_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeDevmemPDumpBitmap(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMPDUMPBITMAP *psDevmemPDumpBitmapIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMPDUMPBITMAP *psDevmemPDumpBitmapOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+       IMG_CHAR *uiFileNameInt = IMG_NULL;
+       DEVMEMINT_CTX * psDevmemCtxInt = IMG_NULL;
+
+
+
+
+       
+       {
+               uiFileNameInt = OSAllocMem(PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR));
+               if (!uiFileNameInt)
+               {
+                       psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto DevmemPDumpBitmap_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevmemPDumpBitmapIN->puiFileName, PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiFileNameInt, psDevmemPDumpBitmapIN->puiFileName,
+                               PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto DevmemPDumpBitmap_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemPDumpBitmapOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psDevmemPDumpBitmapIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psDevmemPDumpBitmapOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemPDumpBitmap_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemPDumpBitmapOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemCtxInt,
+                                                                                       psDevmemPDumpBitmapIN->hDevmemCtx,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+                                       if(psDevmemPDumpBitmapOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemPDumpBitmap_exit;
+                                       }
+                               }
+
+
+       psDevmemPDumpBitmapOUT->eError =
+               DevmemIntPDumpBitmap(
+                                       hDeviceNodeInt,
+                                       uiFileNameInt,
+                                       psDevmemPDumpBitmapIN->ui32FileOffset,
+                                       psDevmemPDumpBitmapIN->ui32Width,
+                                       psDevmemPDumpBitmapIN->ui32Height,
+                                       psDevmemPDumpBitmapIN->ui32StrideInBytes,
+                                       psDevmemPDumpBitmapIN->sDevBaseAddr,
+                                       psDevmemCtxInt,
+                                       psDevmemPDumpBitmapIN->ui32Size,
+                                       psDevmemPDumpBitmapIN->ePixelFormat,
+                                       psDevmemPDumpBitmapIN->ui32AddrMode,
+                                       psDevmemPDumpBitmapIN->ui32PDumpFlags);
+
+
+
+
+DevmemPDumpBitmap_exit:
+       if (uiFileNameInt)
+               OSFreeMem(uiFileNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpComment(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT *psPVRSRVPDumpCommentIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPCOMMENT *psPVRSRVPDumpCommentOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_CHAR *uiCommentInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+       
+       {
+               uiCommentInt = OSAllocMem(PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR));
+               if (!uiCommentInt)
+               {
+                       psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto PVRSRVPDumpComment_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPVRSRVPDumpCommentIN->puiComment, PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiCommentInt, psPVRSRVPDumpCommentIN->puiComment,
+                               PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto PVRSRVPDumpComment_exit;
+                       }
+
+
+
+       psPVRSRVPDumpCommentOUT->eError =
+               PDumpCommentKM(
+                                       uiCommentInt,
+                                       psPVRSRVPDumpCommentIN->ui32Flags);
+
+
+
+
+PVRSRVPDumpComment_exit:
+       if (uiCommentInt)
+               OSFreeMem(uiCommentInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpSetFrame(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME *psPVRSRVPDumpSetFrameIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETFRAME *psPVRSRVPDumpSetFrameOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+       psPVRSRVPDumpSetFrameOUT->eError =
+               PDumpSetFrameKM(psConnection,
+                                       psPVRSRVPDumpSetFrameIN->ui32Frame);
+
+
+
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitPDUMPBridge(IMG_VOID);
+PVRSRV_ERROR DeinitPDUMPBridge(IMG_VOID);
+
+/*
+ * Register all PDUMP functions with services
+ */
+PVRSRV_ERROR InitPDUMPBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_DEVMEMPDUMPBITMAP, PVRSRVBridgeDevmemPDumpBitmap,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPCOMMENT, PVRSRVBridgePVRSRVPDumpComment,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP, PVRSRV_BRIDGE_PDUMP_PVRSRVPDUMPSETFRAME, PVRSRVBridgePVRSRVPDumpSetFrame,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all pdump functions with services
+ */
+PVRSRV_ERROR DeinitPDUMPBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h b/drivers/gpu/rogue_m/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h
new file mode 100644 (file)
index 0000000..227bca3
--- /dev/null
@@ -0,0 +1,172 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for pdumpctrl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for pdumpctrl
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_PDUMPCTRL_BRIDGE_H
+#define COMMON_PDUMPCTRL_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "services.h"
+
+
+#define PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST                      0
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISCAPTURING                 PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+0
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETFRAME                    PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+1
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS                     PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+2
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISLASTCAPTUREFRAME                  PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+3
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSTARTINITPHASE                      PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+4
+#define PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSTOPINITPHASE                       PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+5
+#define PVRSRV_BRIDGE_PDUMPCTRL_CMD_LAST                       (PVRSRV_BRIDGE_PDUMPCTRL_CMD_FIRST+5)
+
+
+/*******************************************
+            PVRSRVPDumpIsCapturing          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpIsCapturing */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPISCAPTURING_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPISCAPTURING;
+
+
+/* Bridge out structure for PVRSRVPDumpIsCapturing */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISCAPTURING_TAG
+{
+       IMG_BOOL bIsCapturing;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISCAPTURING;
+
+/*******************************************
+            PVRSRVPDumpGetFrame          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpGetFrame */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME;
+
+
+/* Bridge out structure for PVRSRVPDumpGetFrame */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME_TAG
+{
+       IMG_UINT32 ui32Frame;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME;
+
+/*******************************************
+            PVRSRVPDumpSetDefaultCaptureParams          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpSetDefaultCaptureParams */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS_TAG
+{
+       IMG_UINT32 ui32Mode;
+       IMG_UINT32 ui32Start;
+       IMG_UINT32 ui32End;
+       IMG_UINT32 ui32Interval;
+       IMG_UINT32 ui32MaxParamFileSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS;
+
+
+/* Bridge out structure for PVRSRVPDumpSetDefaultCaptureParams */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS;
+
+/*******************************************
+            PVRSRVPDumpIsLastCaptureFrame          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpIsLastCaptureFrame */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME;
+
+
+/* Bridge out structure for PVRSRVPDumpIsLastCaptureFrame */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME;
+
+/*******************************************
+            PVRSRVPDumpStartInitPhase          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpStartInitPhase */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTARTINITPHASE_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTARTINITPHASE;
+
+
+/* Bridge out structure for PVRSRVPDumpStartInitPhase */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTARTINITPHASE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTARTINITPHASE;
+
+/*******************************************
+            PVRSRVPDumpStopInitPhase          
+ *******************************************/
+
+/* Bridge in structure for PVRSRVPDumpStopInitPhase */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTOPINITPHASE_TAG
+{
+       IMG_MODULE_ID eModuleID;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTOPINITPHASE;
+
+
+/* Bridge out structure for PVRSRVPDumpStopInitPhase */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTOPINITPHASE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTOPINITPHASE;
+
+#endif /* COMMON_PDUMPCTRL_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c b/drivers/gpu/rogue_m/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c
new file mode 100644 (file)
index 0000000..19bd010
--- /dev/null
@@ -0,0 +1,288 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for pdumpctrl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for pdumpctrl
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "pdump_km.h"
+
+
+#include "common_pdumpctrl_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+#include "lock.h"
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpIsCapturing(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPISCAPTURING *psPVRSRVPDumpIsCapturingIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISCAPTURING *psPVRSRVPDumpIsCapturingOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpIsCapturingIN);
+
+
+
+
+
+
+       psPVRSRVPDumpIsCapturingOUT->eError =
+               PDumpIsCaptureFrameKM(
+                                       &psPVRSRVPDumpIsCapturingOUT->bIsCapturing);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpGetFrame(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME *psPVRSRVPDumpGetFrameIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPGETFRAME *psPVRSRVPDumpGetFrameOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpGetFrameIN);
+
+
+
+
+
+
+       psPVRSRVPDumpGetFrameOUT->eError =
+               PDumpGetFrameKM(psConnection,
+                                       &psPVRSRVPDumpGetFrameOUT->ui32Frame);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpSetDefaultCaptureParams(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *psPVRSRVPDumpSetDefaultCaptureParamsIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *psPVRSRVPDumpSetDefaultCaptureParamsOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+       psPVRSRVPDumpSetDefaultCaptureParamsOUT->eError =
+               PDumpSetDefaultCaptureParamsKM(
+                                       psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Mode,
+                                       psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Start,
+                                       psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32End,
+                                       psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32Interval,
+                                       psPVRSRVPDumpSetDefaultCaptureParamsIN->ui32MaxParamFileSize);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpIsLastCaptureFrame(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME *psPVRSRVPDumpIsLastCaptureFrameIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME *psPVRSRVPDumpIsLastCaptureFrameOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpIsLastCaptureFrameIN);
+
+
+
+
+
+
+       psPVRSRVPDumpIsLastCaptureFrameOUT->eError =
+               PDumpIsLastCaptureFrameKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpStartInitPhase(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTARTINITPHASE *psPVRSRVPDumpStartInitPhaseIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTARTINITPHASE *psPVRSRVPDumpStartInitPhaseOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpStartInitPhaseIN);
+
+
+
+
+
+
+       psPVRSRVPDumpStartInitPhaseOUT->eError =
+               PDumpStartInitPhaseKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePVRSRVPDumpStopInitPhase(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PVRSRVPDUMPSTOPINITPHASE *psPVRSRVPDumpStopInitPhaseIN,
+                                         PVRSRV_BRIDGE_OUT_PVRSRVPDUMPSTOPINITPHASE *psPVRSRVPDumpStopInitPhaseOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+       psPVRSRVPDumpStopInitPhaseOUT->eError =
+               PDumpStopInitPhaseKM(
+                                       psPVRSRVPDumpStopInitPhaseIN->eModuleID);
+
+
+
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static POS_LOCK pPDUMPCTRLBridgeLock;
+static IMG_BYTE pbyPDUMPCTRLBridgeBuffer[20 +  8];
+
+PVRSRV_ERROR InitPDUMPCTRLBridge(IMG_VOID);
+PVRSRV_ERROR DeinitPDUMPCTRLBridge(IMG_VOID);
+
+/*
+ * Register all PDUMPCTRL functions with services
+ */
+PVRSRV_ERROR InitPDUMPCTRLBridge(IMG_VOID)
+{
+       PVR_LOGR_IF_ERROR(OSLockCreate(&pPDUMPCTRLBridgeLock, LOCK_TYPE_PASSIVE), "OSLockCreate");
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISCAPTURING, PVRSRVBridgePVRSRVPDumpIsCapturing,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPGETFRAME, PVRSRVBridgePVRSRVPDumpGetFrame,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS, PVRSRVBridgePVRSRVPDumpSetDefaultCaptureParams,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPISLASTCAPTUREFRAME, PVRSRVBridgePVRSRVPDumpIsLastCaptureFrame,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSTARTINITPHASE, PVRSRVBridgePVRSRVPDumpStartInitPhase,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPCTRL, PVRSRV_BRIDGE_PDUMPCTRL_PVRSRVPDUMPSTOPINITPHASE, PVRSRVBridgePVRSRVPDumpStopInitPhase,
+                                       pPDUMPCTRLBridgeLock, pbyPDUMPCTRLBridgeBuffer,
+                                       20,  8);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all pdumpctrl functions with services
+ */
+PVRSRV_ERROR DeinitPDUMPCTRLBridge(IMG_VOID)
+{
+       PVR_LOGR_IF_ERROR(OSLockDestroy(pPDUMPCTRLBridgeLock), "OSLockDestroy");
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/pdumpmm_bridge/client_pdumpmm_bridge.h b/drivers/gpu/rogue_m/generated/pdumpmm_bridge/client_pdumpmm_bridge.h
new file mode 100644 (file)
index 0000000..fdcabc8
--- /dev/null
@@ -0,0 +1,113 @@
+/*************************************************************************/ /*!
+@File
+@Title          Client bridge header for pdumpmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exports the client bridge functions for pdumpmm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_PDUMPMM_BRIDGE_H
+#define CLIENT_PDUMPMM_BRIDGE_H
+
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+
+#include "common_pdumpmm_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMem(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hPMR,
+                                                            IMG_DEVMEM_OFFSET_T uiOffset,
+                                                            IMG_DEVMEM_SIZE_T uiSize,
+                                                            IMG_UINT32 ui32PDumpFlags,
+                                                            IMG_BOOL bbZero);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMemValue32(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hPMR,
+                                                                   IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                   IMG_UINT32 ui32Value,
+                                                                   IMG_UINT32 ui32PDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpLoadMemValue64(IMG_HANDLE hBridge,
+                                                                   IMG_HANDLE hPMR,
+                                                                   IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                   IMG_UINT64 ui64Value,
+                                                                   IMG_UINT32 ui32PDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpSaveToFile(IMG_HANDLE hBridge,
+                                                               IMG_HANDLE hPMR,
+                                                               IMG_DEVMEM_OFFSET_T uiOffset,
+                                                               IMG_DEVMEM_SIZE_T uiSize,
+                                                               IMG_UINT32 ui32ArraySize,
+                                                               const IMG_CHAR *puiFileName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpSymbolicAddr(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hPMR,
+                                                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                 IMG_UINT32 ui32MemspaceNameLen,
+                                                                 IMG_CHAR *puiMemspaceName,
+                                                                 IMG_UINT32 ui32SymbolicAddrLen,
+                                                                 IMG_CHAR *puiSymbolicAddr,
+                                                                 IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                                                                 IMG_DEVMEM_OFFSET_T *puiNextSymName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpPol32(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hPMR,
+                                                          IMG_DEVMEM_OFFSET_T uiOffset,
+                                                          IMG_UINT32 ui32Value,
+                                                          IMG_UINT32 ui32Mask,
+                                                          PDUMP_POLL_OPERATOR eOperator,
+                                                          IMG_UINT32 ui32PDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePMRPDumpCBP(IMG_HANDLE hBridge,
+                                                        IMG_HANDLE hPMR,
+                                                        IMG_DEVMEM_OFFSET_T uiReadOffset,
+                                                        IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                                                        IMG_DEVMEM_SIZE_T uiPacketSize,
+                                                        IMG_DEVMEM_SIZE_T uiBufferSize);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntPDumpSaveToFileVirtual(IMG_HANDLE hBridge,
+                                                                            IMG_HANDLE hDevmemServerContext,
+                                                                            IMG_DEV_VIRTADDR sAddress,
+                                                                            IMG_DEVMEM_SIZE_T uiSize,
+                                                                            IMG_UINT32 ui32ArraySize,
+                                                                            const IMG_CHAR *puiFileName,
+                                                                            IMG_UINT32 ui32FileOffset,
+                                                                            IMG_UINT32 ui32PDumpFlags);
+
+
+#endif /* CLIENT_PDUMPMM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pdumpmm_bridge/common_pdumpmm_bridge.h b/drivers/gpu/rogue_m/generated/pdumpmm_bridge/common_pdumpmm_bridge.h
new file mode 100644 (file)
index 0000000..8aa4862
--- /dev/null
@@ -0,0 +1,245 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for pdumpmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for pdumpmm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_PDUMPMM_BRIDGE_H
+#define COMMON_PDUMPMM_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST                        0
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEM                  PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE32                   PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE64                   PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSAVETOFILE                       PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+3
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSYMBOLICADDR                     PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+4
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPPOL32                    PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+5
+#define PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCBP                      PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+6
+#define PVRSRV_BRIDGE_PDUMPMM_DEVMEMINTPDUMPSAVETOFILEVIRTUAL                  PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+7
+#define PVRSRV_BRIDGE_PDUMPMM_CMD_LAST                 (PVRSRV_BRIDGE_PDUMPMM_CMD_FIRST+7)
+
+
+/*******************************************
+            PMRPDumpLoadMem          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpLoadMem */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_UINT32 ui32PDumpFlags;
+       IMG_BOOL bbZero;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM;
+
+
+/* Bridge out structure for PMRPDumpLoadMem */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM;
+
+/*******************************************
+            PMRPDumpLoadMemValue32          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpLoadMemValue32 */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_UINT32 ui32Value;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32;
+
+
+/* Bridge out structure for PMRPDumpLoadMemValue32 */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32;
+
+/*******************************************
+            PMRPDumpLoadMemValue64          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpLoadMemValue64 */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_UINT64 ui64Value;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64;
+
+
+/* Bridge out structure for PMRPDumpLoadMemValue64 */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64;
+
+/*******************************************
+            PMRPDumpSaveToFile          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpSaveToFile */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_UINT32 ui32ArraySize;
+       const IMG_CHAR * puiFileName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE;
+
+
+/* Bridge out structure for PMRPDumpSaveToFile */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE;
+
+/*******************************************
+            PMRPDumpSymbolicAddr          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpSymbolicAddr */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_UINT32 ui32MemspaceNameLen;
+       IMG_UINT32 ui32SymbolicAddrLen;
+       /* Output pointer puiMemspaceName is also an implied input */
+       IMG_CHAR * puiMemspaceName;
+       /* Output pointer puiSymbolicAddr is also an implied input */
+       IMG_CHAR * puiSymbolicAddr;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR;
+
+
+/* Bridge out structure for PMRPDumpSymbolicAddr */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR_TAG
+{
+       IMG_CHAR * puiMemspaceName;
+       IMG_CHAR * puiSymbolicAddr;
+       IMG_DEVMEM_OFFSET_T uiNewOffset;
+       IMG_DEVMEM_OFFSET_T uiNextSymName;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR;
+
+/*******************************************
+            PMRPDumpPol32          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpPol32 */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPPOL32_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_UINT32 ui32Value;
+       IMG_UINT32 ui32Mask;
+       PDUMP_POLL_OPERATOR eOperator;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPPOL32;
+
+
+/* Bridge out structure for PMRPDumpPol32 */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32;
+
+/*******************************************
+            PMRPDumpCBP          
+ *******************************************/
+
+/* Bridge in structure for PMRPDumpCBP */
+typedef struct PVRSRV_BRIDGE_IN_PMRPDUMPCBP_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_OFFSET_T uiReadOffset;
+       IMG_DEVMEM_OFFSET_T uiWriteOffset;
+       IMG_DEVMEM_SIZE_T uiPacketSize;
+       IMG_DEVMEM_SIZE_T uiBufferSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRPDUMPCBP;
+
+
+/* Bridge out structure for PMRPDumpCBP */
+typedef struct PVRSRV_BRIDGE_OUT_PMRPDUMPCBP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRPDUMPCBP;
+
+/*******************************************
+            DevmemIntPDumpSaveToFileVirtual          
+ *******************************************/
+
+/* Bridge in structure for DevmemIntPDumpSaveToFileVirtual */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL_TAG
+{
+       IMG_HANDLE hDevmemServerContext;
+       IMG_DEV_VIRTADDR sAddress;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_UINT32 ui32ArraySize;
+       const IMG_CHAR * puiFileName;
+       IMG_UINT32 ui32FileOffset;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL;
+
+
+/* Bridge out structure for DevmemIntPDumpSaveToFileVirtual */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL;
+
+#endif /* COMMON_PDUMPMM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pdumpmm_bridge/server_pdumpmm_bridge.c b/drivers/gpu/rogue_m/generated/pdumpmm_bridge/server_pdumpmm_bridge.c
new file mode 100644 (file)
index 0000000..4c9e338
--- /dev/null
@@ -0,0 +1,586 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for pdumpmm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for pdumpmm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "devicemem_server.h"
+#include "pmr.h"
+#include "physmem.h"
+
+
+#include "common_pdumpmm_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePMRPDumpLoadMem(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEM *psPMRPDumpLoadMemIN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM *psPMRPDumpLoadMemOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpLoadMemOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpLoadMemIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpLoadMemOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpLoadMem_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpLoadMemOUT->eError =
+               PMRPDumpLoadMem(
+                                       psPMRInt,
+                                       psPMRPDumpLoadMemIN->uiOffset,
+                                       psPMRPDumpLoadMemIN->uiSize,
+                                       psPMRPDumpLoadMemIN->ui32PDumpFlags,
+                                       psPMRPDumpLoadMemIN->bbZero);
+
+
+
+
+PMRPDumpLoadMem_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpLoadMemValue32(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32IN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32OUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpLoadMemValue32OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpLoadMemValue32IN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpLoadMemValue32OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpLoadMemValue32_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpLoadMemValue32OUT->eError =
+               PMRPDumpLoadMemValue32(
+                                       psPMRInt,
+                                       psPMRPDumpLoadMemValue32IN->uiOffset,
+                                       psPMRPDumpLoadMemValue32IN->ui32Value,
+                                       psPMRPDumpLoadMemValue32IN->ui32PDumpFlags);
+
+
+
+
+PMRPDumpLoadMemValue32_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpLoadMemValue64(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64IN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64OUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpLoadMemValue64OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpLoadMemValue64IN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpLoadMemValue64OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpLoadMemValue64_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpLoadMemValue64OUT->eError =
+               PMRPDumpLoadMemValue64(
+                                       psPMRInt,
+                                       psPMRPDumpLoadMemValue64IN->uiOffset,
+                                       psPMRPDumpLoadMemValue64IN->ui64Value,
+                                       psPMRPDumpLoadMemValue64IN->ui32PDumpFlags);
+
+
+
+
+PMRPDumpLoadMemValue64_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpSaveToFile(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileIN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+       IMG_CHAR *uiFileNameInt = IMG_NULL;
+
+
+
+
+       if (psPMRPDumpSaveToFileIN->ui32ArraySize != 0)
+       {
+               uiFileNameInt = OSAllocMem(psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR));
+               if (!uiFileNameInt)
+               {
+                       psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto PMRPDumpSaveToFile_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPMRPDumpSaveToFileIN->puiFileName, psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiFileNameInt, psPMRPDumpSaveToFileIN->puiFileName,
+                               psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto PMRPDumpSaveToFile_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpSaveToFileOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpSaveToFileIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpSaveToFileOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpSaveToFile_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpSaveToFileOUT->eError =
+               PMRPDumpSaveToFile(
+                                       psPMRInt,
+                                       psPMRPDumpSaveToFileIN->uiOffset,
+                                       psPMRPDumpSaveToFileIN->uiSize,
+                                       psPMRPDumpSaveToFileIN->ui32ArraySize,
+                                       uiFileNameInt);
+
+
+
+
+PMRPDumpSaveToFile_exit:
+       if (uiFileNameInt)
+               OSFreeMem(uiFileNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpSymbolicAddr(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrIN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+       IMG_CHAR *puiMemspaceNameInt = IMG_NULL;
+       IMG_CHAR *puiSymbolicAddrInt = IMG_NULL;
+
+
+       psPMRPDumpSymbolicAddrOUT->puiMemspaceName = psPMRPDumpSymbolicAddrIN->puiMemspaceName;
+       psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr = psPMRPDumpSymbolicAddrIN->puiSymbolicAddr;
+
+
+       if (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen != 0)
+       {
+               puiMemspaceNameInt = OSAllocMem(psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR));
+               if (!puiMemspaceNameInt)
+               {
+                       psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto PMRPDumpSymbolicAddr_exit;
+               }
+       }
+
+       if (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen != 0)
+       {
+               puiSymbolicAddrInt = OSAllocMem(psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR));
+               if (!puiSymbolicAddrInt)
+               {
+                       psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto PMRPDumpSymbolicAddr_exit;
+               }
+       }
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpSymbolicAddrOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpSymbolicAddrIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpSymbolicAddrOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpSymbolicAddr_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpSymbolicAddrOUT->eError =
+               PMR_PDumpSymbolicAddr(
+                                       psPMRInt,
+                                       psPMRPDumpSymbolicAddrIN->uiOffset,
+                                       psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen,
+                                       puiMemspaceNameInt,
+                                       psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen,
+                                       puiSymbolicAddrInt,
+                                       &psPMRPDumpSymbolicAddrOUT->uiNewOffset,
+                                       &psPMRPDumpSymbolicAddrOUT->uiNextSymName);
+
+
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psPMRPDumpSymbolicAddrOUT->puiMemspaceName, (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR))) 
+               || (OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiMemspaceName, puiMemspaceNameInt,
+               (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+       {
+               psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto PMRPDumpSymbolicAddr_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR))) 
+               || (OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, puiSymbolicAddrInt,
+               (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+       {
+               psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto PMRPDumpSymbolicAddr_exit;
+       }
+
+
+PMRPDumpSymbolicAddr_exit:
+       if (puiMemspaceNameInt)
+               OSFreeMem(puiMemspaceNameInt);
+       if (puiSymbolicAddrInt)
+               OSFreeMem(puiSymbolicAddrInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpPol32(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPPOL32 *psPMRPDumpPol32IN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32 *psPMRPDumpPol32OUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpPol32OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpPol32IN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpPol32OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpPol32_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpPol32OUT->eError =
+               PMRPDumpPol32(
+                                       psPMRInt,
+                                       psPMRPDumpPol32IN->uiOffset,
+                                       psPMRPDumpPol32IN->ui32Value,
+                                       psPMRPDumpPol32IN->ui32Mask,
+                                       psPMRPDumpPol32IN->eOperator,
+                                       psPMRPDumpPol32IN->ui32PDumpFlags);
+
+
+
+
+PMRPDumpPol32_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRPDumpCBP(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRPDUMPCBP *psPMRPDumpCBPIN,
+                                         PVRSRV_BRIDGE_OUT_PMRPDUMPCBP *psPMRPDumpCBPOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRPDumpCBPOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRPDumpCBPIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRPDumpCBPOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PMRPDumpCBP_exit;
+                                       }
+                               }
+
+
+       psPMRPDumpCBPOUT->eError =
+               PMRPDumpCBP(
+                                       psPMRInt,
+                                       psPMRPDumpCBPIN->uiReadOffset,
+                                       psPMRPDumpCBPIN->uiWriteOffset,
+                                       psPMRPDumpCBPIN->uiPacketSize,
+                                       psPMRPDumpCBPIN->uiBufferSize);
+
+
+
+
+PMRPDumpCBP_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDevmemIntPDumpSaveToFileVirtual(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualIN,
+                                         PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEMINT_CTX * psDevmemServerContextInt = IMG_NULL;
+       IMG_CHAR *uiFileNameInt = IMG_NULL;
+
+
+
+
+       if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize != 0)
+       {
+               uiFileNameInt = OSAllocMem(psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR));
+               if (!uiFileNameInt)
+               {
+                       psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto DevmemIntPDumpSaveToFileVirtual_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevmemIntPDumpSaveToFileVirtualIN->puiFileName, psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiFileNameInt, psDevmemIntPDumpSaveToFileVirtualIN->puiFileName,
+                               psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto DevmemIntPDumpSaveToFileVirtual_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psDevmemIntPDumpSaveToFileVirtualOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psDevmemServerContextInt,
+                                                                                       psDevmemIntPDumpSaveToFileVirtualIN->hDevmemServerContext,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+                                       if(psDevmemIntPDumpSaveToFileVirtualOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto DevmemIntPDumpSaveToFileVirtual_exit;
+                                       }
+                               }
+
+
+       psDevmemIntPDumpSaveToFileVirtualOUT->eError =
+               DevmemIntPDumpSaveToFileVirtual(
+                                       psDevmemServerContextInt,
+                                       psDevmemIntPDumpSaveToFileVirtualIN->sAddress,
+                                       psDevmemIntPDumpSaveToFileVirtualIN->uiSize,
+                                       psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize,
+                                       uiFileNameInt,
+                                       psDevmemIntPDumpSaveToFileVirtualIN->ui32FileOffset,
+                                       psDevmemIntPDumpSaveToFileVirtualIN->ui32PDumpFlags);
+
+
+
+
+DevmemIntPDumpSaveToFileVirtual_exit:
+       if (uiFileNameInt)
+               OSFreeMem(uiFileNameInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitPDUMPMMBridge(IMG_VOID);
+PVRSRV_ERROR DeinitPDUMPMMBridge(IMG_VOID);
+
+/*
+ * Register all PDUMPMM functions with services
+ */
+PVRSRV_ERROR InitPDUMPMMBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEM, PVRSRVBridgePMRPDumpLoadMem,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE32, PVRSRVBridgePMRPDumpLoadMemValue32,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPLOADMEMVALUE64, PVRSRVBridgePMRPDumpLoadMemValue64,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSAVETOFILE, PVRSRVBridgePMRPDumpSaveToFile,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPSYMBOLICADDR, PVRSRVBridgePMRPDumpSymbolicAddr,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPPOL32, PVRSRVBridgePMRPDumpPol32,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_PMRPDUMPCBP, PVRSRVBridgePMRPDumpCBP,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMPMM, PVRSRV_BRIDGE_PDUMPMM_DEVMEMINTPDUMPSAVETOFILEVIRTUAL, PVRSRVBridgeDevmemIntPDumpSaveToFileVirtual,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all pdumpmm functions with services
+ */
+PVRSRV_ERROR DeinitPDUMPMMBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/pvrtl_bridge/client_pvrtl_bridge.h b/drivers/gpu/rogue_m/generated/pvrtl_bridge/client_pvrtl_bridge.h
new file mode 100644 (file)
index 0000000..5fe114a
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************/ /*!
+@File
+@Title          Client bridge header for pvrtl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exports the client bridge functions for pvrtl
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_PVRTL_BRIDGE_H
+#define CLIENT_PVRTL_BRIDGE_H
+
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+
+#include "common_pvrtl_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLConnect(IMG_HANDLE hBridge);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLDisconnect(IMG_HANDLE hBridge);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLOpenStream(IMG_HANDLE hBridge,
+                                                         IMG_CHAR *puiName,
+                                                         IMG_UINT32 ui32Mode,
+                                                         IMG_HANDLE *phSD,
+                                                         DEVMEM_SERVER_EXPORTCOOKIE *phClientBUFExportCookie);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLCloseStream(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLAcquireData(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD,
+                                                          IMG_UINT32 *pui32ReadOffset,
+                                                          IMG_UINT32 *pui32ReadLen);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLReleaseData(IMG_HANDLE hBridge,
+                                                          IMG_HANDLE hSD,
+                                                          IMG_UINT32 ui32ReadOffset,
+                                                          IMG_UINT32 ui32ReadLen);
+
+
+#endif /* CLIENT_PVRTL_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pvrtl_bridge/common_pvrtl_bridge.h b/drivers/gpu/rogue_m/generated/pvrtl_bridge/common_pvrtl_bridge.h
new file mode 100644 (file)
index 0000000..37033e1
--- /dev/null
@@ -0,0 +1,174 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for pvrtl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for pvrtl
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_PVRTL_BRIDGE_H
+#define COMMON_PVRTL_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "pvr_tl.h"
+
+
+#define PVRSRV_BRIDGE_PVRTL_CMD_FIRST                  0
+#define PVRSRV_BRIDGE_PVRTL_TLCONNECT                  PVRSRV_BRIDGE_PVRTL_CMD_FIRST+0
+#define PVRSRV_BRIDGE_PVRTL_TLDISCONNECT                       PVRSRV_BRIDGE_PVRTL_CMD_FIRST+1
+#define PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM                       PVRSRV_BRIDGE_PVRTL_CMD_FIRST+2
+#define PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM                      PVRSRV_BRIDGE_PVRTL_CMD_FIRST+3
+#define PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA                      PVRSRV_BRIDGE_PVRTL_CMD_FIRST+4
+#define PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA                      PVRSRV_BRIDGE_PVRTL_CMD_FIRST+5
+#define PVRSRV_BRIDGE_PVRTL_CMD_LAST                   (PVRSRV_BRIDGE_PVRTL_CMD_FIRST+5)
+
+
+/*******************************************
+            TLConnect          
+ *******************************************/
+
+/* Bridge in structure for TLConnect */
+typedef struct PVRSRV_BRIDGE_IN_TLCONNECT_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLCONNECT;
+
+
+/* Bridge out structure for TLConnect */
+typedef struct PVRSRV_BRIDGE_OUT_TLCONNECT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLCONNECT;
+
+/*******************************************
+            TLDisconnect          
+ *******************************************/
+
+/* Bridge in structure for TLDisconnect */
+typedef struct PVRSRV_BRIDGE_IN_TLDISCONNECT_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLDISCONNECT;
+
+
+/* Bridge out structure for TLDisconnect */
+typedef struct PVRSRV_BRIDGE_OUT_TLDISCONNECT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLDISCONNECT;
+
+/*******************************************
+            TLOpenStream          
+ *******************************************/
+
+/* Bridge in structure for TLOpenStream */
+typedef struct PVRSRV_BRIDGE_IN_TLOPENSTREAM_TAG
+{
+       IMG_CHAR * puiName;
+       IMG_UINT32 ui32Mode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLOPENSTREAM;
+
+
+/* Bridge out structure for TLOpenStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLOPENSTREAM_TAG
+{
+       IMG_HANDLE hSD;
+       DEVMEM_SERVER_EXPORTCOOKIE hClientBUFExportCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLOPENSTREAM;
+
+/*******************************************
+            TLCloseStream          
+ *******************************************/
+
+/* Bridge in structure for TLCloseStream */
+typedef struct PVRSRV_BRIDGE_IN_TLCLOSESTREAM_TAG
+{
+       IMG_HANDLE hSD;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLCLOSESTREAM;
+
+
+/* Bridge out structure for TLCloseStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLCLOSESTREAM_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLCLOSESTREAM;
+
+/*******************************************
+            TLAcquireData          
+ *******************************************/
+
+/* Bridge in structure for TLAcquireData */
+typedef struct PVRSRV_BRIDGE_IN_TLACQUIREDATA_TAG
+{
+       IMG_HANDLE hSD;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLACQUIREDATA;
+
+
+/* Bridge out structure for TLAcquireData */
+typedef struct PVRSRV_BRIDGE_OUT_TLACQUIREDATA_TAG
+{
+       IMG_UINT32 ui32ReadOffset;
+       IMG_UINT32 ui32ReadLen;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLACQUIREDATA;
+
+/*******************************************
+            TLReleaseData          
+ *******************************************/
+
+/* Bridge in structure for TLReleaseData */
+typedef struct PVRSRV_BRIDGE_IN_TLRELEASEDATA_TAG
+{
+       IMG_HANDLE hSD;
+       IMG_UINT32 ui32ReadOffset;
+       IMG_UINT32 ui32ReadLen;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLRELEASEDATA;
+
+
+/* Bridge out structure for TLReleaseData */
+typedef struct PVRSRV_BRIDGE_OUT_TLRELEASEDATA_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLRELEASEDATA;
+
+#endif /* COMMON_PVRTL_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/pvrtl_bridge/server_pvrtl_bridge.c b/drivers/gpu/rogue_m/generated/pvrtl_bridge/server_pvrtl_bridge.c
new file mode 100644 (file)
index 0000000..89709ad
--- /dev/null
@@ -0,0 +1,397 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for pvrtl
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for pvrtl
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "tlserver.h"
+
+
+#include "common_pvrtl_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeTLConnect(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLCONNECT *psTLConnectIN,
+                                         PVRSRV_BRIDGE_OUT_TLCONNECT *psTLConnectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psTLConnectIN);
+
+
+
+
+
+
+       psTLConnectOUT->eError =
+               TLServerConnectKM(psConnection
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeTLDisconnect(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLDISCONNECT *psTLDisconnectIN,
+                                         PVRSRV_BRIDGE_OUT_TLDISCONNECT *psTLDisconnectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psTLDisconnectIN);
+
+
+
+
+
+
+       psTLDisconnectOUT->eError =
+               TLServerDisconnectKM(psConnection
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeTLOpenStream(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLOPENSTREAM *psTLOpenStreamIN,
+                                         PVRSRV_BRIDGE_OUT_TLOPENSTREAM *psTLOpenStreamOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_CHAR *uiNameInt = IMG_NULL;
+       TL_STREAM_DESC * psSDInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psClientBUFExportCookieInt = IMG_NULL;
+
+
+
+       psTLOpenStreamOUT->hSD = IMG_NULL;
+
+       
+       {
+               uiNameInt = OSAllocMem(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR));
+               if (!uiNameInt)
+               {
+                       psTLOpenStreamOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto TLOpenStream_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psTLOpenStreamIN->puiName, PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiNameInt, psTLOpenStreamIN->puiName,
+                               PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psTLOpenStreamOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto TLOpenStream_exit;
+                       }
+
+
+
+       psTLOpenStreamOUT->eError =
+               TLServerOpenStreamKM(
+                                       uiNameInt,
+                                       psTLOpenStreamIN->ui32Mode,
+                                       &psSDInt,
+                                       &psClientBUFExportCookieInt);
+       /* Exit early if bridged call fails */
+       if(psTLOpenStreamOUT->eError != PVRSRV_OK)
+       {
+               goto TLOpenStream_exit;
+       }
+
+
+       psTLOpenStreamOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psTLOpenStreamOUT->hSD,
+                                                       (IMG_VOID *) psSDInt,
+                                                       PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&TLServerCloseStreamKM);
+       if (psTLOpenStreamOUT->eError != PVRSRV_OK)
+       {
+               goto TLOpenStream_exit;
+       }
+
+
+       psTLOpenStreamOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psTLOpenStreamOUT->hClientBUFExportCookie,
+                                                       (IMG_VOID *) psClientBUFExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,psTLOpenStreamOUT->hSD);
+       if (psTLOpenStreamOUT->eError != PVRSRV_OK)
+       {
+               goto TLOpenStream_exit;
+       }
+
+
+
+
+TLOpenStream_exit:
+       if (psTLOpenStreamOUT->eError != PVRSRV_OK)
+       {
+               if (psTLOpenStreamOUT->hSD)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               (IMG_HANDLE) psTLOpenStreamOUT->hSD,
+                                               PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psSDInt = IMG_NULL;
+               }
+
+
+               if (psSDInt)
+               {
+                       TLServerCloseStreamKM(psSDInt);
+               }
+       }
+
+       if (uiNameInt)
+               OSFreeMem(uiNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeTLCloseStream(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLCLOSESTREAM *psTLCloseStreamIN,
+                                         PVRSRV_BRIDGE_OUT_TLCLOSESTREAM *psTLCloseStreamOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psTLCloseStreamOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psTLCloseStreamIN->hSD,
+                                       PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+       if ((psTLCloseStreamOUT->eError != PVRSRV_OK) && (psTLCloseStreamOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto TLCloseStream_exit;
+       }
+
+
+
+TLCloseStream_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeTLAcquireData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLACQUIREDATA *psTLAcquireDataIN,
+                                         PVRSRV_BRIDGE_OUT_TLACQUIREDATA *psTLAcquireDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       TL_STREAM_DESC * psSDInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psTLAcquireDataOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSDInt,
+                                                                                       psTLAcquireDataIN->hSD,
+                                                                                       PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+                                       if(psTLAcquireDataOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto TLAcquireData_exit;
+                                       }
+                               }
+
+
+       psTLAcquireDataOUT->eError =
+               TLServerAcquireDataKM(
+                                       psSDInt,
+                                       &psTLAcquireDataOUT->ui32ReadOffset,
+                                       &psTLAcquireDataOUT->ui32ReadLen);
+
+
+
+
+TLAcquireData_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeTLReleaseData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_TLRELEASEDATA *psTLReleaseDataIN,
+                                         PVRSRV_BRIDGE_OUT_TLRELEASEDATA *psTLReleaseDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       TL_STREAM_DESC * psSDInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psTLReleaseDataOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSDInt,
+                                                                                       psTLReleaseDataIN->hSD,
+                                                                                       PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+                                       if(psTLReleaseDataOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto TLReleaseData_exit;
+                                       }
+                               }
+
+
+       psTLReleaseDataOUT->eError =
+               TLServerReleaseDataKM(
+                                       psSDInt,
+                                       psTLReleaseDataIN->ui32ReadOffset,
+                                       psTLReleaseDataIN->ui32ReadLen);
+
+
+
+
+TLReleaseData_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitPVRTLBridge(IMG_VOID);
+PVRSRV_ERROR DeinitPVRTLBridge(IMG_VOID);
+
+/*
+ * Register all PVRTL functions with services
+ */
+PVRSRV_ERROR InitPVRTLBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCONNECT, PVRSRVBridgeTLConnect,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLDISCONNECT, PVRSRVBridgeTLDisconnect,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM, PVRSRVBridgeTLOpenStream,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM, PVRSRVBridgeTLCloseStream,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA, PVRSRVBridgeTLAcquireData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA, PVRSRVBridgeTLReleaseData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all pvrtl functions with services
+ */
+PVRSRV_ERROR DeinitPVRTLBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/regconfig_bridge/common_regconfig_bridge.h b/drivers/gpu/rogue_m/generated/regconfig_bridge/common_regconfig_bridge.h
new file mode 100644 (file)
index 0000000..edda33f
--- /dev/null
@@ -0,0 +1,151 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for regconfig
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for regconfig
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_REGCONFIG_BRIDGE_H
+#define COMMON_REGCONFIG_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+
+#define PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST                      0
+#define PVRSRV_BRIDGE_REGCONFIG_RGXSETREGCONFIGPI                      PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+0
+#define PVRSRV_BRIDGE_REGCONFIG_RGXADDREGCONFIG                        PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+1
+#define PVRSRV_BRIDGE_REGCONFIG_RGXCLEARREGCONFIG                      PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+2
+#define PVRSRV_BRIDGE_REGCONFIG_RGXENABLEREGCONFIG                     PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+3
+#define PVRSRV_BRIDGE_REGCONFIG_RGXDISABLEREGCONFIG                    PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+4
+#define PVRSRV_BRIDGE_REGCONFIG_CMD_LAST                       (PVRSRV_BRIDGE_REGCONFIG_CMD_FIRST+4)
+
+
+/*******************************************
+            RGXSetRegConfigPI          
+ *******************************************/
+
+/* Bridge in structure for RGXSetRegConfigPI */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETREGCONFIGPI_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT8 ui8RegPowerIsland;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETREGCONFIGPI;
+
+
+/* Bridge out structure for RGXSetRegConfigPI */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGPI_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGPI;
+
+/*******************************************
+            RGXAddRegconfig          
+ *******************************************/
+
+/* Bridge in structure for RGXAddRegconfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXADDREGCONFIG_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32RegAddr;
+       IMG_UINT64 ui64RegValue;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXADDREGCONFIG;
+
+
+/* Bridge out structure for RGXAddRegconfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG;
+
+/*******************************************
+            RGXClearRegConfig          
+ *******************************************/
+
+/* Bridge in structure for RGXClearRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG;
+
+
+/* Bridge out structure for RGXClearRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG;
+
+/*******************************************
+            RGXEnableRegConfig          
+ *******************************************/
+
+/* Bridge in structure for RGXEnableRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG;
+
+
+/* Bridge out structure for RGXEnableRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG;
+
+/*******************************************
+            RGXDisableRegConfig          
+ *******************************************/
+
+/* Bridge in structure for RGXDisableRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG;
+
+
+/* Bridge out structure for RGXDisableRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG;
+
+#endif /* COMMON_REGCONFIG_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/regconfig_bridge/server_regconfig_bridge.c b/drivers/gpu/rogue_m/generated/regconfig_bridge/server_regconfig_bridge.c
new file mode 100644 (file)
index 0000000..5c23842
--- /dev/null
@@ -0,0 +1,325 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for regconfig
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for regconfig
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxregconfig.h"
+
+
+#include "common_regconfig_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXSetRegConfigPI(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSETREGCONFIGPI *psRGXSetRegConfigPIIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGPI *psRGXSetRegConfigPIOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetRegConfigPIOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXSetRegConfigPIIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXSetRegConfigPIOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetRegConfigPI_exit;
+                                       }
+                               }
+
+
+       psRGXSetRegConfigPIOUT->eError =
+               PVRSRVRGXSetRegConfigPIKM(
+                                       hDevNodeInt,
+                                       psRGXSetRegConfigPIIN->ui8RegPowerIsland);
+
+
+
+
+RGXSetRegConfigPI_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXAddRegconfig(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXADDREGCONFIG *psRGXAddRegconfigIN,
+                                         PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG *psRGXAddRegconfigOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXAddRegconfigOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXAddRegconfigIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXAddRegconfigOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXAddRegconfig_exit;
+                                       }
+                               }
+
+
+       psRGXAddRegconfigOUT->eError =
+               PVRSRVRGXAddRegConfigKM(
+                                       hDevNodeInt,
+                                       psRGXAddRegconfigIN->ui32RegAddr,
+                                       psRGXAddRegconfigIN->ui64RegValue);
+
+
+
+
+RGXAddRegconfig_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXClearRegConfig(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG *psRGXClearRegConfigIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG *psRGXClearRegConfigOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXClearRegConfigOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXClearRegConfigIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXClearRegConfigOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXClearRegConfig_exit;
+                                       }
+                               }
+
+
+       psRGXClearRegConfigOUT->eError =
+               PVRSRVRGXClearRegConfigKM(
+                                       hDevNodeInt);
+
+
+
+
+RGXClearRegConfig_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXEnableRegConfig(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG *psRGXEnableRegConfigIN,
+                                         PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG *psRGXEnableRegConfigOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXEnableRegConfigOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXEnableRegConfigIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXEnableRegConfigOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXEnableRegConfig_exit;
+                                       }
+                               }
+
+
+       psRGXEnableRegConfigOUT->eError =
+               PVRSRVRGXEnableRegConfigKM(
+                                       hDevNodeInt);
+
+
+
+
+RGXEnableRegConfig_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDisableRegConfig(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG *psRGXDisableRegConfigIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG *psRGXDisableRegConfigOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXDisableRegConfigOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXDisableRegConfigIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXDisableRegConfigOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXDisableRegConfig_exit;
+                                       }
+                               }
+
+
+       psRGXDisableRegConfigOUT->eError =
+               PVRSRVRGXDisableRegConfigKM(
+                                       hDevNodeInt);
+
+
+
+
+RGXDisableRegConfig_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitREGCONFIGBridge(IMG_VOID);
+PVRSRV_ERROR DeinitREGCONFIGBridge(IMG_VOID);
+
+/*
+ * Register all REGCONFIG functions with services
+ */
+PVRSRV_ERROR InitREGCONFIGBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_REGCONFIG, PVRSRV_BRIDGE_REGCONFIG_RGXSETREGCONFIGPI, PVRSRVBridgeRGXSetRegConfigPI,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_REGCONFIG, PVRSRV_BRIDGE_REGCONFIG_RGXADDREGCONFIG, PVRSRVBridgeRGXAddRegconfig,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_REGCONFIG, PVRSRV_BRIDGE_REGCONFIG_RGXCLEARREGCONFIG, PVRSRVBridgeRGXClearRegConfig,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_REGCONFIG, PVRSRV_BRIDGE_REGCONFIG_RGXENABLEREGCONFIG, PVRSRVBridgeRGXEnableRegConfig,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_REGCONFIG, PVRSRV_BRIDGE_REGCONFIG_RGXDISABLEREGCONFIG, PVRSRVBridgeRGXDisableRegConfig,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all regconfig functions with services
+ */
+PVRSRV_ERROR DeinitREGCONFIGBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxcmp_bridge/common_rgxcmp_bridge.h b/drivers/gpu/rogue_m/generated/rgxcmp_bridge/common_rgxcmp_bridge.h
new file mode 100644 (file)
index 0000000..81f1c51
--- /dev/null
@@ -0,0 +1,206 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxcmp
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxcmp
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXCMP_BRIDGE_H
+#define COMMON_RGXCMP_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "sync_external.h"
+#include "rgx_fwif_shared.h"
+
+
+#define PVRSRV_BRIDGE_RGXCMP_CMD_FIRST                 0
+#define PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT                   PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT                  PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM                        PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA                       PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY                      PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXCMP_RGXKICKSYNCCDM                    PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXCMP_CMD_LAST                  (PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5)
+
+
+/*******************************************
+            RGXCreateComputeContext          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateComputeContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32Priority;
+       IMG_DEV_VIRTADDR sMCUFenceAddr;
+       IMG_UINT32 ui32FrameworkCmdize;
+       IMG_BYTE * psFrameworkCmd;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT;
+
+
+/* Bridge out structure for RGXCreateComputeContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT_TAG
+{
+       IMG_HANDLE hComputeContext;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT;
+
+/*******************************************
+            RGXDestroyComputeContext          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyComputeContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT_TAG
+{
+       IMG_HANDLE hComputeContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT;
+
+
+/* Bridge out structure for RGXDestroyComputeContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT;
+
+/*******************************************
+            RGXKickCDM          
+ *******************************************/
+
+/* Bridge in structure for RGXKickCDM */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKCDM_TAG
+{
+       IMG_HANDLE hComputeContext;
+       IMG_UINT32 ui32ClientFenceCount;
+       IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientFenceOffset;
+       IMG_UINT32 * pui32ClientFenceValue;
+       IMG_UINT32 ui32ClientUpdateCount;
+       IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientUpdateOffset;
+       IMG_UINT32 * pui32ClientUpdateValue;
+       IMG_UINT32 ui32ServerSyncCount;
+       IMG_UINT32 * pui32ServerSyncFlags;
+       IMG_HANDLE * phServerSyncs;
+       IMG_UINT32 ui32CmdSize;
+       IMG_BYTE * psDMCmd;
+       IMG_BOOL bbPDumpContinuous;
+       IMG_UINT32 ui32ExternalJobReference;
+       IMG_UINT32 ui32InternalJobReference;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKCDM;
+
+
+/* Bridge out structure for RGXKickCDM */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKCDM_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKCDM;
+
+/*******************************************
+            RGXFlushComputeData          
+ *******************************************/
+
+/* Bridge in structure for RGXFlushComputeData */
+typedef struct PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA_TAG
+{
+       IMG_HANDLE hComputeContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA;
+
+
+/* Bridge out structure for RGXFlushComputeData */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA;
+
+/*******************************************
+            RGXSetComputeContextPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXSetComputeContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY_TAG
+{
+       IMG_HANDLE hComputeContext;
+       IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY;
+
+
+/* Bridge out structure for RGXSetComputeContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY;
+
+/*******************************************
+            RGXKickSyncCDM          
+ *******************************************/
+
+/* Bridge in structure for RGXKickSyncCDM */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCCDM_TAG
+{
+       IMG_HANDLE hComputeContext;
+       IMG_UINT32 ui32ClientFenceCount;
+       IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientFenceOffset;
+       IMG_UINT32 * pui32ClientFenceValue;
+       IMG_UINT32 ui32ClientUpdateCount;
+       IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientUpdateOffset;
+       IMG_UINT32 * pui32ClientUpdateValue;
+       IMG_UINT32 ui32ServerSyncCount;
+       IMG_UINT32 * pui32ServerSyncFlags;
+       IMG_HANDLE * phServerSyncs;
+       IMG_UINT32 ui32NumCheckFenceFDs;
+       IMG_INT32 * pi32CheckFenceFDs;
+       IMG_INT32 i32UpdateFenceFD;
+       IMG_BOOL bbPDumpContinuous;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKSYNCCDM;
+
+
+/* Bridge out structure for RGXKickSyncCDM */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNCCDM_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKSYNCCDM;
+
+#endif /* COMMON_RGXCMP_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxcmp_bridge/server_rgxcmp_bridge.c b/drivers/gpu/rogue_m/generated/rgxcmp_bridge/server_rgxcmp_bridge.c
new file mode 100644 (file)
index 0000000..38a88ee
--- /dev/null
@@ -0,0 +1,1060 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxcmp
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxcmp
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxcompute.h"
+
+
+#include "common_rgxcmp_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXCreateComputeContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_BYTE *psFrameworkCmdInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+       RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
+
+
+
+
+       if (psRGXCreateComputeContextIN->ui32FrameworkCmdize != 0)
+       {
+               psFrameworkCmdInt = OSAllocMem(psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
+               if (!psFrameworkCmdInt)
+               {
+                       psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCreateComputeContext_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateComputeContextIN->psFrameworkCmd, psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateComputeContextIN->psFrameworkCmd,
+                               psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXCreateComputeContext_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateComputeContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateComputeContextIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateComputeContext_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateComputeContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXCreateComputeContextIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateComputeContext_exit;
+                                       }
+                               }
+
+
+       psRGXCreateComputeContextOUT->eError =
+               PVRSRVRGXCreateComputeContextKM(psConnection,
+                                       hDevNodeInt,
+                                       psRGXCreateComputeContextIN->ui32Priority,
+                                       psRGXCreateComputeContextIN->sMCUFenceAddr,
+                                       psRGXCreateComputeContextIN->ui32FrameworkCmdize,
+                                       psFrameworkCmdInt,
+                                       hPrivDataInt,
+                                       &psComputeContextInt);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateComputeContext_exit;
+       }
+
+
+       psRGXCreateComputeContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateComputeContextOUT->hComputeContext,
+                                                       (IMG_VOID *) psComputeContextInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyComputeContextKM);
+       if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateComputeContext_exit;
+       }
+
+
+
+
+RGXCreateComputeContext_exit:
+       if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
+       {
+               if (psComputeContextInt)
+               {
+                       PVRSRVRGXDestroyComputeContextKM(psComputeContextInt);
+               }
+       }
+
+       if (psFrameworkCmdInt)
+               OSFreeMem(psFrameworkCmdInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyComputeContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT *psRGXDestroyComputeContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT *psRGXDestroyComputeContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyComputeContextOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyComputeContextIN->hComputeContext,
+                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+       if ((psRGXDestroyComputeContextOUT->eError != PVRSRV_OK) && (psRGXDestroyComputeContextOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyComputeContext_exit;
+       }
+
+
+
+RGXDestroyComputeContext_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXKICKCDM *psRGXKickCDMIN,
+                                         PVRSRV_BRIDGE_OUT_RGXKICKCDM *psRGXKickCDMOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL;
+       IMG_HANDLE *hServerSyncsInt2 = IMG_NULL;
+       IMG_BYTE *psDMCmdInt = IMG_NULL;
+
+
+
+
+       if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
+       {
+               psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientFenceUFOSyncPrimBlockInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+               hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
+               if (!hClientFenceUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock,
+                               psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceOffsetInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceOffsetInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientFenceOffset, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceOffsetInt, psRGXKickCDMIN->pui32ClientFenceOffset,
+                               psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceValueInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceValueInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientFenceValue, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickCDMIN->pui32ClientFenceValue,
+                               psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
+       {
+               psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientUpdateUFOSyncPrimBlockInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+               hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClientUpdateUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock,
+                               psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateOffsetInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateOffsetInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientUpdateOffset, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateOffsetInt, psRGXKickCDMIN->pui32ClientUpdateOffset,
+                               psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateValueInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateValueInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientUpdateValue, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickCDMIN->pui32ClientUpdateValue,
+                               psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ServerSyncCount != 0)
+       {
+               ui32ServerSyncFlagsInt = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
+               if (!ui32ServerSyncFlagsInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ServerSyncFlags, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickCDMIN->pui32ServerSyncFlags,
+                               psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32ServerSyncCount != 0)
+       {
+               psServerSyncsInt = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerSyncsInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+               hServerSyncsInt2 = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
+               if (!hServerSyncsInt2)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phServerSyncs, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickCDMIN->phServerSyncs,
+                               psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+       if (psRGXKickCDMIN->ui32CmdSize != 0)
+       {
+               psDMCmdInt = OSAllocMem(psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE));
+               if (!psDMCmdInt)
+               {
+                       psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psDMCmd, psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, psDMCmdInt, psRGXKickCDMIN->psDMCmd,
+                               psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickCDM_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psComputeContextInt,
+                                                                                       psRGXKickCDMIN->hComputeContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+                                       if(psRGXKickCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickCDM_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickCDMIN->ui32ClientFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i],
+                                                                                       hClientFenceUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickCDMIN->ui32ClientUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i],
+                                                                                       hClientUpdateUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickCDMIN->ui32ServerSyncCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerSyncsInt[i],
+                                                                                       hServerSyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psRGXKickCDMOUT->eError =
+               PVRSRVRGXKickCDMKM(
+                                       psComputeContextInt,
+                                       psRGXKickCDMIN->ui32ClientFenceCount,
+                                       psClientFenceUFOSyncPrimBlockInt,
+                                       ui32ClientFenceOffsetInt,
+                                       ui32ClientFenceValueInt,
+                                       psRGXKickCDMIN->ui32ClientUpdateCount,
+                                       psClientUpdateUFOSyncPrimBlockInt,
+                                       ui32ClientUpdateOffsetInt,
+                                       ui32ClientUpdateValueInt,
+                                       psRGXKickCDMIN->ui32ServerSyncCount,
+                                       ui32ServerSyncFlagsInt,
+                                       psServerSyncsInt,
+                                       psRGXKickCDMIN->ui32CmdSize,
+                                       psDMCmdInt,
+                                       psRGXKickCDMIN->bbPDumpContinuous,
+                                       psRGXKickCDMIN->ui32ExternalJobReference,
+                                       psRGXKickCDMIN->ui32InternalJobReference);
+
+
+
+
+RGXKickCDM_exit:
+       if (psClientFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psClientFenceUFOSyncPrimBlockInt);
+       if (hClientFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientFenceUFOSyncPrimBlockInt2);
+       if (ui32ClientFenceOffsetInt)
+               OSFreeMem(ui32ClientFenceOffsetInt);
+       if (ui32ClientFenceValueInt)
+               OSFreeMem(ui32ClientFenceValueInt);
+       if (psClientUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psClientUpdateUFOSyncPrimBlockInt);
+       if (hClientUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2);
+       if (ui32ClientUpdateOffsetInt)
+               OSFreeMem(ui32ClientUpdateOffsetInt);
+       if (ui32ClientUpdateValueInt)
+               OSFreeMem(ui32ClientUpdateValueInt);
+       if (ui32ServerSyncFlagsInt)
+               OSFreeMem(ui32ServerSyncFlagsInt);
+       if (psServerSyncsInt)
+               OSFreeMem(psServerSyncsInt);
+       if (hServerSyncsInt2)
+               OSFreeMem(hServerSyncsInt2);
+       if (psDMCmdInt)
+               OSFreeMem(psDMCmdInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXFlushComputeData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataIN,
+                                         PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXFlushComputeDataOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psComputeContextInt,
+                                                                                       psRGXFlushComputeDataIN->hComputeContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+                                       if(psRGXFlushComputeDataOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXFlushComputeData_exit;
+                                       }
+                               }
+
+
+       psRGXFlushComputeDataOUT->eError =
+               PVRSRVRGXFlushComputeDataKM(
+                                       psComputeContextInt);
+
+
+
+
+RGXFlushComputeData_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXSetComputeContextPriority(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetComputeContextPriorityOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psComputeContextInt,
+                                                                                       psRGXSetComputeContextPriorityIN->hComputeContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+                                       if(psRGXSetComputeContextPriorityOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetComputeContextPriority_exit;
+                                       }
+                               }
+
+
+       psRGXSetComputeContextPriorityOUT->eError =
+               PVRSRVRGXSetComputeContextPriorityKM(psConnection,
+                                       psComputeContextInt,
+                                       psRGXSetComputeContextPriorityIN->ui32Priority);
+
+
+
+
+RGXSetComputeContextPriority_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXKICKSYNCCDM *psRGXKickSyncCDMIN,
+                                         PVRSRV_BRIDGE_OUT_RGXKICKSYNCCDM *psRGXKickSyncCDMOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL;
+       IMG_HANDLE *hServerSyncsInt2 = IMG_NULL;
+       IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
+
+
+
+
+       if (psRGXKickSyncCDMIN->ui32ClientFenceCount != 0)
+       {
+               psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientFenceUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+               hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
+               if (!hClientFenceUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncCDMIN->phClientFenceUFOSyncPrimBlock,
+                               psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceOffsetInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceOffsetInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientFenceOffset, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceOffsetInt, psRGXKickSyncCDMIN->pui32ClientFenceOffset,
+                               psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceValueInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceValueInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientFenceValue, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickSyncCDMIN->pui32ClientFenceValue,
+                               psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ClientUpdateCount != 0)
+       {
+               psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientUpdateUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+               hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClientUpdateUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncCDMIN->phClientUpdateUFOSyncPrimBlock,
+                               psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateOffsetInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateOffsetInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientUpdateOffset, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateOffsetInt, psRGXKickSyncCDMIN->pui32ClientUpdateOffset,
+                               psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateValueInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateValueInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientUpdateValue, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickSyncCDMIN->pui32ClientUpdateValue,
+                               psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ServerSyncCount != 0)
+       {
+               ui32ServerSyncFlagsInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
+               if (!ui32ServerSyncFlagsInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ServerSyncFlags, psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncCDMIN->pui32ServerSyncFlags,
+                               psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32ServerSyncCount != 0)
+       {
+               psServerSyncsInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerSyncsInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+               hServerSyncsInt2 = OSAllocMem(psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
+               if (!hServerSyncsInt2)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->phServerSyncs, psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickSyncCDMIN->phServerSyncs,
+                               psRGXKickSyncCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+       if (psRGXKickSyncCDMIN->ui32NumCheckFenceFDs != 0)
+       {
+               i32CheckFenceFDsInt = OSAllocMem(psRGXKickSyncCDMIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
+               if (!i32CheckFenceFDsInt)
+               {
+                       psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncCDM_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pi32CheckFenceFDs, psRGXKickSyncCDMIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
+                               || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXKickSyncCDMIN->pi32CheckFenceFDs,
+                               psRGXKickSyncCDMIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncCDM_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psComputeContextInt,
+                                                                                       psRGXKickSyncCDMIN->hComputeContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+                                       if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncCDM_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncCDMIN->ui32ClientFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i],
+                                                                                       hClientFenceUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncCDMIN->ui32ClientUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i],
+                                                                                       hClientUpdateUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncCDMIN->ui32ServerSyncCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncCDMOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerSyncsInt[i],
+                                                                                       hServerSyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncCDM_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psRGXKickSyncCDMOUT->eError =
+               PVRSRVRGXKickSyncCDMKM(
+                                       psComputeContextInt,
+                                       psRGXKickSyncCDMIN->ui32ClientFenceCount,
+                                       psClientFenceUFOSyncPrimBlockInt,
+                                       ui32ClientFenceOffsetInt,
+                                       ui32ClientFenceValueInt,
+                                       psRGXKickSyncCDMIN->ui32ClientUpdateCount,
+                                       psClientUpdateUFOSyncPrimBlockInt,
+                                       ui32ClientUpdateOffsetInt,
+                                       ui32ClientUpdateValueInt,
+                                       psRGXKickSyncCDMIN->ui32ServerSyncCount,
+                                       ui32ServerSyncFlagsInt,
+                                       psServerSyncsInt,
+                                       psRGXKickSyncCDMIN->ui32NumCheckFenceFDs,
+                                       i32CheckFenceFDsInt,
+                                       psRGXKickSyncCDMIN->i32UpdateFenceFD,
+                                       psRGXKickSyncCDMIN->bbPDumpContinuous);
+
+
+
+
+RGXKickSyncCDM_exit:
+       if (psClientFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psClientFenceUFOSyncPrimBlockInt);
+       if (hClientFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientFenceUFOSyncPrimBlockInt2);
+       if (ui32ClientFenceOffsetInt)
+               OSFreeMem(ui32ClientFenceOffsetInt);
+       if (ui32ClientFenceValueInt)
+               OSFreeMem(ui32ClientFenceValueInt);
+       if (psClientUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psClientUpdateUFOSyncPrimBlockInt);
+       if (hClientUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2);
+       if (ui32ClientUpdateOffsetInt)
+               OSFreeMem(ui32ClientUpdateOffsetInt);
+       if (ui32ClientUpdateValueInt)
+               OSFreeMem(ui32ClientUpdateValueInt);
+       if (ui32ServerSyncFlagsInt)
+               OSFreeMem(ui32ServerSyncFlagsInt);
+       if (psServerSyncsInt)
+               OSFreeMem(psServerSyncsInt);
+       if (hServerSyncsInt2)
+               OSFreeMem(hServerSyncsInt2);
+       if (i32CheckFenceFDsInt)
+               OSFreeMem(i32CheckFenceFDsInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXCMPBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXCMPBridge(IMG_VOID);
+
+/*
+ * Register all RGXCMP functions with services
+ */
+PVRSRV_ERROR InitRGXCMPBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT, PVRSRVBridgeRGXCreateComputeContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT, PVRSRVBridgeRGXDestroyComputeContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM, PVRSRVBridgeRGXKickCDM,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA, PVRSRVBridgeRGXFlushComputeData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY, PVRSRVBridgeRGXSetComputeContextPriority,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXKICKSYNCCDM, PVRSRVBridgeRGXKickSyncCDM,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxcmp functions with services
+ */
+PVRSRV_ERROR DeinitRGXCMPBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h b/drivers/gpu/rogue_m/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h
new file mode 100644 (file)
index 0000000..7e13a61
--- /dev/null
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxhwperf
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxhwperf
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXHWPERF_BRIDGE_H
+#define COMMON_RGXHWPERF_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "rgx_hwperf_km.h"
+
+
+#define PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST                      0
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF                  PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGENABLEHWPERFCOUNTERS                  PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERFCOUNTERS                  PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS                        PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXHWPERF_CMD_LAST                       (PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+3)
+
+
+/*******************************************
+            RGXCtrlHWPerf          
+ *******************************************/
+
+/* Bridge in structure for RGXCtrlHWPerf */
+typedef struct PVRSRV_BRIDGE_IN_RGXCTRLHWPERF_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_BOOL bToggle;
+       IMG_UINT64 ui64Mask;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCTRLHWPERF;
+
+
+/* Bridge out structure for RGXCtrlHWPerf */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF;
+
+/*******************************************
+            RGXConfigEnableHWPerfCounters          
+ *******************************************/
+
+/* Bridge in structure for RGXConfigEnableHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGENABLEHWPERFCOUNTERS_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32ArrayLen;
+       RGX_HWPERF_CONFIG_CNTBLK * psBlockConfigs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCONFIGENABLEHWPERFCOUNTERS;
+
+
+/* Bridge out structure for RGXConfigEnableHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGENABLEHWPERFCOUNTERS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCONFIGENABLEHWPERFCOUNTERS;
+
+/*******************************************
+            RGXCtrlHWPerfCounters          
+ *******************************************/
+
+/* Bridge in structure for RGXCtrlHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_IN_RGXCTRLHWPERFCOUNTERS_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_BOOL bEnable;
+       IMG_UINT32 ui32ArrayLen;
+       IMG_UINT16 * pui16BlockIDs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCTRLHWPERFCOUNTERS;
+
+
+/* Bridge out structure for RGXCtrlHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCTRLHWPERFCOUNTERS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCTRLHWPERFCOUNTERS;
+
+/*******************************************
+            RGXConfigCustomCounters          
+ *******************************************/
+
+/* Bridge in structure for RGXConfigCustomCounters */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT16 ui16CustomBlockID;
+       IMG_UINT16 ui16NumCustomCounters;
+       IMG_UINT32 * pui32CustomCounterIDs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS;
+
+
+/* Bridge out structure for RGXConfigCustomCounters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS;
+
+#endif /* COMMON_RGXHWPERF_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c b/drivers/gpu/rogue_m/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c
new file mode 100644 (file)
index 0000000..1639e9b
--- /dev/null
@@ -0,0 +1,357 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxhwperf
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxhwperf
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxhwperf.h"
+
+
+#include "common_rgxhwperf_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXCtrlHWPerf(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCTRLHWPERF *psRGXCtrlHWPerfIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF *psRGXCtrlHWPerfOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCtrlHWPerfOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCtrlHWPerfIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCtrlHWPerfOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCtrlHWPerf_exit;
+                                       }
+                               }
+
+
+       psRGXCtrlHWPerfOUT->eError =
+               PVRSRVRGXCtrlHWPerfKM(
+                                       hDevNodeInt,
+                                       psRGXCtrlHWPerfIN->bToggle,
+                                       psRGXCtrlHWPerfIN->ui64Mask);
+
+
+
+
+RGXCtrlHWPerf_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXConfigEnableHWPerfCounters(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCONFIGENABLEHWPERFCOUNTERS *psRGXConfigEnableHWPerfCountersIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCONFIGENABLEHWPERFCOUNTERS *psRGXConfigEnableHWPerfCountersOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       RGX_HWPERF_CONFIG_CNTBLK *psBlockConfigsInt = IMG_NULL;
+
+
+
+
+       if (psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen != 0)
+       {
+               psBlockConfigsInt = OSAllocMem(psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK));
+               if (!psBlockConfigsInt)
+               {
+                       psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXConfigEnableHWPerfCounters_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXConfigEnableHWPerfCountersIN->psBlockConfigs, psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK))
+                               || (OSCopyFromUser(NULL, psBlockConfigsInt, psRGXConfigEnableHWPerfCountersIN->psBlockConfigs,
+                               psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK)) != PVRSRV_OK) )
+                       {
+                               psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXConfigEnableHWPerfCounters_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXConfigEnableHWPerfCountersOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXConfigEnableHWPerfCountersIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXConfigEnableHWPerfCountersOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXConfigEnableHWPerfCounters_exit;
+                                       }
+                               }
+
+
+       psRGXConfigEnableHWPerfCountersOUT->eError =
+               PVRSRVRGXConfigEnableHWPerfCountersKM(
+                                       hDevNodeInt,
+                                       psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen,
+                                       psBlockConfigsInt);
+
+
+
+
+RGXConfigEnableHWPerfCounters_exit:
+       if (psBlockConfigsInt)
+               OSFreeMem(psBlockConfigsInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCtrlHWPerfCounters(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCTRLHWPERFCOUNTERS *psRGXCtrlHWPerfCountersIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCTRLHWPERFCOUNTERS *psRGXCtrlHWPerfCountersOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_UINT16 *ui16BlockIDsInt = IMG_NULL;
+
+
+
+
+       if (psRGXCtrlHWPerfCountersIN->ui32ArrayLen != 0)
+       {
+               ui16BlockIDsInt = OSAllocMem(psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16));
+               if (!ui16BlockIDsInt)
+               {
+                       psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCtrlHWPerfCounters_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCtrlHWPerfCountersIN->pui16BlockIDs, psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16))
+                               || (OSCopyFromUser(NULL, ui16BlockIDsInt, psRGXCtrlHWPerfCountersIN->pui16BlockIDs,
+                               psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16)) != PVRSRV_OK) )
+                       {
+                               psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXCtrlHWPerfCounters_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCtrlHWPerfCountersOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCtrlHWPerfCountersIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCtrlHWPerfCountersOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCtrlHWPerfCounters_exit;
+                                       }
+                               }
+
+
+       psRGXCtrlHWPerfCountersOUT->eError =
+               PVRSRVRGXCtrlHWPerfCountersKM(
+                                       hDevNodeInt,
+                                       psRGXCtrlHWPerfCountersIN->bEnable,
+                                       psRGXCtrlHWPerfCountersIN->ui32ArrayLen,
+                                       ui16BlockIDsInt);
+
+
+
+
+RGXCtrlHWPerfCounters_exit:
+       if (ui16BlockIDsInt)
+               OSFreeMem(ui16BlockIDsInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXConfigCustomCounters(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS *psRGXConfigCustomCountersIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS *psRGXConfigCustomCountersOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_UINT32 *ui32CustomCounterIDsInt = IMG_NULL;
+
+
+
+
+       if (psRGXConfigCustomCountersIN->ui16NumCustomCounters != 0)
+       {
+               ui32CustomCounterIDsInt = OSAllocMem(psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32));
+               if (!ui32CustomCounterIDsInt)
+               {
+                       psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXConfigCustomCounters_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXConfigCustomCountersIN->pui32CustomCounterIDs, psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32CustomCounterIDsInt, psRGXConfigCustomCountersIN->pui32CustomCounterIDs,
+                               psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXConfigCustomCounters_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXConfigCustomCountersOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXConfigCustomCountersIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXConfigCustomCountersOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXConfigCustomCounters_exit;
+                                       }
+                               }
+
+
+       psRGXConfigCustomCountersOUT->eError =
+               PVRSRVRGXConfigCustomCountersKM(
+                                       hDevNodeInt,
+                                       psRGXConfigCustomCountersIN->ui16CustomBlockID,
+                                       psRGXConfigCustomCountersIN->ui16NumCustomCounters,
+                                       ui32CustomCounterIDsInt);
+
+
+
+
+RGXConfigCustomCounters_exit:
+       if (ui32CustomCounterIDsInt)
+               OSFreeMem(ui32CustomCounterIDsInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXHWPERFBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXHWPERFBridge(IMG_VOID);
+
+/*
+ * Register all RGXHWPERF functions with services
+ */
+PVRSRV_ERROR InitRGXHWPERFBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF, PVRSRVBridgeRGXCtrlHWPerf,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGENABLEHWPERFCOUNTERS, PVRSRVBridgeRGXConfigEnableHWPerfCounters,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERFCOUNTERS, PVRSRVBridgeRGXCtrlHWPerfCounters,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXHWPERF, PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS, PVRSRVBridgeRGXConfigCustomCounters,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxhwperf functions with services
+ */
+PVRSRV_ERROR DeinitRGXHWPERFBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxinit_bridge/common_rgxinit_bridge.h b/drivers/gpu/rogue_m/generated/rgxinit_bridge/common_rgxinit_bridge.h
new file mode 100644 (file)
index 0000000..9097cb5
--- /dev/null
@@ -0,0 +1,201 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxinit
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxinit
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXINIT_BRIDGE_H
+#define COMMON_RGXINIT_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "rgxscript.h"
+#include "devicemem_typedefs.h"
+#include "rgx_fwif_shared.h"
+#include "rgx_fwif.h"
+
+
+#define PVRSRV_BRIDGE_RGXINIT_CMD_FIRST                        0
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITALLOCFWIMGMEM                     PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITFIRMWARE                  PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITLOADFWIMAGE                       PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITDEVPART2                  PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXINIT_GPUVIRTPOPULATELMASUBARENAS                      PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXINIT_CMD_LAST                 (PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+4)
+
+
+/*******************************************
+            RGXInitAllocFWImgMem          
+ *******************************************/
+
+/* Bridge in structure for RGXInitAllocFWImgMem */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITALLOCFWIMGMEM_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_DEVMEM_SIZE_T uiFWCodeLen;
+       IMG_DEVMEM_SIZE_T uiFWDataLen;
+       IMG_DEVMEM_SIZE_T uiFWCoremem;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITALLOCFWIMGMEM;
+
+
+/* Bridge out structure for RGXInitAllocFWImgMem */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITALLOCFWIMGMEM_TAG
+{
+       DEVMEM_SERVER_EXPORTCOOKIE hFWCodeAllocServerExportCookie;
+       IMG_DEV_VIRTADDR sFWCodeDevVAddrBase;
+       DEVMEM_SERVER_EXPORTCOOKIE hFWDataAllocServerExportCookie;
+       IMG_DEV_VIRTADDR sFWDataDevVAddrBase;
+       DEVMEM_SERVER_EXPORTCOOKIE hFWCorememAllocServerExportCookie;
+       IMG_DEV_VIRTADDR sFWCorememDevVAddrBase;
+       RGXFWIF_DEV_VIRTADDR sFWCorememMetaVAddrBase;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITALLOCFWIMGMEM;
+
+/*******************************************
+            RGXInitFirmware          
+ *******************************************/
+
+/* Bridge in structure for RGXInitFirmware */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITFIRMWARE_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_BOOL bEnableSignatureChecks;
+       IMG_UINT32 ui32SignatureChecksBufSize;
+       IMG_UINT32 ui32HWPerfFWBufSizeKB;
+       IMG_UINT64 ui64HWPerfFilter;
+       IMG_UINT32 ui32RGXFWAlignChecksSize;
+       IMG_UINT32 * pui32RGXFWAlignChecks;
+       IMG_UINT32 ui32ConfigFlags;
+       IMG_UINT32 ui32LogType;
+       IMG_UINT32 ui32FilterFlags;
+       IMG_UINT32 ui32JonesDisableMask;
+       IMG_UINT32 ui32ui32HWRDebugDumpLimit;
+       RGXFWIF_COMPCHECKS_BVNC sClientBVNC;
+       IMG_UINT32 ui32HWPerfCountersDataSize;
+       RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITFIRMWARE;
+
+
+/* Bridge out structure for RGXInitFirmware */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITFIRMWARE_TAG
+{
+       RGXFWIF_DEV_VIRTADDR spsRGXFwInit;
+       DEVMEM_SERVER_EXPORTCOOKIE hHWPerfDataAllocServerExportCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITFIRMWARE;
+
+/*******************************************
+            RGXInitLoadFWImage          
+ *******************************************/
+
+/* Bridge in structure for RGXInitLoadFWImage */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITLOADFWIMAGE_TAG
+{
+       IMG_HANDLE hImgDestImport;
+       IMG_HANDLE hImgSrcImport;
+       IMG_UINT64 ui64ImgLen;
+       IMG_HANDLE hSigImport;
+       IMG_UINT64 ui64SigLen;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITLOADFWIMAGE;
+
+
+/* Bridge out structure for RGXInitLoadFWImage */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITLOADFWIMAGE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITLOADFWIMAGE;
+
+/*******************************************
+            RGXInitDevPart2          
+ *******************************************/
+
+/* Bridge in structure for RGXInitDevPart2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITDEVPART2_TAG
+{
+       IMG_HANDLE hDevNode;
+       RGX_INIT_COMMAND * psInitScript;
+       RGX_INIT_COMMAND * psDbgScript;
+       RGX_INIT_COMMAND * psDbgBusScript;
+       RGX_INIT_COMMAND * psDeinitScript;
+       IMG_UINT32 ui32ui32KernelCatBaseIdReg;
+       IMG_UINT32 ui32KernelCatBaseId;
+       IMG_UINT32 ui32KernelCatBaseReg;
+       IMG_UINT32 ui32KernelCatBaseWordSize;
+       IMG_UINT32 ui32KernelCatBaseAlignShift;
+       IMG_UINT32 ui32KernelCatBaseShift;
+       IMG_UINT64 ui64KernelCatBaseMask;
+       IMG_UINT32 ui32DeviceFlags;
+       IMG_UINT32 ui32RGXActivePMConf;
+       DEVMEM_SERVER_EXPORTCOOKIE hFWCodeAllocServerExportCookie;
+       DEVMEM_SERVER_EXPORTCOOKIE hFWDataAllocServerExportCookie;
+       DEVMEM_SERVER_EXPORTCOOKIE hFWCorememAllocServerExportCookie;
+       DEVMEM_SERVER_EXPORTCOOKIE hHWPerfDataAllocServerExportCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITDEVPART2;
+
+
+/* Bridge out structure for RGXInitDevPart2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITDEVPART2_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITDEVPART2;
+
+/*******************************************
+            GPUVIRTPopulateLMASubArenas          
+ *******************************************/
+
+/* Bridge in structure for GPUVIRTPopulateLMASubArenas */
+typedef struct PVRSRV_BRIDGE_IN_GPUVIRTPOPULATELMASUBARENAS_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32NumElements;
+       IMG_UINT32 * pui32Elements;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_GPUVIRTPOPULATELMASUBARENAS;
+
+
+/* Bridge out structure for GPUVIRTPopulateLMASubArenas */
+typedef struct PVRSRV_BRIDGE_OUT_GPUVIRTPOPULATELMASUBARENAS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_GPUVIRTPOPULATELMASUBARENAS;
+
+#endif /* COMMON_RGXINIT_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxinit_bridge/server_rgxinit_bridge.c b/drivers/gpu/rogue_m/generated/rgxinit_bridge/server_rgxinit_bridge.c
new file mode 100644 (file)
index 0000000..5f0d05d
--- /dev/null
@@ -0,0 +1,733 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxinit
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxinit
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxinit.h"
+
+
+#include "common_rgxinit_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+static PVRSRV_ERROR ReleaseFWCodeAllocServerExportCookie(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+static PVRSRV_ERROR ReleaseFWDataAllocServerExportCookie(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+static PVRSRV_ERROR ReleaseFWCorememAllocServerExportCookie(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+static PVRSRV_ERROR ReleaseHWPerfDataAllocServerExportCookie(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXInitAllocFWImgMem(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXINITALLOCFWIMGMEM *psRGXInitAllocFWImgMemIN,
+                                         PVRSRV_BRIDGE_OUT_RGXINITALLOCFWIMGMEM *psRGXInitAllocFWImgMemOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWCodeAllocServerExportCookieInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWDataAllocServerExportCookieInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWCorememAllocServerExportCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitAllocFWImgMemOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXInitAllocFWImgMemIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitAllocFWImgMem_exit;
+                                       }
+                               }
+
+
+       psRGXInitAllocFWImgMemOUT->eError =
+               PVRSRVRGXInitAllocFWImgMemKM(
+                                       hDevNodeInt,
+                                       psRGXInitAllocFWImgMemIN->uiFWCodeLen,
+                                       psRGXInitAllocFWImgMemIN->uiFWDataLen,
+                                       psRGXInitAllocFWImgMemIN->uiFWCoremem,
+                                       &psFWCodeAllocServerExportCookieInt,
+                                       &psRGXInitAllocFWImgMemOUT->sFWCodeDevVAddrBase,
+                                       &psFWDataAllocServerExportCookieInt,
+                                       &psRGXInitAllocFWImgMemOUT->sFWDataDevVAddrBase,
+                                       &psFWCorememAllocServerExportCookieInt,
+                                       &psRGXInitAllocFWImgMemOUT->sFWCorememDevVAddrBase,
+                                       &psRGXInitAllocFWImgMemOUT->sFWCorememMetaVAddrBase);
+       /* Exit early if bridged call fails */
+       if(psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitAllocFWImgMem_exit;
+       }
+
+
+       psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXInitAllocFWImgMemOUT->hFWCodeAllocServerExportCookie,
+                                                       (IMG_VOID *) psFWCodeAllocServerExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseFWCodeAllocServerExportCookie);
+       if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitAllocFWImgMem_exit;
+       }
+
+
+       psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXInitAllocFWImgMemOUT->hFWDataAllocServerExportCookie,
+                                                       (IMG_VOID *) psFWDataAllocServerExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseFWDataAllocServerExportCookie);
+       if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitAllocFWImgMem_exit;
+       }
+
+
+       psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXInitAllocFWImgMemOUT->hFWCorememAllocServerExportCookie,
+                                                       (IMG_VOID *) psFWCorememAllocServerExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseFWCorememAllocServerExportCookie);
+       if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitAllocFWImgMem_exit;
+       }
+
+
+
+
+RGXInitAllocFWImgMem_exit:
+       if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
+       {
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXInitFirmware(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXINITFIRMWARE *psRGXInitFirmwareIN,
+                                         PVRSRV_BRIDGE_OUT_RGXINITFIRMWARE *psRGXInitFirmwareOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_UINT32 *ui32RGXFWAlignChecksInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psHWPerfDataAllocServerExportCookieInt = IMG_NULL;
+
+
+
+
+       if (psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize != 0)
+       {
+               ui32RGXFWAlignChecksInt = OSAllocMem(psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32));
+               if (!ui32RGXFWAlignChecksInt)
+               {
+                       psRGXInitFirmwareOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXInitFirmware_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXInitFirmwareIN->pui32RGXFWAlignChecks, psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32RGXFWAlignChecksInt, psRGXInitFirmwareIN->pui32RGXFWAlignChecks,
+                               psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXInitFirmwareOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXInitFirmware_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitFirmwareOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXInitFirmwareIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXInitFirmwareOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitFirmware_exit;
+                                       }
+                               }
+
+
+       psRGXInitFirmwareOUT->eError =
+               PVRSRVRGXInitFirmwareKM(
+                                       hDevNodeInt,
+                                       &psRGXInitFirmwareOUT->spsRGXFwInit,
+                                       psRGXInitFirmwareIN->bEnableSignatureChecks,
+                                       psRGXInitFirmwareIN->ui32SignatureChecksBufSize,
+                                       psRGXInitFirmwareIN->ui32HWPerfFWBufSizeKB,
+                                       psRGXInitFirmwareIN->ui64HWPerfFilter,
+                                       psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize,
+                                       ui32RGXFWAlignChecksInt,
+                                       psRGXInitFirmwareIN->ui32ConfigFlags,
+                                       psRGXInitFirmwareIN->ui32LogType,
+                                       psRGXInitFirmwareIN->ui32FilterFlags,
+                                       psRGXInitFirmwareIN->ui32JonesDisableMask,
+                                       psRGXInitFirmwareIN->ui32ui32HWRDebugDumpLimit,
+                                       &psRGXInitFirmwareIN->sClientBVNC,
+                                       psRGXInitFirmwareIN->ui32HWPerfCountersDataSize,
+                                       &psHWPerfDataAllocServerExportCookieInt,
+                                       psRGXInitFirmwareIN->eRGXRDPowerIslandConf);
+       /* Exit early if bridged call fails */
+       if(psRGXInitFirmwareOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitFirmware_exit;
+       }
+
+
+       psRGXInitFirmwareOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXInitFirmwareOUT->hHWPerfDataAllocServerExportCookie,
+                                                       (IMG_VOID *) psHWPerfDataAllocServerExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseHWPerfDataAllocServerExportCookie);
+       if (psRGXInitFirmwareOUT->eError != PVRSRV_OK)
+       {
+               goto RGXInitFirmware_exit;
+       }
+
+
+
+
+RGXInitFirmware_exit:
+       if (psRGXInitFirmwareOUT->eError != PVRSRV_OK)
+       {
+       }
+
+       if (ui32RGXFWAlignChecksInt)
+               OSFreeMem(ui32RGXFWAlignChecksInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXInitLoadFWImage(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXINITLOADFWIMAGE *psRGXInitLoadFWImageIN,
+                                         PVRSRV_BRIDGE_OUT_RGXINITLOADFWIMAGE *psRGXInitLoadFWImageOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psImgDestImportInt = IMG_NULL;
+       PMR * psImgSrcImportInt = IMG_NULL;
+       PMR * psSigImportInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitLoadFWImageOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psImgDestImportInt,
+                                                                                       psRGXInitLoadFWImageIN->hImgDestImport,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRGXInitLoadFWImageOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitLoadFWImage_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitLoadFWImageOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psImgSrcImportInt,
+                                                                                       psRGXInitLoadFWImageIN->hImgSrcImport,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRGXInitLoadFWImageOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitLoadFWImage_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitLoadFWImageOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSigImportInt,
+                                                                                       psRGXInitLoadFWImageIN->hSigImport,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRGXInitLoadFWImageOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitLoadFWImage_exit;
+                                       }
+                               }
+
+
+       psRGXInitLoadFWImageOUT->eError =
+               PVRSRVRGXInitLoadFWImageKM(
+                                       psImgDestImportInt,
+                                       psImgSrcImportInt,
+                                       psRGXInitLoadFWImageIN->ui64ImgLen,
+                                       psSigImportInt,
+                                       psRGXInitLoadFWImageIN->ui64SigLen);
+
+
+
+
+RGXInitLoadFWImage_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXInitDevPart2(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXINITDEVPART2 *psRGXInitDevPart2IN,
+                                         PVRSRV_BRIDGE_OUT_RGXINITDEVPART2 *psRGXInitDevPart2OUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       RGX_INIT_COMMAND *psInitScriptInt = IMG_NULL;
+       RGX_INIT_COMMAND *psDbgScriptInt = IMG_NULL;
+       RGX_INIT_COMMAND *psDbgBusScriptInt = IMG_NULL;
+       RGX_INIT_COMMAND *psDeinitScriptInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWCodeAllocServerExportCookieInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWDataAllocServerExportCookieInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psFWCorememAllocServerExportCookieInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psHWPerfDataAllocServerExportCookieInt = IMG_NULL;
+
+
+
+
+       
+       {
+               psInitScriptInt = OSAllocMem(RGX_MAX_INIT_COMMANDS * sizeof(RGX_INIT_COMMAND));
+               if (!psInitScriptInt)
+               {
+                       psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXInitDevPart2_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXInitDevPart2IN->psInitScript, RGX_MAX_INIT_COMMANDS * sizeof(RGX_INIT_COMMAND))
+                               || (OSCopyFromUser(NULL, psInitScriptInt, psRGXInitDevPart2IN->psInitScript,
+                               RGX_MAX_INIT_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
+                       {
+                               psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXInitDevPart2_exit;
+                       }
+       
+       {
+               psDbgScriptInt = OSAllocMem(RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND));
+               if (!psDbgScriptInt)
+               {
+                       psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXInitDevPart2_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXInitDevPart2IN->psDbgScript, RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND))
+                               || (OSCopyFromUser(NULL, psDbgScriptInt, psRGXInitDevPart2IN->psDbgScript,
+                               RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
+                       {
+                               psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXInitDevPart2_exit;
+                       }
+       
+       {
+               psDbgBusScriptInt = OSAllocMem(RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND));
+               if (!psDbgBusScriptInt)
+               {
+                       psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXInitDevPart2_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXInitDevPart2IN->psDbgBusScript, RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND))
+                               || (OSCopyFromUser(NULL, psDbgBusScriptInt, psRGXInitDevPart2IN->psDbgBusScript,
+                               RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
+                       {
+                               psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXInitDevPart2_exit;
+                       }
+       
+       {
+               psDeinitScriptInt = OSAllocMem(RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND));
+               if (!psDeinitScriptInt)
+               {
+                       psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXInitDevPart2_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXInitDevPart2IN->psDeinitScript, RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND))
+                               || (OSCopyFromUser(NULL, psDeinitScriptInt, psRGXInitDevPart2IN->psDeinitScript,
+                               RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
+                       {
+                               psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXInitDevPart2_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitDevPart2OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXInitDevPart2IN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXInitDevPart2OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitDevPart2_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitDevPart2OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psFWCodeAllocServerExportCookieInt,
+                                                                                       psRGXInitDevPart2IN->hFWCodeAllocServerExportCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+                                       if(psRGXInitDevPart2OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitDevPart2_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitDevPart2OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psFWDataAllocServerExportCookieInt,
+                                                                                       psRGXInitDevPart2IN->hFWDataAllocServerExportCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+                                       if(psRGXInitDevPart2OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitDevPart2_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitDevPart2OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psFWCorememAllocServerExportCookieInt,
+                                                                                       psRGXInitDevPart2IN->hFWCorememAllocServerExportCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+                                       if(psRGXInitDevPart2OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitDevPart2_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXInitDevPart2OUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psHWPerfDataAllocServerExportCookieInt,
+                                                                                       psRGXInitDevPart2IN->hHWPerfDataAllocServerExportCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+                                       if(psRGXInitDevPart2OUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXInitDevPart2_exit;
+                                       }
+                               }
+
+
+       psRGXInitDevPart2OUT->eError =
+               PVRSRVRGXInitDevPart2KM(
+                                       hDevNodeInt,
+                                       psInitScriptInt,
+                                       psDbgScriptInt,
+                                       psDbgBusScriptInt,
+                                       psDeinitScriptInt,
+                                       psRGXInitDevPart2IN->ui32ui32KernelCatBaseIdReg,
+                                       psRGXInitDevPart2IN->ui32KernelCatBaseId,
+                                       psRGXInitDevPart2IN->ui32KernelCatBaseReg,
+                                       psRGXInitDevPart2IN->ui32KernelCatBaseWordSize,
+                                       psRGXInitDevPart2IN->ui32KernelCatBaseAlignShift,
+                                       psRGXInitDevPart2IN->ui32KernelCatBaseShift,
+                                       psRGXInitDevPart2IN->ui64KernelCatBaseMask,
+                                       psRGXInitDevPart2IN->ui32DeviceFlags,
+                                       psRGXInitDevPart2IN->ui32RGXActivePMConf,
+                                       psFWCodeAllocServerExportCookieInt,
+                                       psFWDataAllocServerExportCookieInt,
+                                       psFWCorememAllocServerExportCookieInt,
+                                       psHWPerfDataAllocServerExportCookieInt);
+
+
+       psRGXInitDevPart2OUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXInitDevPart2IN->hFWCodeAllocServerExportCookie,
+                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+       if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXInitDevPart2_exit;
+       }
+
+       psRGXInitDevPart2OUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXInitDevPart2IN->hFWDataAllocServerExportCookie,
+                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+       if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXInitDevPart2_exit;
+       }
+
+       psRGXInitDevPart2OUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXInitDevPart2IN->hFWCorememAllocServerExportCookie,
+                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+       if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXInitDevPart2_exit;
+       }
+
+       psRGXInitDevPart2OUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXInitDevPart2IN->hHWPerfDataAllocServerExportCookie,
+                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE);
+       if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXInitDevPart2_exit;
+       }
+
+
+
+RGXInitDevPart2_exit:
+       if (psInitScriptInt)
+               OSFreeMem(psInitScriptInt);
+       if (psDbgScriptInt)
+               OSFreeMem(psDbgScriptInt);
+       if (psDbgBusScriptInt)
+               OSFreeMem(psDbgBusScriptInt);
+       if (psDeinitScriptInt)
+               OSFreeMem(psDeinitScriptInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeGPUVIRTPopulateLMASubArenas(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_GPUVIRTPOPULATELMASUBARENAS *psGPUVIRTPopulateLMASubArenasIN,
+                                         PVRSRV_BRIDGE_OUT_GPUVIRTPOPULATELMASUBARENAS *psGPUVIRTPopulateLMASubArenasOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_UINT32 *ui32ElementsInt = IMG_NULL;
+
+
+
+
+       if (psGPUVIRTPopulateLMASubArenasIN->ui32NumElements != 0)
+       {
+               ui32ElementsInt = OSAllocMem(psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32));
+               if (!ui32ElementsInt)
+               {
+                       psGPUVIRTPopulateLMASubArenasOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto GPUVIRTPopulateLMASubArenas_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psGPUVIRTPopulateLMASubArenasIN->pui32Elements, psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ElementsInt, psGPUVIRTPopulateLMASubArenasIN->pui32Elements,
+                               psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psGPUVIRTPopulateLMASubArenasOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto GPUVIRTPopulateLMASubArenas_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psGPUVIRTPopulateLMASubArenasOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psGPUVIRTPopulateLMASubArenasIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psGPUVIRTPopulateLMASubArenasOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto GPUVIRTPopulateLMASubArenas_exit;
+                                       }
+                               }
+
+
+       psGPUVIRTPopulateLMASubArenasOUT->eError =
+               PVRSRVGPUVIRTPopulateLMASubArenasKM(
+                                       hDevNodeInt,
+                                       psGPUVIRTPopulateLMASubArenasIN->ui32NumElements,
+                                       ui32ElementsInt);
+
+
+
+
+GPUVIRTPopulateLMASubArenas_exit:
+       if (ui32ElementsInt)
+               OSFreeMem(ui32ElementsInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXINITBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXINITBridge(IMG_VOID);
+
+/*
+ * Register all RGXINIT functions with services
+ */
+PVRSRV_ERROR InitRGXINITBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITALLOCFWIMGMEM, PVRSRVBridgeRGXInitAllocFWImgMem,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITFIRMWARE, PVRSRVBridgeRGXInitFirmware,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITLOADFWIMAGE, PVRSRVBridgeRGXInitLoadFWImage,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITDEVPART2, PVRSRVBridgeRGXInitDevPart2,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_GPUVIRTPOPULATELMASUBARENAS, PVRSRVBridgeGPUVIRTPopulateLMASubArenas,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxinit functions with services
+ */
+PVRSRV_ERROR DeinitRGXINITBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxpdump_bridge/common_rgxpdump_bridge.h b/drivers/gpu/rogue_m/generated/rgxpdump_bridge/common_rgxpdump_bridge.h
new file mode 100644 (file)
index 0000000..a1d6a35
--- /dev/null
@@ -0,0 +1,96 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxpdump
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxpdump
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXPDUMP_BRIDGE_H
+#define COMMON_RGXPDUMP_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+
+#define PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST                       0
+#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPTRACEBUFFER                        PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXPDUMP_PDUMPSIGNATUREBUFFER                    PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXPDUMP_CMD_LAST                        (PVRSRV_BRIDGE_RGXPDUMP_CMD_FIRST+1)
+
+
+/*******************************************
+            PDumpTraceBuffer          
+ *******************************************/
+
+/* Bridge in structure for PDumpTraceBuffer */
+typedef struct PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER;
+
+
+/* Bridge out structure for PDumpTraceBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER;
+
+/*******************************************
+            PDumpSignatureBuffer          
+ *******************************************/
+
+/* Bridge in structure for PDumpSignatureBuffer */
+typedef struct PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER_TAG
+{
+       IMG_HANDLE hDeviceNode;
+       IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER;
+
+
+/* Bridge out structure for PDumpSignatureBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER;
+
+#endif /* COMMON_RGXPDUMP_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxpdump_bridge/server_rgxpdump_bridge.c b/drivers/gpu/rogue_m/generated/rgxpdump_bridge/server_rgxpdump_bridge.c
new file mode 100644 (file)
index 0000000..648b7db
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxpdump
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxpdump
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxpdump.h"
+
+
+#include "common_rgxpdump_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePDumpTraceBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PDUMPTRACEBUFFER *psPDumpTraceBufferIN,
+                                         PVRSRV_BRIDGE_OUT_PDUMPTRACEBUFFER *psPDumpTraceBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPDumpTraceBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psPDumpTraceBufferIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psPDumpTraceBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PDumpTraceBuffer_exit;
+                                       }
+                               }
+
+
+       psPDumpTraceBufferOUT->eError =
+               PVRSRVPDumpTraceBufferKM(
+                                       hDeviceNodeInt,
+                                       psPDumpTraceBufferIN->ui32PDumpFlags);
+
+
+
+
+PDumpTraceBuffer_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePDumpSignatureBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER *psPDumpSignatureBufferIN,
+                                         PVRSRV_BRIDGE_OUT_PDUMPSIGNATUREBUFFER *psPDumpSignatureBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDeviceNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPDumpSignatureBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDeviceNodeInt,
+                                                                                       psPDumpSignatureBufferIN->hDeviceNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psPDumpSignatureBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto PDumpSignatureBuffer_exit;
+                                       }
+                               }
+
+
+       psPDumpSignatureBufferOUT->eError =
+               PVRSRVPDumpSignatureBufferKM(
+                                       hDeviceNodeInt,
+                                       psPDumpSignatureBufferIN->ui32PDumpFlags);
+
+
+
+
+PDumpSignatureBuffer_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXPDUMPBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXPDUMPBridge(IMG_VOID);
+
+/*
+ * Register all RGXPDUMP functions with services
+ */
+PVRSRV_ERROR InitRGXPDUMPBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPTRACEBUFFER, PVRSRVBridgePDumpTraceBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXPDUMP, PVRSRV_BRIDGE_RGXPDUMP_PDUMPSIGNATUREBUFFER, PVRSRVBridgePDumpSignatureBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxpdump functions with services
+ */
+PVRSRV_ERROR DeinitRGXPDUMPBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxta3d_bridge/common_rgxta3d_bridge.h b/drivers/gpu/rogue_m/generated/rgxta3d_bridge/common_rgxta3d_bridge.h
new file mode 100644 (file)
index 0000000..5d87997
--- /dev/null
@@ -0,0 +1,531 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxta3d
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxta3d
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXTA3D_BRIDGE_H
+#define COMMON_RGXTA3D_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "sync_external.h"
+#include "rgx_fwif_shared.h"
+
+
+#define PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST                        0
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATA                        PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATA                       PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERTARGET                    PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERTARGET                   PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER                        PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER                       PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER                      PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER                    PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST                        PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+8
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST                       PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+9
+#define PVRSRV_BRIDGE_RGXTA3D_RGXADDBLOCKTOFREELIST                    PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+10
+#define PVRSRV_BRIDGE_RGXTA3D_RGXREMOVEBLOCKFROMFREELIST                       PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+11
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT                   PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+12
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT                  PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+13
+#define PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D                      PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+14
+#define PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY                      PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+15
+#define PVRSRV_BRIDGE_RGXTA3D_RGXGETLASTRENDERCONTEXTRESETREASON                       PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+16
+#define PVRSRV_BRIDGE_RGXTA3D_RGXGETPARTIALRENDERCOUNT                 PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+17
+#define PVRSRV_BRIDGE_RGXTA3D_RGXKICKSYNCTA                    PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+18
+#define PVRSRV_BRIDGE_RGXTA3D_CMD_LAST                 (PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+18)
+
+
+/*******************************************
+            RGXCreateHWRTData          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateHWRTData */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATA_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32RenderTarget;
+       IMG_DEV_VIRTADDR sPMMlistDevVAddr;
+       IMG_DEV_VIRTADDR sVFPPageTableAddr;
+       IMG_HANDLE * phapsFreeLists;
+       IMG_UINT32 ui32PPPScreen;
+       IMG_UINT32 ui32PPPGridOffset;
+       IMG_UINT64 ui64PPPMultiSampleCtl;
+       IMG_UINT32 ui32TPCStride;
+       IMG_DEV_VIRTADDR sTailPtrsDevVAddr;
+       IMG_UINT32 ui32TPCSize;
+       IMG_UINT32 ui32TEScreen;
+       IMG_UINT32 ui32TEAA;
+       IMG_UINT32 ui32TEMTILE1;
+       IMG_UINT32 ui32TEMTILE2;
+       IMG_UINT32 ui32MTileStride;
+       IMG_UINT32 ui32ui32ISPMergeLowerX;
+       IMG_UINT32 ui32ui32ISPMergeLowerY;
+       IMG_UINT32 ui32ui32ISPMergeUpperX;
+       IMG_UINT32 ui32ui32ISPMergeUpperY;
+       IMG_UINT32 ui32ui32ISPMergeScaleX;
+       IMG_UINT32 ui32ui32ISPMergeScaleY;
+       IMG_UINT16 ui16MaxRTs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATA;
+
+
+/* Bridge out structure for RGXCreateHWRTData */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATA_TAG
+{
+       IMG_HANDLE hCleanupCookie;
+       IMG_HANDLE hRTACtlMemDesc;
+       IMG_HANDLE hsHWRTDataMemDesc;
+       IMG_UINT32 ui32FWHWRTData;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATA;
+
+/*******************************************
+            RGXDestroyHWRTData          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyHWRTData */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATA_TAG
+{
+       IMG_HANDLE hCleanupCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATA;
+
+
+/* Bridge out structure for RGXDestroyHWRTData */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATA_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATA;
+
+/*******************************************
+            RGXCreateRenderTarget          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRenderTarget */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERENDERTARGET_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_DEV_VIRTADDR spsVHeapTableDevVAddr;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATERENDERTARGET;
+
+
+/* Bridge out structure for RGXCreateRenderTarget */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERENDERTARGET_TAG
+{
+       IMG_HANDLE hsRenderTargetMemDesc;
+       IMG_UINT32 ui32sRenderTargetFWDevVAddr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATERENDERTARGET;
+
+/*******************************************
+            RGXDestroyRenderTarget          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRenderTarget */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRENDERTARGET_TAG
+{
+       IMG_HANDLE hsRenderTargetMemDesc;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYRENDERTARGET;
+
+
+/* Bridge out structure for RGXDestroyRenderTarget */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERTARGET_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERTARGET;
+
+/*******************************************
+            RGXCreateZSBuffer          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_HANDLE hReservation;
+       IMG_HANDLE hPMR;
+       PVRSRV_MEMALLOCFLAGS_T uiMapFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER;
+
+
+/* Bridge out structure for RGXCreateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER_TAG
+{
+       IMG_HANDLE hsZSBufferKM;
+       IMG_UINT32 ui32sZSBufferFWDevVAddr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER;
+
+/*******************************************
+            RGXDestroyZSBuffer          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER_TAG
+{
+       IMG_HANDLE hsZSBufferMemDesc;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER;
+
+
+/* Bridge out structure for RGXDestroyZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER;
+
+/*******************************************
+            RGXPopulateZSBuffer          
+ *******************************************/
+
+/* Bridge in structure for RGXPopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER_TAG
+{
+       IMG_HANDLE hsZSBufferKM;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER;
+
+
+/* Bridge out structure for RGXPopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER_TAG
+{
+       IMG_HANDLE hsPopulation;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER;
+
+/*******************************************
+            RGXUnpopulateZSBuffer          
+ *******************************************/
+
+/* Bridge in structure for RGXUnpopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER_TAG
+{
+       IMG_HANDLE hsPopulation;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER;
+
+
+/* Bridge out structure for RGXUnpopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER;
+
+/*******************************************
+            RGXCreateFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEFREELIST_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32ui32MaxFLPages;
+       IMG_UINT32 ui32ui32InitFLPages;
+       IMG_UINT32 ui32ui32GrowFLPages;
+       IMG_BOOL bbFreeListCheck;
+       IMG_DEV_VIRTADDR spsFreeListDevVAddr;
+       IMG_HANDLE hsFreeListPMR;
+       IMG_DEVMEM_OFFSET_T uiPMROffset;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATEFREELIST;
+
+
+/* Bridge out structure for RGXCreateFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST_TAG
+{
+       IMG_HANDLE hCleanupCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST;
+
+/*******************************************
+            RGXDestroyFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST_TAG
+{
+       IMG_HANDLE hCleanupCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST;
+
+
+/* Bridge out structure for RGXDestroyFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST;
+
+/*******************************************
+            RGXAddBlockToFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXAddBlockToFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXADDBLOCKTOFREELIST_TAG
+{
+       IMG_HANDLE hsFreeList;
+       IMG_UINT32 ui3232NumPages;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXADDBLOCKTOFREELIST;
+
+
+/* Bridge out structure for RGXAddBlockToFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXADDBLOCKTOFREELIST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXADDBLOCKTOFREELIST;
+
+/*******************************************
+            RGXRemoveBlockFromFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXRemoveBlockFromFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXREMOVEBLOCKFROMFREELIST_TAG
+{
+       IMG_HANDLE hsFreeList;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXREMOVEBLOCKFROMFREELIST;
+
+
+/* Bridge out structure for RGXRemoveBlockFromFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXREMOVEBLOCKFROMFREELIST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXREMOVEBLOCKFROMFREELIST;
+
+/*******************************************
+            RGXCreateRenderContext          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRenderContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32Priority;
+       IMG_DEV_VIRTADDR sMCUFenceAddr;
+       IMG_DEV_VIRTADDR sVDMCallStackAddr;
+       IMG_UINT32 ui32FrameworkCmdize;
+       IMG_BYTE * psFrameworkCmd;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT;
+
+
+/* Bridge out structure for RGXCreateRenderContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT_TAG
+{
+       IMG_HANDLE hRenderContext;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT;
+
+/*******************************************
+            RGXDestroyRenderContext          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRenderContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT_TAG
+{
+       IMG_HANDLE hCleanupCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT;
+
+
+/* Bridge out structure for RGXDestroyRenderContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT;
+
+/*******************************************
+            RGXKickTA3D          
+ *******************************************/
+
+/* Bridge in structure for RGXKickTA3D */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKTA3D_TAG
+{
+       IMG_HANDLE hRenderContext;
+       IMG_UINT32 ui32ClientTAFenceCount;
+       IMG_HANDLE * phClientTAFenceSyncPrimBlock;
+       IMG_UINT32 * pui32ClientTAFenceSyncOffset;
+       IMG_UINT32 * pui32ClientTAFenceValue;
+       IMG_UINT32 ui32ClientTAUpdateCount;
+       IMG_HANDLE * phClientTAUpdateSyncPrimBlock;
+       IMG_UINT32 * pui32ClientTAUpdateSyncOffset;
+       IMG_UINT32 * pui32ClientTAUpdateValue;
+       IMG_UINT32 ui32ServerTASyncPrims;
+       IMG_UINT32 * pui32ServerTASyncFlags;
+       IMG_HANDLE * phServerTASyncs;
+       IMG_UINT32 ui32Client3DFenceCount;
+       IMG_HANDLE * phClient3DFenceSyncPrimBlock;
+       IMG_UINT32 * pui32Client3DFenceSyncOffset;
+       IMG_UINT32 * pui32Client3DFenceValue;
+       IMG_UINT32 ui32Client3DUpdateCount;
+       IMG_HANDLE * phClient3DUpdateSyncPrimBlock;
+       IMG_UINT32 * pui32Client3DUpdateSyncOffset;
+       IMG_UINT32 * pui32Client3DUpdateValue;
+       IMG_UINT32 ui32Server3DSyncPrims;
+       IMG_UINT32 * pui32Server3DSyncFlags;
+       IMG_HANDLE * phServer3DSyncs;
+       IMG_HANDLE hPRFenceUFOSyncPrimBlock;
+       IMG_UINT32 ui32FRFenceUFOSyncOffset;
+       IMG_UINT32 ui32FRFenceValue;
+       IMG_UINT32 ui32NumCheckFenceFDs;
+       IMG_INT32 * pi32CheckFenceFDs;
+       IMG_INT32 i32UpdateFenceFD;
+       IMG_UINT32 ui32TACmdSize;
+       IMG_BYTE * psTACmd;
+       IMG_UINT32 ui323DPRCmdSize;
+       IMG_BYTE * ps3DPRCmd;
+       IMG_UINT32 ui323DCmdSize;
+       IMG_BYTE * ps3DCmd;
+       IMG_UINT32 ui32ExternalJobReference;
+       IMG_UINT32 ui32InternalJobReference;
+       IMG_BOOL bbLastTAInScene;
+       IMG_BOOL bbKickTA;
+       IMG_BOOL bbKickPR;
+       IMG_BOOL bbKick3D;
+       IMG_BOOL bbAbort;
+       IMG_BOOL bbPDumpContinuous;
+       IMG_HANDLE hRTDataCleanup;
+       IMG_HANDLE hZBuffer;
+       IMG_HANDLE hSBuffer;
+       IMG_BOOL bbCommitRefCountsTA;
+       IMG_BOOL bbCommitRefCounts3D;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKTA3D;
+
+
+/* Bridge out structure for RGXKickTA3D */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKTA3D_TAG
+{
+       IMG_BOOL bbCommittedRefCountsTA;
+       IMG_BOOL bbCommittedRefCounts3D;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKTA3D;
+
+/*******************************************
+            RGXSetRenderContextPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXSetRenderContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY_TAG
+{
+       IMG_HANDLE hRenderContext;
+       IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY;
+
+
+/* Bridge out structure for RGXSetRenderContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY;
+
+/*******************************************
+            RGXGetLastRenderContextResetReason          
+ *******************************************/
+
+/* Bridge in structure for RGXGetLastRenderContextResetReason */
+typedef struct PVRSRV_BRIDGE_IN_RGXGETLASTRENDERCONTEXTRESETREASON_TAG
+{
+       IMG_HANDLE hRenderContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXGETLASTRENDERCONTEXTRESETREASON;
+
+
+/* Bridge out structure for RGXGetLastRenderContextResetReason */
+typedef struct PVRSRV_BRIDGE_OUT_RGXGETLASTRENDERCONTEXTRESETREASON_TAG
+{
+       IMG_UINT32 ui32LastResetReason;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXGETLASTRENDERCONTEXTRESETREASON;
+
+/*******************************************
+            RGXGetPartialRenderCount          
+ *******************************************/
+
+/* Bridge in structure for RGXGetPartialRenderCount */
+typedef struct PVRSRV_BRIDGE_IN_RGXGETPARTIALRENDERCOUNT_TAG
+{
+       IMG_HANDLE hHWRTDataMemDesc;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXGETPARTIALRENDERCOUNT;
+
+
+/* Bridge out structure for RGXGetPartialRenderCount */
+typedef struct PVRSRV_BRIDGE_OUT_RGXGETPARTIALRENDERCOUNT_TAG
+{
+       IMG_UINT32 ui32NumPartialRenders;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXGETPARTIALRENDERCOUNT;
+
+/*******************************************
+            RGXKickSyncTA          
+ *******************************************/
+
+/* Bridge in structure for RGXKickSyncTA */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCTA_TAG
+{
+       IMG_HANDLE hRenderContext;
+       IMG_UINT32 ui32ClientTAFenceCount;
+       IMG_HANDLE * phClientTAFenceUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientTAFenceOffset;
+       IMG_UINT32 * pui32ClientTAFenceValue;
+       IMG_UINT32 ui32ClientTAUpdateCount;
+       IMG_HANDLE * phClientTAUpdateUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientTAUpdateOffset;
+       IMG_UINT32 * pui32ClientTAUpdateValue;
+       IMG_UINT32 ui32ServerTASyncPrims;
+       IMG_UINT32 * pui32ServerTASyncFlags;
+       IMG_HANDLE * phServerTASyncs;
+       IMG_UINT32 ui32Client3DFenceCount;
+       IMG_HANDLE * phClient3DFenceUFOSyncPrimBlock;
+       IMG_UINT32 * pui32Client3DFenceOffset;
+       IMG_UINT32 * pui32Client3DFenceValue;
+       IMG_UINT32 ui32Client3DUpdateCount;
+       IMG_HANDLE * phClient3DUpdateUFOSyncPrimBlock;
+       IMG_UINT32 * pui32Client3DUpdateOffset;
+       IMG_UINT32 * pui32Client3DUpdateValue;
+       IMG_UINT32 ui32Server3DSyncPrims;
+       IMG_UINT32 * pui32Server3DSyncFlags;
+       IMG_HANDLE * phServer3DSyncs;
+       IMG_UINT32 ui32NumCheckFenceFDs;
+       IMG_INT32 * pi32CheckFenceFDs;
+       IMG_INT32 i32UpdateFenceFD;
+       IMG_BOOL bbPDumpContinuous;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKSYNCTA;
+
+
+/* Bridge out structure for RGXKickSyncTA */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNCTA_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKSYNCTA;
+
+#endif /* COMMON_RGXTA3D_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxta3d_bridge/server_rgxta3d_bridge.c b/drivers/gpu/rogue_m/generated/rgxta3d_bridge/server_rgxta3d_bridge.c
new file mode 100644 (file)
index 0000000..be88f6b
--- /dev/null
@@ -0,0 +1,2639 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxta3d
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxta3d
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxta3d.h"
+
+
+#include "common_rgxta3d_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXCreateHWRTData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATA *psRGXCreateHWRTDataIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATA *psRGXCreateHWRTDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       RGX_FREELIST * *psapsFreeListsInt = IMG_NULL;
+       IMG_HANDLE *hapsFreeListsInt2 = IMG_NULL;
+       RGX_RTDATA_CLEANUP_DATA * psCleanupCookieInt = IMG_NULL;
+       DEVMEM_MEMDESC * psRTACtlMemDescInt = IMG_NULL;
+       DEVMEM_MEMDESC * pssHWRTDataMemDescInt = IMG_NULL;
+
+
+
+       psRGXCreateHWRTDataOUT->hCleanupCookie = IMG_NULL;
+
+       
+       {
+               psapsFreeListsInt = OSAllocMem(RGXFW_MAX_FREELISTS * sizeof(RGX_FREELIST *));
+               if (!psapsFreeListsInt)
+               {
+                       psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCreateHWRTData_exit;
+               }
+               hapsFreeListsInt2 = OSAllocMem(RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE));
+               if (!hapsFreeListsInt2)
+               {
+                       psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCreateHWRTData_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateHWRTDataIN->phapsFreeLists, RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hapsFreeListsInt2, psRGXCreateHWRTDataIN->phapsFreeLists,
+                               RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXCreateHWRTData_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateHWRTDataOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateHWRTDataIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateHWRTData_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<RGXFW_MAX_FREELISTS;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateHWRTDataOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psapsFreeListsInt[i],
+                                                                                       hapsFreeListsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+                                       if(psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateHWRTData_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psRGXCreateHWRTDataOUT->eError =
+               RGXCreateHWRTData(
+                                       hDevNodeInt,
+                                       psRGXCreateHWRTDataIN->ui32RenderTarget,
+                                       psRGXCreateHWRTDataIN->sPMMlistDevVAddr,
+                                       psRGXCreateHWRTDataIN->sVFPPageTableAddr,
+                                       psapsFreeListsInt,
+                                       &psCleanupCookieInt,
+                                       &psRTACtlMemDescInt,
+                                       psRGXCreateHWRTDataIN->ui32PPPScreen,
+                                       psRGXCreateHWRTDataIN->ui32PPPGridOffset,
+                                       psRGXCreateHWRTDataIN->ui64PPPMultiSampleCtl,
+                                       psRGXCreateHWRTDataIN->ui32TPCStride,
+                                       psRGXCreateHWRTDataIN->sTailPtrsDevVAddr,
+                                       psRGXCreateHWRTDataIN->ui32TPCSize,
+                                       psRGXCreateHWRTDataIN->ui32TEScreen,
+                                       psRGXCreateHWRTDataIN->ui32TEAA,
+                                       psRGXCreateHWRTDataIN->ui32TEMTILE1,
+                                       psRGXCreateHWRTDataIN->ui32TEMTILE2,
+                                       psRGXCreateHWRTDataIN->ui32MTileStride,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeLowerX,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeLowerY,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeUpperX,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeUpperY,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeScaleX,
+                                       psRGXCreateHWRTDataIN->ui32ui32ISPMergeScaleY,
+                                       psRGXCreateHWRTDataIN->ui16MaxRTs,
+                                       &pssHWRTDataMemDescInt,
+                                       &psRGXCreateHWRTDataOUT->ui32FWHWRTData);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateHWRTData_exit;
+       }
+
+
+       psRGXCreateHWRTDataOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateHWRTDataOUT->hCleanupCookie,
+                                                       (IMG_VOID *) psCleanupCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RGXDestroyHWRTData);
+       if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateHWRTData_exit;
+       }
+
+
+       psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateHWRTDataOUT->hRTACtlMemDesc,
+                                                       (IMG_VOID *) psRTACtlMemDescInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,psRGXCreateHWRTDataOUT->hCleanupCookie);
+       if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateHWRTData_exit;
+       }
+
+
+       psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateHWRTDataOUT->hsHWRTDataMemDesc,
+                                                       (IMG_VOID *) pssHWRTDataMemDescInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,psRGXCreateHWRTDataOUT->hCleanupCookie);
+       if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateHWRTData_exit;
+       }
+
+
+
+
+RGXCreateHWRTData_exit:
+       if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
+       {
+               if (psRGXCreateHWRTDataOUT->hCleanupCookie)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               (IMG_HANDLE) psRGXCreateHWRTDataOUT->hCleanupCookie,
+                                               PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psCleanupCookieInt = IMG_NULL;
+               }
+
+
+               if (psCleanupCookieInt)
+               {
+                       RGXDestroyHWRTData(psCleanupCookieInt);
+               }
+       }
+
+       if (psapsFreeListsInt)
+               OSFreeMem(psapsFreeListsInt);
+       if (hapsFreeListsInt2)
+               OSFreeMem(hapsFreeListsInt2);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyHWRTData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATA *psRGXDestroyHWRTDataIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATA *psRGXDestroyHWRTDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyHWRTDataOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyHWRTDataIN->hCleanupCookie,
+                                       PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
+       if ((psRGXDestroyHWRTDataOUT->eError != PVRSRV_OK) && (psRGXDestroyHWRTDataOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyHWRTData_exit;
+       }
+
+
+
+RGXDestroyHWRTData_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCreateRenderTarget(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATERENDERTARGET *psRGXCreateRenderTargetIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATERENDERTARGET *psRGXCreateRenderTargetOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       RGX_RT_CLEANUP_DATA * pssRenderTargetMemDescInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateRenderTargetOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateRenderTargetIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateRenderTarget_exit;
+                                       }
+                               }
+
+
+       psRGXCreateRenderTargetOUT->eError =
+               RGXCreateRenderTarget(
+                                       hDevNodeInt,
+                                       psRGXCreateRenderTargetIN->spsVHeapTableDevVAddr,
+                                       &pssRenderTargetMemDescInt,
+                                       &psRGXCreateRenderTargetOUT->ui32sRenderTargetFWDevVAddr);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateRenderTarget_exit;
+       }
+
+
+       psRGXCreateRenderTargetOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateRenderTargetOUT->hsRenderTargetMemDesc,
+                                                       (IMG_VOID *) pssRenderTargetMemDescInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RGXDestroyRenderTarget);
+       if (psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateRenderTarget_exit;
+       }
+
+
+
+
+RGXCreateRenderTarget_exit:
+       if (psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
+       {
+               if (pssRenderTargetMemDescInt)
+               {
+                       RGXDestroyRenderTarget(pssRenderTargetMemDescInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyRenderTarget(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYRENDERTARGET *psRGXDestroyRenderTargetIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERTARGET *psRGXDestroyRenderTargetOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyRenderTargetOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyRenderTargetIN->hsRenderTargetMemDesc,
+                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET);
+       if ((psRGXDestroyRenderTargetOUT->eError != PVRSRV_OK) && (psRGXDestroyRenderTargetOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyRenderTarget_exit;
+       }
+
+
+
+RGXDestroyRenderTarget_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCreateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER *psRGXCreateZSBufferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER *psRGXCreateZSBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       DEVMEMINT_RESERVATION * psReservationInt = IMG_NULL;
+       PMR * psPMRInt = IMG_NULL;
+       RGX_ZSBUFFER_DATA * pssZSBufferKMInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateZSBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateZSBufferIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateZSBuffer_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateZSBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psReservationInt,
+                                                                                       psRGXCreateZSBufferIN->hReservation,
+                                                                                       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+                                       if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateZSBuffer_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateZSBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psRGXCreateZSBufferIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateZSBuffer_exit;
+                                       }
+                               }
+
+
+       psRGXCreateZSBufferOUT->eError =
+               RGXCreateZSBufferKM(
+                                       hDevNodeInt,
+                                       psReservationInt,
+                                       psPMRInt,
+                                       psRGXCreateZSBufferIN->uiMapFlags,
+                                       &pssZSBufferKMInt,
+                                       &psRGXCreateZSBufferOUT->ui32sZSBufferFWDevVAddr);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateZSBuffer_exit;
+       }
+
+
+       psRGXCreateZSBufferOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateZSBufferOUT->hsZSBufferKM,
+                                                       (IMG_VOID *) pssZSBufferKMInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RGXDestroyZSBufferKM);
+       if (psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateZSBuffer_exit;
+       }
+
+
+
+
+RGXCreateZSBuffer_exit:
+       if (psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               if (pssZSBufferKMInt)
+               {
+                       RGXDestroyZSBufferKM(pssZSBufferKMInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER *psRGXDestroyZSBufferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER *psRGXDestroyZSBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyZSBufferOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyZSBufferIN->hsZSBufferMemDesc,
+                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+       if ((psRGXDestroyZSBufferOUT->eError != PVRSRV_OK) && (psRGXDestroyZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyZSBuffer_exit;
+       }
+
+
+
+RGXDestroyZSBuffer_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXPopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_ZSBUFFER_DATA * pssZSBufferKMInt = IMG_NULL;
+       RGX_POPULATION * pssPopulationInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXPopulateZSBufferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &pssZSBufferKMInt,
+                                                                                       psRGXPopulateZSBufferIN->hsZSBufferKM,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+                                       if(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXPopulateZSBuffer_exit;
+                                       }
+                               }
+
+
+       psRGXPopulateZSBufferOUT->eError =
+               RGXPopulateZSBufferKM(
+                                       pssZSBufferKMInt,
+                                       &pssPopulationInt);
+       /* Exit early if bridged call fails */
+       if(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               goto RGXPopulateZSBuffer_exit;
+       }
+
+
+       psRGXPopulateZSBufferOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXPopulateZSBufferOUT->hsPopulation,
+                                                       (IMG_VOID *) pssPopulationInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_POPULATION,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RGXUnpopulateZSBufferKM);
+       if (psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               goto RGXPopulateZSBuffer_exit;
+       }
+
+
+
+
+RGXPopulateZSBuffer_exit:
+       if (psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
+       {
+               if (pssPopulationInt)
+               {
+                       RGXUnpopulateZSBufferKM(pssPopulationInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXUnpopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER *psRGXUnpopulateZSBufferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER *psRGXUnpopulateZSBufferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXUnpopulateZSBufferOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXUnpopulateZSBufferIN->hsPopulation,
+                                       PVRSRV_HANDLE_TYPE_RGX_POPULATION);
+       if ((psRGXUnpopulateZSBufferOUT->eError != PVRSRV_OK) && (psRGXUnpopulateZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXUnpopulateZSBuffer_exit;
+       }
+
+
+
+RGXUnpopulateZSBuffer_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCreateFreeList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATEFREELIST *psRGXCreateFreeListIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST *psRGXCreateFreeListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       PMR * pssFreeListPMRInt = IMG_NULL;
+       RGX_FREELIST * psCleanupCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateFreeListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateFreeListIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateFreeList_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateFreeListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &pssFreeListPMRInt,
+                                                                                       psRGXCreateFreeListIN->hsFreeListPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateFreeList_exit;
+                                       }
+                               }
+
+
+       psRGXCreateFreeListOUT->eError =
+               RGXCreateFreeList(
+                                       hDevNodeInt,
+                                       psRGXCreateFreeListIN->ui32ui32MaxFLPages,
+                                       psRGXCreateFreeListIN->ui32ui32InitFLPages,
+                                       psRGXCreateFreeListIN->ui32ui32GrowFLPages,
+                                       psRGXCreateFreeListIN->bbFreeListCheck,
+                                       psRGXCreateFreeListIN->spsFreeListDevVAddr,
+                                       pssFreeListPMRInt,
+                                       psRGXCreateFreeListIN->uiPMROffset,
+                                       &psCleanupCookieInt);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateFreeList_exit;
+       }
+
+
+       psRGXCreateFreeListOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateFreeListOUT->hCleanupCookie,
+                                                       (IMG_VOID *) psCleanupCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RGXDestroyFreeList);
+       if (psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateFreeList_exit;
+       }
+
+
+
+
+RGXCreateFreeList_exit:
+       if (psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+       {
+               if (psCleanupCookieInt)
+               {
+                       RGXDestroyFreeList(psCleanupCookieInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyFreeList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST *psRGXDestroyFreeListIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST *psRGXDestroyFreeListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyFreeListOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyFreeListIN->hCleanupCookie,
+                                       PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+       if ((psRGXDestroyFreeListOUT->eError != PVRSRV_OK) && (psRGXDestroyFreeListOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyFreeList_exit;
+       }
+
+
+
+RGXDestroyFreeList_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXAddBlockToFreeList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXADDBLOCKTOFREELIST *psRGXAddBlockToFreeListIN,
+                                         PVRSRV_BRIDGE_OUT_RGXADDBLOCKTOFREELIST *psRGXAddBlockToFreeListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_FREELIST * pssFreeListInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXAddBlockToFreeListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &pssFreeListInt,
+                                                                                       psRGXAddBlockToFreeListIN->hsFreeList,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+                                       if(psRGXAddBlockToFreeListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXAddBlockToFreeList_exit;
+                                       }
+                               }
+
+
+       psRGXAddBlockToFreeListOUT->eError =
+               RGXAddBlockToFreeListKM(
+                                       pssFreeListInt,
+                                       psRGXAddBlockToFreeListIN->ui3232NumPages);
+
+
+
+
+RGXAddBlockToFreeList_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXRemoveBlockFromFreeList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXREMOVEBLOCKFROMFREELIST *psRGXRemoveBlockFromFreeListIN,
+                                         PVRSRV_BRIDGE_OUT_RGXREMOVEBLOCKFROMFREELIST *psRGXRemoveBlockFromFreeListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_FREELIST * pssFreeListInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXRemoveBlockFromFreeListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &pssFreeListInt,
+                                                                                       psRGXRemoveBlockFromFreeListIN->hsFreeList,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+                                       if(psRGXRemoveBlockFromFreeListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXRemoveBlockFromFreeList_exit;
+                                       }
+                               }
+
+
+       psRGXRemoveBlockFromFreeListOUT->eError =
+               RGXRemoveBlockFromFreeListKM(
+                                       pssFreeListInt);
+
+
+
+
+RGXRemoveBlockFromFreeList_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCreateRenderContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT *psRGXCreateRenderContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT *psRGXCreateRenderContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_BYTE *psFrameworkCmdInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+       RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL;
+
+
+
+
+       if (psRGXCreateRenderContextIN->ui32FrameworkCmdize != 0)
+       {
+               psFrameworkCmdInt = OSAllocMem(psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
+               if (!psFrameworkCmdInt)
+               {
+                       psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCreateRenderContext_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateRenderContextIN->psFrameworkCmd, psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateRenderContextIN->psFrameworkCmd,
+                               psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXCreateRenderContext_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateRenderContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateRenderContextIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateRenderContext_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateRenderContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXCreateRenderContextIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateRenderContext_exit;
+                                       }
+                               }
+
+
+       psRGXCreateRenderContextOUT->eError =
+               PVRSRVRGXCreateRenderContextKM(psConnection,
+                                       hDevNodeInt,
+                                       psRGXCreateRenderContextIN->ui32Priority,
+                                       psRGXCreateRenderContextIN->sMCUFenceAddr,
+                                       psRGXCreateRenderContextIN->sVDMCallStackAddr,
+                                       psRGXCreateRenderContextIN->ui32FrameworkCmdize,
+                                       psFrameworkCmdInt,
+                                       hPrivDataInt,
+                                       &psRenderContextInt);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateRenderContext_exit;
+       }
+
+
+       psRGXCreateRenderContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateRenderContextOUT->hRenderContext,
+                                                       (IMG_VOID *) psRenderContextInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyRenderContextKM);
+       if (psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateRenderContext_exit;
+       }
+
+
+
+
+RGXCreateRenderContext_exit:
+       if (psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
+       {
+               if (psRenderContextInt)
+               {
+                       PVRSRVRGXDestroyRenderContextKM(psRenderContextInt);
+               }
+       }
+
+       if (psFrameworkCmdInt)
+               OSFreeMem(psFrameworkCmdInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyRenderContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT *psRGXDestroyRenderContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT *psRGXDestroyRenderContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyRenderContextOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyRenderContextIN->hCleanupCookie,
+                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+       if ((psRGXDestroyRenderContextOUT->eError != PVRSRV_OK) && (psRGXDestroyRenderContextOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyRenderContext_exit;
+       }
+
+
+
+RGXDestroyRenderContext_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXKICKTA3D *psRGXKickTA3DIN,
+                                         PVRSRV_BRIDGE_OUT_RGXKICKTA3D *psRGXKickTA3DOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientTAFenceSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientTAFenceSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAFenceSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientTAUpdateSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientTAUpdateSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAUpdateSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerTASyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerTASyncsInt = IMG_NULL;
+       IMG_HANDLE *hServerTASyncsInt2 = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClient3DFenceSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClient3DFenceSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32Client3DFenceSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32Client3DFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClient3DUpdateSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClient3DUpdateSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32Client3DUpdateSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32Client3DUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32Server3DSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServer3DSyncsInt = IMG_NULL;
+       IMG_HANDLE *hServer3DSyncsInt2 = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * psPRFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
+       IMG_BYTE *psTACmdInt = IMG_NULL;
+       IMG_BYTE *ps3DPRCmdInt = IMG_NULL;
+       IMG_BYTE *ps3DCmdInt = IMG_NULL;
+       RGX_RTDATA_CLEANUP_DATA * psRTDataCleanupInt = IMG_NULL;
+       RGX_ZSBUFFER_DATA * psZBufferInt = IMG_NULL;
+       RGX_ZSBUFFER_DATA * psSBufferInt = IMG_NULL;
+
+
+
+
+       if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
+       {
+               psClientTAFenceSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientTAFenceSyncPrimBlockInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hClientTAFenceSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE));
+               if (!hClientTAFenceSyncPrimBlockInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClientTAFenceSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientTAFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAFenceSyncPrimBlock,
+                               psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
+       {
+               ui32ClientTAFenceSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAFenceSyncOffsetInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAFenceSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset,
+                               psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
+       {
+               ui32ClientTAFenceValueInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAFenceValueInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAFenceValue, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAFenceValueInt, psRGXKickTA3DIN->pui32ClientTAFenceValue,
+                               psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
+       {
+               psClientTAUpdateSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientTAUpdateSyncPrimBlockInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hClientTAUpdateSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClientTAUpdateSyncPrimBlockInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClientTAUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientTAUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAUpdateSyncPrimBlock,
+                               psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
+       {
+               ui32ClientTAUpdateSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAUpdateSyncOffsetInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset,
+                               psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
+       {
+               ui32ClientTAUpdateValueInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAUpdateValueInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAUpdateValue, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAUpdateValueInt, psRGXKickTA3DIN->pui32ClientTAUpdateValue,
+                               psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ServerTASyncPrims != 0)
+       {
+               ui32ServerTASyncFlagsInt = OSAllocMem(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32));
+               if (!ui32ServerTASyncFlagsInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ServerTASyncFlags, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerTASyncFlagsInt, psRGXKickTA3DIN->pui32ServerTASyncFlags,
+                               psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32ServerTASyncPrims != 0)
+       {
+               psServerTASyncsInt = OSAllocMem(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerTASyncsInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hServerTASyncsInt2 = OSAllocMem(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE));
+               if (!hServerTASyncsInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phServerTASyncs, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerTASyncsInt2, psRGXKickTA3DIN->phServerTASyncs,
+                               psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
+       {
+               psClient3DFenceSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClient3DFenceSyncPrimBlockInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hClient3DFenceSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE));
+               if (!hClient3DFenceSyncPrimBlockInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClient3DFenceSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClient3DFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DFenceSyncPrimBlock,
+                               psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
+       {
+               ui32Client3DFenceSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DFenceSyncOffsetInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DFenceSyncOffset, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DFenceSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DFenceSyncOffset,
+                               psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
+       {
+               ui32Client3DFenceValueInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DFenceValueInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DFenceValue, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DFenceValueInt, psRGXKickTA3DIN->pui32Client3DFenceValue,
+                               psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
+       {
+               psClient3DUpdateSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClient3DUpdateSyncPrimBlockInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hClient3DUpdateSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClient3DUpdateSyncPrimBlockInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClient3DUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClient3DUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DUpdateSyncPrimBlock,
+                               psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
+       {
+               ui32Client3DUpdateSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DUpdateSyncOffsetInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset,
+                               psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
+       {
+               ui32Client3DUpdateValueInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DUpdateValueInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DUpdateValue, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DUpdateValueInt, psRGXKickTA3DIN->pui32Client3DUpdateValue,
+                               psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Server3DSyncPrims != 0)
+       {
+               ui32Server3DSyncFlagsInt = OSAllocMem(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32));
+               if (!ui32Server3DSyncFlagsInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Server3DSyncFlags, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Server3DSyncFlagsInt, psRGXKickTA3DIN->pui32Server3DSyncFlags,
+                               psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32Server3DSyncPrims != 0)
+       {
+               psServer3DSyncsInt = OSAllocMem(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServer3DSyncsInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+               hServer3DSyncsInt2 = OSAllocMem(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE));
+               if (!hServer3DSyncsInt2)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phServer3DSyncs, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServer3DSyncsInt2, psRGXKickTA3DIN->phServer3DSyncs,
+                               psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32NumCheckFenceFDs != 0)
+       {
+               i32CheckFenceFDsInt = OSAllocMem(psRGXKickTA3DIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
+               if (!i32CheckFenceFDsInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pi32CheckFenceFDs, psRGXKickTA3DIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
+                               || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXKickTA3DIN->pi32CheckFenceFDs,
+                               psRGXKickTA3DIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui32TACmdSize != 0)
+       {
+               psTACmdInt = OSAllocMem(psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE));
+               if (!psTACmdInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->psTACmd, psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, psTACmdInt, psRGXKickTA3DIN->psTACmd,
+                               psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui323DPRCmdSize != 0)
+       {
+               ps3DPRCmdInt = OSAllocMem(psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE));
+               if (!ps3DPRCmdInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->ps3DPRCmd, psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, ps3DPRCmdInt, psRGXKickTA3DIN->ps3DPRCmd,
+                               psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+       if (psRGXKickTA3DIN->ui323DCmdSize != 0)
+       {
+               ps3DCmdInt = OSAllocMem(psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE));
+               if (!ps3DCmdInt)
+               {
+                       psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickTA3D_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->ps3DCmd, psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, ps3DCmdInt, psRGXKickTA3DIN->ps3DCmd,
+                               psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickTA3D_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRenderContextInt,
+                                                                                       psRGXKickTA3DIN->hRenderContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32ClientTAFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientTAFenceSyncPrimBlockInt[i],
+                                                                                       hClientTAFenceSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32ClientTAUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientTAUpdateSyncPrimBlockInt[i],
+                                                                                       hClientTAUpdateSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32ServerTASyncPrims;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerTASyncsInt[i],
+                                                                                       hServerTASyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32Client3DFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClient3DFenceSyncPrimBlockInt[i],
+                                                                                       hClient3DFenceSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32Client3DUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClient3DUpdateSyncPrimBlockInt[i],
+                                                                                       hClient3DUpdateSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickTA3DIN->ui32Server3DSyncPrims;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServer3DSyncsInt[i],
+                                                                                       hServer3DSyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+               }
+       }
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPRFenceUFOSyncPrimBlockInt,
+                                                                                       psRGXKickTA3DIN->hPRFenceUFOSyncPrimBlock,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+
+                               if (psRGXKickTA3DIN->hRTDataCleanup)
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRTDataCleanupInt,
+                                                                                       psRGXKickTA3DIN->hRTDataCleanup,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+
+                               if (psRGXKickTA3DIN->hZBuffer)
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psZBufferInt,
+                                                                                       psRGXKickTA3DIN->hZBuffer,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+
+                               if (psRGXKickTA3DIN->hSBuffer)
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickTA3DOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSBufferInt,
+                                                                                       psRGXKickTA3DIN->hSBuffer,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+                                       if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickTA3D_exit;
+                                       }
+                               }
+
+
+       psRGXKickTA3DOUT->eError =
+               PVRSRVRGXKickTA3DKM(
+                                       psRenderContextInt,
+                                       psRGXKickTA3DIN->ui32ClientTAFenceCount,
+                                       psClientTAFenceSyncPrimBlockInt,
+                                       ui32ClientTAFenceSyncOffsetInt,
+                                       ui32ClientTAFenceValueInt,
+                                       psRGXKickTA3DIN->ui32ClientTAUpdateCount,
+                                       psClientTAUpdateSyncPrimBlockInt,
+                                       ui32ClientTAUpdateSyncOffsetInt,
+                                       ui32ClientTAUpdateValueInt,
+                                       psRGXKickTA3DIN->ui32ServerTASyncPrims,
+                                       ui32ServerTASyncFlagsInt,
+                                       psServerTASyncsInt,
+                                       psRGXKickTA3DIN->ui32Client3DFenceCount,
+                                       psClient3DFenceSyncPrimBlockInt,
+                                       ui32Client3DFenceSyncOffsetInt,
+                                       ui32Client3DFenceValueInt,
+                                       psRGXKickTA3DIN->ui32Client3DUpdateCount,
+                                       psClient3DUpdateSyncPrimBlockInt,
+                                       ui32Client3DUpdateSyncOffsetInt,
+                                       ui32Client3DUpdateValueInt,
+                                       psRGXKickTA3DIN->ui32Server3DSyncPrims,
+                                       ui32Server3DSyncFlagsInt,
+                                       psServer3DSyncsInt,
+                                       psPRFenceUFOSyncPrimBlockInt,
+                                       psRGXKickTA3DIN->ui32FRFenceUFOSyncOffset,
+                                       psRGXKickTA3DIN->ui32FRFenceValue,
+                                       psRGXKickTA3DIN->ui32NumCheckFenceFDs,
+                                       i32CheckFenceFDsInt,
+                                       psRGXKickTA3DIN->i32UpdateFenceFD,
+                                       psRGXKickTA3DIN->ui32TACmdSize,
+                                       psTACmdInt,
+                                       psRGXKickTA3DIN->ui323DPRCmdSize,
+                                       ps3DPRCmdInt,
+                                       psRGXKickTA3DIN->ui323DCmdSize,
+                                       ps3DCmdInt,
+                                       psRGXKickTA3DIN->ui32ExternalJobReference,
+                                       psRGXKickTA3DIN->ui32InternalJobReference,
+                                       psRGXKickTA3DIN->bbLastTAInScene,
+                                       psRGXKickTA3DIN->bbKickTA,
+                                       psRGXKickTA3DIN->bbKickPR,
+                                       psRGXKickTA3DIN->bbKick3D,
+                                       psRGXKickTA3DIN->bbAbort,
+                                       psRGXKickTA3DIN->bbPDumpContinuous,
+                                       psRTDataCleanupInt,
+                                       psZBufferInt,
+                                       psSBufferInt,
+                                       psRGXKickTA3DIN->bbCommitRefCountsTA,
+                                       psRGXKickTA3DIN->bbCommitRefCounts3D,
+                                       &psRGXKickTA3DOUT->bbCommittedRefCountsTA,
+                                       &psRGXKickTA3DOUT->bbCommittedRefCounts3D);
+
+
+
+
+RGXKickTA3D_exit:
+       if (psClientTAFenceSyncPrimBlockInt)
+               OSFreeMem(psClientTAFenceSyncPrimBlockInt);
+       if (hClientTAFenceSyncPrimBlockInt2)
+               OSFreeMem(hClientTAFenceSyncPrimBlockInt2);
+       if (ui32ClientTAFenceSyncOffsetInt)
+               OSFreeMem(ui32ClientTAFenceSyncOffsetInt);
+       if (ui32ClientTAFenceValueInt)
+               OSFreeMem(ui32ClientTAFenceValueInt);
+       if (psClientTAUpdateSyncPrimBlockInt)
+               OSFreeMem(psClientTAUpdateSyncPrimBlockInt);
+       if (hClientTAUpdateSyncPrimBlockInt2)
+               OSFreeMem(hClientTAUpdateSyncPrimBlockInt2);
+       if (ui32ClientTAUpdateSyncOffsetInt)
+               OSFreeMem(ui32ClientTAUpdateSyncOffsetInt);
+       if (ui32ClientTAUpdateValueInt)
+               OSFreeMem(ui32ClientTAUpdateValueInt);
+       if (ui32ServerTASyncFlagsInt)
+               OSFreeMem(ui32ServerTASyncFlagsInt);
+       if (psServerTASyncsInt)
+               OSFreeMem(psServerTASyncsInt);
+       if (hServerTASyncsInt2)
+               OSFreeMem(hServerTASyncsInt2);
+       if (psClient3DFenceSyncPrimBlockInt)
+               OSFreeMem(psClient3DFenceSyncPrimBlockInt);
+       if (hClient3DFenceSyncPrimBlockInt2)
+               OSFreeMem(hClient3DFenceSyncPrimBlockInt2);
+       if (ui32Client3DFenceSyncOffsetInt)
+               OSFreeMem(ui32Client3DFenceSyncOffsetInt);
+       if (ui32Client3DFenceValueInt)
+               OSFreeMem(ui32Client3DFenceValueInt);
+       if (psClient3DUpdateSyncPrimBlockInt)
+               OSFreeMem(psClient3DUpdateSyncPrimBlockInt);
+       if (hClient3DUpdateSyncPrimBlockInt2)
+               OSFreeMem(hClient3DUpdateSyncPrimBlockInt2);
+       if (ui32Client3DUpdateSyncOffsetInt)
+               OSFreeMem(ui32Client3DUpdateSyncOffsetInt);
+       if (ui32Client3DUpdateValueInt)
+               OSFreeMem(ui32Client3DUpdateValueInt);
+       if (ui32Server3DSyncFlagsInt)
+               OSFreeMem(ui32Server3DSyncFlagsInt);
+       if (psServer3DSyncsInt)
+               OSFreeMem(psServer3DSyncsInt);
+       if (hServer3DSyncsInt2)
+               OSFreeMem(hServer3DSyncsInt2);
+       if (i32CheckFenceFDsInt)
+               OSFreeMem(i32CheckFenceFDsInt);
+       if (psTACmdInt)
+               OSFreeMem(psTACmdInt);
+       if (ps3DPRCmdInt)
+               OSFreeMem(ps3DPRCmdInt);
+       if (ps3DCmdInt)
+               OSFreeMem(ps3DCmdInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXSetRenderContextPriority(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetRenderContextPriorityOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRenderContextInt,
+                                                                                       psRGXSetRenderContextPriorityIN->hRenderContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+                                       if(psRGXSetRenderContextPriorityOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetRenderContextPriority_exit;
+                                       }
+                               }
+
+
+       psRGXSetRenderContextPriorityOUT->eError =
+               PVRSRVRGXSetRenderContextPriorityKM(psConnection,
+                                       psRenderContextInt,
+                                       psRGXSetRenderContextPriorityIN->ui32Priority);
+
+
+
+
+RGXSetRenderContextPriority_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXGetLastRenderContextResetReason(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXGETLASTRENDERCONTEXTRESETREASON *psRGXGetLastRenderContextResetReasonIN,
+                                         PVRSRV_BRIDGE_OUT_RGXGETLASTRENDERCONTEXTRESETREASON *psRGXGetLastRenderContextResetReasonOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXGetLastRenderContextResetReasonOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRenderContextInt,
+                                                                                       psRGXGetLastRenderContextResetReasonIN->hRenderContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+                                       if(psRGXGetLastRenderContextResetReasonOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXGetLastRenderContextResetReason_exit;
+                                       }
+                               }
+
+
+       psRGXGetLastRenderContextResetReasonOUT->eError =
+               PVRSRVRGXGetLastRenderContextResetReasonKM(
+                                       psRenderContextInt,
+                                       &psRGXGetLastRenderContextResetReasonOUT->ui32LastResetReason);
+
+
+
+
+RGXGetLastRenderContextResetReason_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXGetPartialRenderCount(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXGETPARTIALRENDERCOUNT *psRGXGetPartialRenderCountIN,
+                                         PVRSRV_BRIDGE_OUT_RGXGETPARTIALRENDERCOUNT *psRGXGetPartialRenderCountOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       DEVMEM_MEMDESC * psHWRTDataMemDescInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXGetPartialRenderCountOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psHWRTDataMemDescInt,
+                                                                                       psRGXGetPartialRenderCountIN->hHWRTDataMemDesc,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC);
+                                       if(psRGXGetPartialRenderCountOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXGetPartialRenderCount_exit;
+                                       }
+                               }
+
+
+       psRGXGetPartialRenderCountOUT->eError =
+               PVRSRVRGXGetPartialRenderCountKM(
+                                       psHWRTDataMemDescInt,
+                                       &psRGXGetPartialRenderCountOUT->ui32NumPartialRenders);
+
+
+
+
+RGXGetPartialRenderCount_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXKICKSYNCTA *psRGXKickSyncTAIN,
+                                         PVRSRV_BRIDGE_OUT_RGXKICKSYNCTA *psRGXKickSyncTAOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientTAFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientTAFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAFenceOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientTAUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientTAUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAUpdateOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientTAUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerTASyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerTASyncsInt = IMG_NULL;
+       IMG_HANDLE *hServerTASyncsInt2 = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClient3DFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClient3DFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32Client3DFenceOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32Client3DFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClient3DUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClient3DUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32Client3DUpdateOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32Client3DUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32Server3DSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServer3DSyncsInt = IMG_NULL;
+       IMG_HANDLE *hServer3DSyncsInt2 = IMG_NULL;
+       IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
+
+
+
+
+       if (psRGXKickSyncTAIN->ui32ClientTAFenceCount != 0)
+       {
+               psClientTAFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientTAFenceUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hClientTAFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE));
+               if (!hClientTAFenceUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClientTAFenceUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientTAFenceUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClientTAFenceUFOSyncPrimBlock,
+                               psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ClientTAFenceCount != 0)
+       {
+               ui32ClientTAFenceOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAFenceOffsetInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAFenceOffset, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAFenceOffsetInt, psRGXKickSyncTAIN->pui32ClientTAFenceOffset,
+                               psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ClientTAFenceCount != 0)
+       {
+               ui32ClientTAFenceValueInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAFenceValueInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAFenceValue, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAFenceValueInt, psRGXKickSyncTAIN->pui32ClientTAFenceValue,
+                               psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ClientTAUpdateCount != 0)
+       {
+               psClientTAUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientTAUpdateUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hClientTAUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClientTAUpdateUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClientTAUpdateUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientTAUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClientTAUpdateUFOSyncPrimBlock,
+                               psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ClientTAUpdateCount != 0)
+       {
+               ui32ClientTAUpdateOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAUpdateOffsetInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAUpdateOffset, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAUpdateOffsetInt, psRGXKickSyncTAIN->pui32ClientTAUpdateOffset,
+                               psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ClientTAUpdateCount != 0)
+       {
+               ui32ClientTAUpdateValueInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientTAUpdateValueInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAUpdateValue, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientTAUpdateValueInt, psRGXKickSyncTAIN->pui32ClientTAUpdateValue,
+                               psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ServerTASyncPrims != 0)
+       {
+               ui32ServerTASyncFlagsInt = OSAllocMem(psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32));
+               if (!ui32ServerTASyncFlagsInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ServerTASyncFlags, psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerTASyncFlagsInt, psRGXKickSyncTAIN->pui32ServerTASyncFlags,
+                               psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32ServerTASyncPrims != 0)
+       {
+               psServerTASyncsInt = OSAllocMem(psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerTASyncsInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hServerTASyncsInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE));
+               if (!hServerTASyncsInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phServerTASyncs, psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerTASyncsInt2, psRGXKickSyncTAIN->phServerTASyncs,
+                               psRGXKickSyncTAIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DFenceCount != 0)
+       {
+               psClient3DFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClient3DFenceUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hClient3DFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE));
+               if (!hClient3DFenceUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClient3DFenceUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClient3DFenceUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClient3DFenceUFOSyncPrimBlock,
+                               psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DFenceCount != 0)
+       {
+               ui32Client3DFenceOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DFenceOffsetInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DFenceOffset, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DFenceOffsetInt, psRGXKickSyncTAIN->pui32Client3DFenceOffset,
+                               psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DFenceCount != 0)
+       {
+               ui32Client3DFenceValueInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DFenceValueInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DFenceValue, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DFenceValueInt, psRGXKickSyncTAIN->pui32Client3DFenceValue,
+                               psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DUpdateCount != 0)
+       {
+               psClient3DUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClient3DUpdateUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hClient3DUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClient3DUpdateUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClient3DUpdateUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClient3DUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClient3DUpdateUFOSyncPrimBlock,
+                               psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DUpdateCount != 0)
+       {
+               ui32Client3DUpdateOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DUpdateOffsetInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DUpdateOffset, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DUpdateOffsetInt, psRGXKickSyncTAIN->pui32Client3DUpdateOffset,
+                               psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Client3DUpdateCount != 0)
+       {
+               ui32Client3DUpdateValueInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32Client3DUpdateValueInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DUpdateValue, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Client3DUpdateValueInt, psRGXKickSyncTAIN->pui32Client3DUpdateValue,
+                               psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Server3DSyncPrims != 0)
+       {
+               ui32Server3DSyncFlagsInt = OSAllocMem(psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32));
+               if (!ui32Server3DSyncFlagsInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Server3DSyncFlags, psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32Server3DSyncFlagsInt, psRGXKickSyncTAIN->pui32Server3DSyncFlags,
+                               psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32Server3DSyncPrims != 0)
+       {
+               psServer3DSyncsInt = OSAllocMem(psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServer3DSyncsInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+               hServer3DSyncsInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE));
+               if (!hServer3DSyncsInt2)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phServer3DSyncs, psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServer3DSyncsInt2, psRGXKickSyncTAIN->phServer3DSyncs,
+                               psRGXKickSyncTAIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+       if (psRGXKickSyncTAIN->ui32NumCheckFenceFDs != 0)
+       {
+               i32CheckFenceFDsInt = OSAllocMem(psRGXKickSyncTAIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
+               if (!i32CheckFenceFDsInt)
+               {
+                       psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTA_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pi32CheckFenceFDs, psRGXKickSyncTAIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
+                               || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXKickSyncTAIN->pi32CheckFenceFDs,
+                               psRGXKickSyncTAIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTA_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRenderContextInt,
+                                                                                       psRGXKickSyncTAIN->hRenderContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32ClientTAFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientTAFenceUFOSyncPrimBlockInt[i],
+                                                                                       hClientTAFenceUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32ClientTAUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientTAUpdateUFOSyncPrimBlockInt[i],
+                                                                                       hClientTAUpdateUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32ServerTASyncPrims;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerTASyncsInt[i],
+                                                                                       hServerTASyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32Client3DFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClient3DFenceUFOSyncPrimBlockInt[i],
+                                                                                       hClient3DFenceUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32Client3DUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClient3DUpdateUFOSyncPrimBlockInt[i],
+                                                                                       hClient3DUpdateUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTAIN->ui32Server3DSyncPrims;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTAOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServer3DSyncsInt[i],
+                                                                                       hServer3DSyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickSyncTAOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTA_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psRGXKickSyncTAOUT->eError =
+               PVRSRVRGXKickSyncTAKM(
+                                       psRenderContextInt,
+                                       psRGXKickSyncTAIN->ui32ClientTAFenceCount,
+                                       psClientTAFenceUFOSyncPrimBlockInt,
+                                       ui32ClientTAFenceOffsetInt,
+                                       ui32ClientTAFenceValueInt,
+                                       psRGXKickSyncTAIN->ui32ClientTAUpdateCount,
+                                       psClientTAUpdateUFOSyncPrimBlockInt,
+                                       ui32ClientTAUpdateOffsetInt,
+                                       ui32ClientTAUpdateValueInt,
+                                       psRGXKickSyncTAIN->ui32ServerTASyncPrims,
+                                       ui32ServerTASyncFlagsInt,
+                                       psServerTASyncsInt,
+                                       psRGXKickSyncTAIN->ui32Client3DFenceCount,
+                                       psClient3DFenceUFOSyncPrimBlockInt,
+                                       ui32Client3DFenceOffsetInt,
+                                       ui32Client3DFenceValueInt,
+                                       psRGXKickSyncTAIN->ui32Client3DUpdateCount,
+                                       psClient3DUpdateUFOSyncPrimBlockInt,
+                                       ui32Client3DUpdateOffsetInt,
+                                       ui32Client3DUpdateValueInt,
+                                       psRGXKickSyncTAIN->ui32Server3DSyncPrims,
+                                       ui32Server3DSyncFlagsInt,
+                                       psServer3DSyncsInt,
+                                       psRGXKickSyncTAIN->ui32NumCheckFenceFDs,
+                                       i32CheckFenceFDsInt,
+                                       psRGXKickSyncTAIN->i32UpdateFenceFD,
+                                       psRGXKickSyncTAIN->bbPDumpContinuous);
+
+
+
+
+RGXKickSyncTA_exit:
+       if (psClientTAFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psClientTAFenceUFOSyncPrimBlockInt);
+       if (hClientTAFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientTAFenceUFOSyncPrimBlockInt2);
+       if (ui32ClientTAFenceOffsetInt)
+               OSFreeMem(ui32ClientTAFenceOffsetInt);
+       if (ui32ClientTAFenceValueInt)
+               OSFreeMem(ui32ClientTAFenceValueInt);
+       if (psClientTAUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psClientTAUpdateUFOSyncPrimBlockInt);
+       if (hClientTAUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientTAUpdateUFOSyncPrimBlockInt2);
+       if (ui32ClientTAUpdateOffsetInt)
+               OSFreeMem(ui32ClientTAUpdateOffsetInt);
+       if (ui32ClientTAUpdateValueInt)
+               OSFreeMem(ui32ClientTAUpdateValueInt);
+       if (ui32ServerTASyncFlagsInt)
+               OSFreeMem(ui32ServerTASyncFlagsInt);
+       if (psServerTASyncsInt)
+               OSFreeMem(psServerTASyncsInt);
+       if (hServerTASyncsInt2)
+               OSFreeMem(hServerTASyncsInt2);
+       if (psClient3DFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psClient3DFenceUFOSyncPrimBlockInt);
+       if (hClient3DFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hClient3DFenceUFOSyncPrimBlockInt2);
+       if (ui32Client3DFenceOffsetInt)
+               OSFreeMem(ui32Client3DFenceOffsetInt);
+       if (ui32Client3DFenceValueInt)
+               OSFreeMem(ui32Client3DFenceValueInt);
+       if (psClient3DUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psClient3DUpdateUFOSyncPrimBlockInt);
+       if (hClient3DUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hClient3DUpdateUFOSyncPrimBlockInt2);
+       if (ui32Client3DUpdateOffsetInt)
+               OSFreeMem(ui32Client3DUpdateOffsetInt);
+       if (ui32Client3DUpdateValueInt)
+               OSFreeMem(ui32Client3DUpdateValueInt);
+       if (ui32Server3DSyncFlagsInt)
+               OSFreeMem(ui32Server3DSyncFlagsInt);
+       if (psServer3DSyncsInt)
+               OSFreeMem(psServer3DSyncsInt);
+       if (hServer3DSyncsInt2)
+               OSFreeMem(hServer3DSyncsInt2);
+       if (i32CheckFenceFDsInt)
+               OSFreeMem(i32CheckFenceFDsInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXTA3DBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXTA3DBridge(IMG_VOID);
+
+/*
+ * Register all RGXTA3D functions with services
+ */
+PVRSRV_ERROR InitRGXTA3DBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATA, PVRSRVBridgeRGXCreateHWRTData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATA, PVRSRVBridgeRGXDestroyHWRTData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERTARGET, PVRSRVBridgeRGXCreateRenderTarget,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERTARGET, PVRSRVBridgeRGXDestroyRenderTarget,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER, PVRSRVBridgeRGXCreateZSBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER, PVRSRVBridgeRGXDestroyZSBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER, PVRSRVBridgeRGXPopulateZSBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER, PVRSRVBridgeRGXUnpopulateZSBuffer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST, PVRSRVBridgeRGXCreateFreeList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST, PVRSRVBridgeRGXDestroyFreeList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXADDBLOCKTOFREELIST, PVRSRVBridgeRGXAddBlockToFreeList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXREMOVEBLOCKFROMFREELIST, PVRSRVBridgeRGXRemoveBlockFromFreeList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT, PVRSRVBridgeRGXCreateRenderContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT, PVRSRVBridgeRGXDestroyRenderContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D, PVRSRVBridgeRGXKickTA3D,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY, PVRSRVBridgeRGXSetRenderContextPriority,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXGETLASTRENDERCONTEXTRESETREASON, PVRSRVBridgeRGXGetLastRenderContextResetReason,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXGETPARTIALRENDERCOUNT, PVRSRVBridgeRGXGetPartialRenderCount,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTA3D, PVRSRV_BRIDGE_RGXTA3D_RGXKICKSYNCTA, PVRSRVBridgeRGXKickSyncTA,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxta3d functions with services
+ */
+PVRSRV_ERROR DeinitRGXTA3DBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/rgxtq_bridge/common_rgxtq_bridge.h b/drivers/gpu/rogue_m/generated/rgxtq_bridge/common_rgxtq_bridge.h
new file mode 100644 (file)
index 0000000..807bcec
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxtq
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for rgxtq
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXTQ_BRIDGE_H
+#define COMMON_RGXTQ_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "sync_external.h"
+#include "rgx_fwif_shared.h"
+
+
+#define PVRSRV_BRIDGE_RGXTQ_CMD_FIRST                  0
+#define PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT                   PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT                  PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER                  PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY                      PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTQ_RGXKICKSYNCTRANSFER                        PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTQ_CMD_LAST                   (PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4)
+
+
+/*******************************************
+            RGXCreateTransferContext          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32Priority;
+       IMG_DEV_VIRTADDR sMCUFenceAddr;
+       IMG_UINT32 ui32FrameworkCmdize;
+       IMG_BYTE * psFrameworkCmd;
+       IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT;
+
+
+/* Bridge out structure for RGXCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT_TAG
+{
+       IMG_HANDLE hTransferContext;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT;
+
+/*******************************************
+            RGXDestroyTransferContext          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT_TAG
+{
+       IMG_HANDLE hTransferContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT;
+
+
+/* Bridge out structure for RGXDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT;
+
+/*******************************************
+            RGXSubmitTransfer          
+ *******************************************/
+
+/* Bridge in structure for RGXSubmitTransfer */
+typedef struct PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER_TAG
+{
+       IMG_HANDLE hTransferContext;
+       IMG_UINT32 ui32PrepareCount;
+       IMG_UINT32 * pui32ClientFenceCount;
+       IMG_HANDLE* * phFenceUFOSyncPrimBlock;
+       IMG_UINT32* * pui32FenceSyncOffset;
+       IMG_UINT32* * pui32FenceValue;
+       IMG_UINT32 * pui32ClientUpdateCount;
+       IMG_HANDLE* * phUpdateUFOSyncPrimBlock;
+       IMG_UINT32* * pui32UpdateSyncOffset;
+       IMG_UINT32* * pui32UpdateValue;
+       IMG_UINT32 * pui32ServerSyncCount;
+       IMG_UINT32* * pui32ServerSyncFlags;
+       IMG_HANDLE* * phServerSync;
+       IMG_UINT32 ui32NumCheckFenceFDs;
+       IMG_INT32 * pi32CheckFenceFDs;
+       IMG_INT32 i32UpdateFenceFD;
+       IMG_UINT32 * pui32CommandSize;
+       IMG_UINT8* * pui8FWCommand;
+       IMG_UINT32 * pui32TQPrepareFlags;
+       IMG_UINT32 ui32ExternalJobReference;
+       IMG_UINT32 ui32InternalJobReference;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER;
+
+
+/* Bridge out structure for RGXSubmitTransfer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER;
+
+/*******************************************
+            RGXSetTransferContextPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY_TAG
+{
+       IMG_HANDLE hTransferContext;
+       IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY;
+
+
+/* Bridge out structure for RGXSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY;
+
+/*******************************************
+            RGXKickSyncTransfer          
+ *******************************************/
+
+/* Bridge in structure for RGXKickSyncTransfer */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER_TAG
+{
+       IMG_HANDLE hTransferContext;
+       IMG_UINT32 ui32ClientFenceCount;
+       IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientFenceSyncOffset;
+       IMG_UINT32 * pui32ClientFenceValue;
+       IMG_UINT32 ui32ClientUpdateCount;
+       IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
+       IMG_UINT32 * pui32ClientUpdateSyncOffset;
+       IMG_UINT32 * pui32ClientUpdateValue;
+       IMG_UINT32 ui32ServerSyncCount;
+       IMG_UINT32 * pui32ServerSyncFlags;
+       IMG_HANDLE * phServerSyncs;
+       IMG_UINT32 ui32NumCheckFenceFDs;
+       IMG_INT32 * pi32CheckFenceFDs;
+       IMG_INT32 i32UpdateFenceFD;
+       IMG_UINT32 ui32TQPrepareFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER;
+
+
+/* Bridge out structure for RGXKickSyncTransfer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER;
+
+#endif /* COMMON_RGXTQ_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/rgxtq_bridge/server_rgxtq_bridge.c b/drivers/gpu/rogue_m/generated/rgxtq_bridge/server_rgxtq_bridge.c
new file mode 100644 (file)
index 0000000..f57d773
--- /dev/null
@@ -0,0 +1,1713 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxtq
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxtq
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxtransfer.h"
+
+
+#include "common_rgxtq_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       IMG_BYTE *psFrameworkCmdInt = IMG_NULL;
+       IMG_HANDLE hPrivDataInt = IMG_NULL;
+       RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
+
+
+
+
+       if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0)
+       {
+               psFrameworkCmdInt = OSAllocMem(psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
+               if (!psFrameworkCmdInt)
+               {
+                       psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXCreateTransferContext_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateTransferContextIN->psFrameworkCmd, psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
+                               || (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateTransferContextIN->psFrameworkCmd,
+                               psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+                       {
+                               psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXCreateTransferContext_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateTransferContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCreateTransferContextIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateTransferContext_exit;
+                                       }
+                               }
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCreateTransferContextOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hPrivDataInt,
+                                                                                       psRGXCreateTransferContextIN->hPrivData,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+                                       if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCreateTransferContext_exit;
+                                       }
+                               }
+
+
+       psRGXCreateTransferContextOUT->eError =
+               PVRSRVRGXCreateTransferContextKM(psConnection,
+                                       hDevNodeInt,
+                                       psRGXCreateTransferContextIN->ui32Priority,
+                                       psRGXCreateTransferContextIN->sMCUFenceAddr,
+                                       psRGXCreateTransferContextIN->ui32FrameworkCmdize,
+                                       psFrameworkCmdInt,
+                                       hPrivDataInt,
+                                       &psTransferContextInt);
+       /* Exit early if bridged call fails */
+       if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateTransferContext_exit;
+       }
+
+
+       psRGXCreateTransferContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRGXCreateTransferContextOUT->hTransferContext,
+                                                       (IMG_VOID *) psTransferContextInt,
+                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyTransferContextKM);
+       if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
+       {
+               goto RGXCreateTransferContext_exit;
+       }
+
+
+
+
+RGXCreateTransferContext_exit:
+       if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
+       {
+               if (psTransferContextInt)
+               {
+                       PVRSRVRGXDestroyTransferContextKM(psTransferContextInt);
+               }
+       }
+
+       if (psFrameworkCmdInt)
+               OSFreeMem(psFrameworkCmdInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextIN,
+                                         PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRGXDestroyTransferContextOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRGXDestroyTransferContextIN->hTransferContext,
+                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+       if ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) && (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RGXDestroyTransferContext_exit;
+       }
+
+
+
+RGXDestroyTransferContext_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER *psRGXSubmitTransferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER *psRGXSubmitTransferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceCountInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * **psFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE **hFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 **ui32FenceSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 **ui32FenceValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateCountInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * **psUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE **hUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 **ui32UpdateSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 **ui32UpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerSyncCountInt = IMG_NULL;
+       IMG_UINT32 **ui32ServerSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * **psServerSyncInt = IMG_NULL;
+       IMG_HANDLE **hServerSyncInt2 = IMG_NULL;
+       IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
+       IMG_UINT32 *ui32CommandSizeInt = IMG_NULL;
+       IMG_UINT8 **ui8FWCommandInt = IMG_NULL;
+       IMG_UINT32 *ui32TQPrepareFlagsInt = IMG_NULL;
+
+
+
+
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               ui32ClientFenceCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceCountInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ClientFenceCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceCountInt, psRGXSubmitTransferIN->pui32ClientFenceCount,
+                               psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+               IMG_UINT32 ui32AllocSize2=0;
+               IMG_UINT32 ui32Size2;
+               IMG_UINT8 *pui8Ptr2 = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
+                       ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                               ui32AllocSize2 += ui32Size2;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                               pui8Ptr2 = OSAllocMem(ui32AllocSize2);
+                               if (pui8Ptr2 == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
+                               pui8Ptr2 += ui32Size2;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);         
+                               ui32Size2 = ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE);            
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                               ui32AllocSize2 += ui32Size2;
+                                       }
+                                       else
+                                       {
+                                               psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                               hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
+                                               pui8Ptr2 += ui32Size2;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_HANDLE **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i],
+                               sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE)))
+                               || (OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr,
+                               (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui32FenceSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);             
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui32FenceSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32FenceSyncOffset[i], sizeof(IMG_UINT32 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i],
+                               sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
+                               || (OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr,
+                               (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui32FenceValueInt = (IMG_UINT32 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);             
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui32FenceValueInt[i] = (IMG_UINT32 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32FenceValue[i], sizeof(IMG_UINT32 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceValue[i],
+                               sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
+                               || (OSCopyFromUser(NULL, (ui32FenceValueInt[i]), psPtr,
+                               (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               ui32ClientUpdateCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateCountInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ClientUpdateCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateCountInt, psRGXSubmitTransferIN->pui32ClientUpdateCount,
+                               psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+               IMG_UINT32 ui32AllocSize2=0;
+               IMG_UINT32 ui32Size2;
+               IMG_UINT8 *pui8Ptr2 = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
+                       ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                               ui32AllocSize2 += ui32Size2;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                               pui8Ptr2 = OSAllocMem(ui32AllocSize2);
+                               if (pui8Ptr2 == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
+                               pui8Ptr2 += ui32Size2;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);                
+                               ui32Size2 = ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE);           
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                               ui32AllocSize2 += ui32Size2;
+                                       }
+                                       else
+                                       {
+                                               psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                               hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
+                                               pui8Ptr2 += ui32Size2;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_HANDLE **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i],
+                               sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)))
+                               || (OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr,
+                               (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui32UpdateSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);            
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui32UpdateSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i], sizeof(IMG_UINT32 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i],
+                               sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
+                               || (OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr,
+                               (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui32UpdateValueInt = (IMG_UINT32 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);            
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui32UpdateValueInt[i] = (IMG_UINT32 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32UpdateValue[i], sizeof(IMG_UINT32 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateValue[i],
+                               sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
+                               || (OSCopyFromUser(NULL, (ui32UpdateValueInt[i]), psPtr,
+                               (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               ui32ServerSyncCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
+               if (!ui32ServerSyncCountInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ServerSyncCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerSyncCountInt, psRGXSubmitTransferIN->pui32ServerSyncCount,
+                               psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui32ServerSyncFlagsInt = (IMG_UINT32 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);              
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui32ServerSyncFlagsInt[i] = (IMG_UINT32 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32ServerSyncFlags[i], sizeof(IMG_UINT32 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32ServerSyncFlags[i],
+                               sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32)))
+                               || (OSCopyFromUser(NULL, (ui32ServerSyncFlagsInt[i]), psPtr,
+                               (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+               IMG_UINT32 ui32AllocSize2=0;
+               IMG_UINT32 ui32Size2;
+               IMG_UINT8 *pui8Ptr2 = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE * *);
+                       ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                               ui32AllocSize2 += ui32Size2;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               psServerSyncInt = (SERVER_SYNC_PRIMITIVE * **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                               pui8Ptr2 = OSAllocMem(ui32AllocSize2);
+                               if (pui8Ptr2 == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               hServerSyncInt2 = (IMG_HANDLE **) pui8Ptr2;
+                               pui8Ptr2 += ui32Size2;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);         
+                               ui32Size2 = ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE);             
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                               ui32AllocSize2 += ui32Size2;
+                                       }
+                                       else
+                                       {
+                                               psServerSyncInt[i] = (SERVER_SYNC_PRIMITIVE * *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                               hServerSyncInt2[i] = (IMG_HANDLE *) pui8Ptr2;
+                                               pui8Ptr2 += ui32Size2;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_HANDLE **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phServerSync[i], sizeof(IMG_HANDLE **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phServerSync[i],
+                               sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE)))
+                               || (OSCopyFromUser(NULL, (hServerSyncInt2[i]), psPtr,
+                               (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32NumCheckFenceFDs != 0)
+       {
+               i32CheckFenceFDsInt = OSAllocMem(psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
+               if (!i32CheckFenceFDsInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pi32CheckFenceFDs, psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
+                               || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXSubmitTransferIN->pi32CheckFenceFDs,
+                               psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               ui32CommandSizeInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
+               if (!ui32CommandSizeInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32CommandSize, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32CommandSizeInt, psRGXSubmitTransferIN->pui32CommandSize,
+                               psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               IMG_UINT32 ui32Pass=0;
+               IMG_UINT32 i;
+               IMG_UINT32 ui32AllocSize=0;
+               IMG_UINT32 ui32Size;
+               IMG_UINT8 *pui8Ptr = IMG_NULL;
+
+               /*
+                       Two pass loop, 1st find out the size and 2nd allocation and set offsets.
+                       Keeps allocation cost down and simplifies the free path
+               */
+               for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+               {
+                       ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8 *);
+                       if (ui32Pass == 0)
+                       {
+                               ui32AllocSize += ui32Size;
+                       }
+                       else
+                       {
+                               pui8Ptr = OSAllocMem(ui32AllocSize);
+                               if (pui8Ptr == IMG_NULL)
+                               {
+                                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                                       goto RGXSubmitTransfer_exit;
+                               }
+                               ui8FWCommandInt = (IMG_UINT8 **) pui8Ptr;
+                               pui8Ptr += ui32Size;
+                       }
+                       
+                       for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+                       {
+                               ui32Size = ui32CommandSizeInt[i] * sizeof(IMG_UINT8);           
+                               if (ui32Size)
+                               {
+                                       if (ui32Pass == 0)
+                                       {
+                                               ui32AllocSize += ui32Size;
+                                       }
+                                       else
+                                       {
+                                               ui8FWCommandInt[i] = (IMG_UINT8 *) pui8Ptr;
+                                               pui8Ptr += ui32Size;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+               IMG_UINT8 **psPtr;
+
+               /* Loop over all the pointers in the array copying the data into the kernel */
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       /* Copy the pointer over from the client side */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui8FWCommand[i], sizeof(IMG_UINT8 **))
+                               || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui8FWCommand[i],
+                               sizeof(IMG_UINT8 **)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32CommandSizeInt[i] * sizeof(IMG_UINT8)))
+                               || (OSCopyFromUser(NULL, (ui8FWCommandInt[i]), psPtr,
+                               (ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+               }
+       }
+       if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+       {
+               ui32TQPrepareFlagsInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
+               if (!ui32TQPrepareFlagsInt)
+               {
+                       psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXSubmitTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32TQPrepareFlags, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32TQPrepareFlagsInt, psRGXSubmitTransferIN->pui32TQPrepareFlags,
+                               psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXSubmitTransfer_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSubmitTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psTransferContextInt,
+                                                                                       psRGXSubmitTransferIN->hTransferContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+                                       if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSubmitTransfer_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       IMG_UINT32 j;
+                       for (j=0;j<ui32ClientFenceCountInt[i];j++)
+                       {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSubmitTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psFenceUFOSyncPrimBlockInt[i][j],
+                                                                                       hFenceUFOSyncPrimBlockInt2[i][j],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSubmitTransfer_exit;
+                                       }
+                               }
+
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       IMG_UINT32 j;
+                       for (j=0;j<ui32ClientUpdateCountInt[i];j++)
+                       {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSubmitTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psUpdateUFOSyncPrimBlockInt[i][j],
+                                                                                       hUpdateUFOSyncPrimBlockInt2[i][j],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSubmitTransfer_exit;
+                                       }
+                               }
+
+                       }
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+               {
+                       IMG_UINT32 j;
+                       for (j=0;j<ui32ServerSyncCountInt[i];j++)
+                       {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSubmitTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerSyncInt[i][j],
+                                                                                       hServerSyncInt2[i][j],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSubmitTransfer_exit;
+                                       }
+                               }
+
+                       }
+               }
+       }
+
+       psRGXSubmitTransferOUT->eError =
+               PVRSRVRGXSubmitTransferKM(
+                                       psTransferContextInt,
+                                       psRGXSubmitTransferIN->ui32PrepareCount,
+                                       ui32ClientFenceCountInt,
+                                       psFenceUFOSyncPrimBlockInt,
+                                       ui32FenceSyncOffsetInt,
+                                       ui32FenceValueInt,
+                                       ui32ClientUpdateCountInt,
+                                       psUpdateUFOSyncPrimBlockInt,
+                                       ui32UpdateSyncOffsetInt,
+                                       ui32UpdateValueInt,
+                                       ui32ServerSyncCountInt,
+                                       ui32ServerSyncFlagsInt,
+                                       psServerSyncInt,
+                                       psRGXSubmitTransferIN->ui32NumCheckFenceFDs,
+                                       i32CheckFenceFDsInt,
+                                       psRGXSubmitTransferIN->i32UpdateFenceFD,
+                                       ui32CommandSizeInt,
+                                       ui8FWCommandInt,
+                                       ui32TQPrepareFlagsInt,
+                                       psRGXSubmitTransferIN->ui32ExternalJobReference,
+                                       psRGXSubmitTransferIN->ui32InternalJobReference);
+
+
+
+
+RGXSubmitTransfer_exit:
+       if (ui32ClientFenceCountInt)
+               OSFreeMem(ui32ClientFenceCountInt);
+       if (psFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psFenceUFOSyncPrimBlockInt);
+       if (hFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hFenceUFOSyncPrimBlockInt2);
+       if (ui32FenceSyncOffsetInt)
+               OSFreeMem(ui32FenceSyncOffsetInt);
+       if (ui32FenceValueInt)
+               OSFreeMem(ui32FenceValueInt);
+       if (ui32ClientUpdateCountInt)
+               OSFreeMem(ui32ClientUpdateCountInt);
+       if (psUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psUpdateUFOSyncPrimBlockInt);
+       if (hUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hUpdateUFOSyncPrimBlockInt2);
+       if (ui32UpdateSyncOffsetInt)
+               OSFreeMem(ui32UpdateSyncOffsetInt);
+       if (ui32UpdateValueInt)
+               OSFreeMem(ui32UpdateValueInt);
+       if (ui32ServerSyncCountInt)
+               OSFreeMem(ui32ServerSyncCountInt);
+       if (ui32ServerSyncFlagsInt)
+               OSFreeMem(ui32ServerSyncFlagsInt);
+       if (psServerSyncInt)
+               OSFreeMem(psServerSyncInt);
+       if (hServerSyncInt2)
+               OSFreeMem(hServerSyncInt2);
+       if (i32CheckFenceFDsInt)
+               OSFreeMem(i32CheckFenceFDsInt);
+       if (ui32CommandSizeInt)
+               OSFreeMem(ui32CommandSizeInt);
+       if (ui8FWCommandInt)
+               OSFreeMem(ui8FWCommandInt);
+       if (ui32TQPrepareFlagsInt)
+               OSFreeMem(ui32TQPrepareFlagsInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityIN,
+                                         PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXSetTransferContextPriorityOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psTransferContextInt,
+                                                                                       psRGXSetTransferContextPriorityIN->hTransferContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+                                       if(psRGXSetTransferContextPriorityOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXSetTransferContextPriority_exit;
+                                       }
+                               }
+
+
+       psRGXSetTransferContextPriorityOUT->eError =
+               PVRSRVRGXSetTransferContextPriorityKM(psConnection,
+                                       psTransferContextInt,
+                                       psRGXSetTransferContextPriorityIN->ui32Priority);
+
+
+
+
+RGXSetTransferContextPriority_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferIN,
+                                         PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL;
+       IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = IMG_NULL;
+       IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL;
+       IMG_HANDLE *hServerSyncsInt2 = IMG_NULL;
+       IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
+
+
+
+
+       if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
+       {
+               psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientFenceUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+               hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
+               if (!hClientFenceUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock,
+                               psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceSyncOffsetInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset,
+                               psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
+       {
+               ui32ClientFenceValueInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
+               if (!ui32ClientFenceValueInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientFenceValue, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickSyncTransferIN->pui32ClientFenceValue,
+                               psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
+       {
+               psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psClientUpdateUFOSyncPrimBlockInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+               hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
+               if (!hClientUpdateUFOSyncPrimBlockInt2)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock,
+                               psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateSyncOffsetInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset,
+                               psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
+       {
+               ui32ClientUpdateValueInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
+               if (!ui32ClientUpdateValueInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientUpdateValue, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickSyncTransferIN->pui32ClientUpdateValue,
+                               psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
+       {
+               ui32ServerSyncFlagsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
+               if (!ui32ServerSyncFlagsInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ServerSyncFlags, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncTransferIN->pui32ServerSyncFlags,
+                               psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
+       {
+               psServerSyncsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerSyncsInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+               hServerSyncsInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
+               if (!hServerSyncsInt2)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phServerSyncs, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickSyncTransferIN->phServerSyncs,
+                               psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+       if (psRGXKickSyncTransferIN->ui32NumCheckFenceFDs != 0)
+       {
+               i32CheckFenceFDsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
+               if (!i32CheckFenceFDsInt)
+               {
+                       psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RGXKickSyncTransfer_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pi32CheckFenceFDs, psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
+                               || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXKickSyncTransferIN->pi32CheckFenceFDs,
+                               psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
+                       {
+                               psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RGXKickSyncTransfer_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psTransferContextInt,
+                                                                                       psRGXKickSyncTransferIN->hTransferContext,
+                                                                                       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+                                       if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTransfer_exit;
+                                       }
+                               }
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTransferIN->ui32ClientFenceCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i],
+                                                                                       hClientFenceUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTransfer_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTransferIN->ui32ClientUpdateCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i],
+                                                                                       hClientUpdateUFOSyncPrimBlockInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTransfer_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psRGXKickSyncTransferIN->ui32ServerSyncCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXKickSyncTransferOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerSyncsInt[i],
+                                                                                       hServerSyncsInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXKickSyncTransfer_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psRGXKickSyncTransferOUT->eError =
+               PVRSRVRGXKickSyncTransferKM(
+                                       psTransferContextInt,
+                                       psRGXKickSyncTransferIN->ui32ClientFenceCount,
+                                       psClientFenceUFOSyncPrimBlockInt,
+                                       ui32ClientFenceSyncOffsetInt,
+                                       ui32ClientFenceValueInt,
+                                       psRGXKickSyncTransferIN->ui32ClientUpdateCount,
+                                       psClientUpdateUFOSyncPrimBlockInt,
+                                       ui32ClientUpdateSyncOffsetInt,
+                                       ui32ClientUpdateValueInt,
+                                       psRGXKickSyncTransferIN->ui32ServerSyncCount,
+                                       ui32ServerSyncFlagsInt,
+                                       psServerSyncsInt,
+                                       psRGXKickSyncTransferIN->ui32NumCheckFenceFDs,
+                                       i32CheckFenceFDsInt,
+                                       psRGXKickSyncTransferIN->i32UpdateFenceFD,
+                                       psRGXKickSyncTransferIN->ui32TQPrepareFlags);
+
+
+
+
+RGXKickSyncTransfer_exit:
+       if (psClientFenceUFOSyncPrimBlockInt)
+               OSFreeMem(psClientFenceUFOSyncPrimBlockInt);
+       if (hClientFenceUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientFenceUFOSyncPrimBlockInt2);
+       if (ui32ClientFenceSyncOffsetInt)
+               OSFreeMem(ui32ClientFenceSyncOffsetInt);
+       if (ui32ClientFenceValueInt)
+               OSFreeMem(ui32ClientFenceValueInt);
+       if (psClientUpdateUFOSyncPrimBlockInt)
+               OSFreeMem(psClientUpdateUFOSyncPrimBlockInt);
+       if (hClientUpdateUFOSyncPrimBlockInt2)
+               OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2);
+       if (ui32ClientUpdateSyncOffsetInt)
+               OSFreeMem(ui32ClientUpdateSyncOffsetInt);
+       if (ui32ClientUpdateValueInt)
+               OSFreeMem(ui32ClientUpdateValueInt);
+       if (ui32ServerSyncFlagsInt)
+               OSFreeMem(ui32ServerSyncFlagsInt);
+       if (psServerSyncsInt)
+               OSFreeMem(psServerSyncsInt);
+       if (hServerSyncsInt2)
+               OSFreeMem(hServerSyncsInt2);
+       if (i32CheckFenceFDsInt)
+               OSFreeMem(i32CheckFenceFDsInt);
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRGXTQBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRGXTQBridge(IMG_VOID);
+
+/*
+ * Register all RGXTQ functions with services
+ */
+PVRSRV_ERROR InitRGXTQBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT, PVRSRVBridgeRGXCreateTransferContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT, PVRSRVBridgeRGXDestroyTransferContext,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER, PVRSRVBridgeRGXSubmitTransfer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY, PVRSRVBridgeRGXSetTransferContextPriority,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXKICKSYNCTRANSFER, PVRSRVBridgeRGXKickSyncTransfer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxtq functions with services
+ */
+PVRSRV_ERROR DeinitRGXTQBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/ri_bridge/client_ri_bridge.h b/drivers/gpu/rogue_m/generated/ri_bridge/client_ri_bridge.h
new file mode 100644 (file)
index 0000000..ec290bf
--- /dev/null
@@ -0,0 +1,84 @@
+/*************************************************************************/ /*!
+@File
+@Title          Client bridge header for ri
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exports the client bridge functions for ri
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CLIENT_RI_BRIDGE_H
+#define CLIENT_RI_BRIDGE_H
+
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+
+#include "common_ri_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIWritePMREntry(IMG_HANDLE hBridge,
+                                                            IMG_HANDLE hPMRHandle,
+                                                            IMG_UINT32 ui32TextASize,
+                                                            const IMG_CHAR *puiTextA,
+                                                            IMG_UINT64 ui64LogicalSize);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hPMRHandle,
+                                                                IMG_UINT32 ui32TextBSize,
+                                                                const IMG_CHAR *puiTextB,
+                                                                IMG_UINT64 ui64Offset,
+                                                                IMG_UINT64 ui64Size,
+                                                                IMG_BOOL bIsImport,
+                                                                IMG_BOOL bIsExportable,
+                                                                IMG_HANDLE *phRIHandle);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge,
+                                                                IMG_HANDLE hRIHandle,
+                                                                IMG_DEV_VIRTADDR sAddr);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge,
+                                                                 IMG_HANDLE hRIHandle);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpList(IMG_HANDLE hBridge,
+                                                       IMG_HANDLE hPMRHandle);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpAll(IMG_HANDLE hBridge);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRIDumpProcess(IMG_HANDLE hBridge,
+                                                          IMG_PID ui32Pid);
+
+
+#endif /* CLIENT_RI_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/ri_bridge/common_ri_bridge.h b/drivers/gpu/rogue_m/generated/ri_bridge/common_ri_bridge.h
new file mode 100644 (file)
index 0000000..415360d
--- /dev/null
@@ -0,0 +1,195 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for ri
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for ri
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RI_BRIDGE_H
+#define COMMON_RI_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "ri_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_RI_CMD_FIRST                     0
+#define PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY                       PVRSRV_BRIDGE_RI_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY                   PVRSRV_BRIDGE_RI_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR                   PVRSRV_BRIDGE_RI_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY                  PVRSRV_BRIDGE_RI_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RI_RIDUMPLIST                    PVRSRV_BRIDGE_RI_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RI_RIDUMPALL                     PVRSRV_BRIDGE_RI_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RI_RIDUMPPROCESS                 PVRSRV_BRIDGE_RI_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RI_CMD_LAST                      (PVRSRV_BRIDGE_RI_CMD_FIRST+6)
+
+
+/*******************************************
+            RIWritePMREntry          
+ *******************************************/
+
+/* Bridge in structure for RIWritePMREntry */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY_TAG
+{
+       IMG_HANDLE hPMRHandle;
+       IMG_UINT32 ui32TextASize;
+       const IMG_CHAR * puiTextA;
+       IMG_UINT64 ui64LogicalSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY;
+
+
+/* Bridge out structure for RIWritePMREntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY;
+
+/*******************************************
+            RIWriteMEMDESCEntry          
+ *******************************************/
+
+/* Bridge in structure for RIWriteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY_TAG
+{
+       IMG_HANDLE hPMRHandle;
+       IMG_UINT32 ui32TextBSize;
+       const IMG_CHAR * puiTextB;
+       IMG_UINT64 ui64Offset;
+       IMG_UINT64 ui64Size;
+       IMG_BOOL bIsImport;
+       IMG_BOOL bIsExportable;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY;
+
+
+/* Bridge out structure for RIWriteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY_TAG
+{
+       IMG_HANDLE hRIHandle;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY;
+
+/*******************************************
+            RIUpdateMEMDESCAddr          
+ *******************************************/
+
+/* Bridge in structure for RIUpdateMEMDESCAddr */
+typedef struct PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR_TAG
+{
+       IMG_HANDLE hRIHandle;
+       IMG_DEV_VIRTADDR sAddr;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR;
+
+
+/* Bridge out structure for RIUpdateMEMDESCAddr */
+typedef struct PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR;
+
+/*******************************************
+            RIDeleteMEMDESCEntry          
+ *******************************************/
+
+/* Bridge in structure for RIDeleteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY_TAG
+{
+       IMG_HANDLE hRIHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY;
+
+
+/* Bridge out structure for RIDeleteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY;
+
+/*******************************************
+            RIDumpList          
+ *******************************************/
+
+/* Bridge in structure for RIDumpList */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPLIST_TAG
+{
+       IMG_HANDLE hPMRHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIDUMPLIST;
+
+
+/* Bridge out structure for RIDumpList */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPLIST_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIDUMPLIST;
+
+/*******************************************
+            RIDumpAll          
+ *******************************************/
+
+/* Bridge in structure for RIDumpAll */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPALL_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIDUMPALL;
+
+
+/* Bridge out structure for RIDumpAll */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPALL_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIDUMPALL;
+
+/*******************************************
+            RIDumpProcess          
+ *******************************************/
+
+/* Bridge in structure for RIDumpProcess */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPPROCESS_TAG
+{
+       IMG_PID ui32Pid;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RIDUMPPROCESS;
+
+
+/* Bridge out structure for RIDumpProcess */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPPROCESS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RIDUMPPROCESS;
+
+#endif /* COMMON_RI_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/ri_bridge/server_ri_bridge.c b/drivers/gpu/rogue_m/generated/ri_bridge/server_ri_bridge.c
new file mode 100644 (file)
index 0000000..ca370d9
--- /dev/null
@@ -0,0 +1,456 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for ri
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for ri
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "ri_server.h"
+
+
+#include "common_ri_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRIWritePMREntry(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY *psRIWritePMREntryIN,
+                                         PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY *psRIWritePMREntryOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRHandleInt = IMG_NULL;
+       IMG_CHAR *uiTextAInt = IMG_NULL;
+
+
+
+
+       if (psRIWritePMREntryIN->ui32TextASize != 0)
+       {
+               uiTextAInt = OSAllocMem(psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR));
+               if (!uiTextAInt)
+               {
+                       psRIWritePMREntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RIWritePMREntry_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRIWritePMREntryIN->puiTextA, psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiTextAInt, psRIWritePMREntryIN->puiTextA,
+                               psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psRIWritePMREntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RIWritePMREntry_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRIWritePMREntryOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRHandleInt,
+                                                                                       psRIWritePMREntryIN->hPMRHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRIWritePMREntryOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RIWritePMREntry_exit;
+                                       }
+                               }
+
+
+       psRIWritePMREntryOUT->eError =
+               RIWritePMREntryKM(
+                                       psPMRHandleInt,
+                                       psRIWritePMREntryIN->ui32TextASize,
+                                       uiTextAInt,
+                                       psRIWritePMREntryIN->ui64LogicalSize);
+
+
+
+
+RIWritePMREntry_exit:
+       if (uiTextAInt)
+               OSFreeMem(uiTextAInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIWriteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryIN,
+                                         PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRHandleInt = IMG_NULL;
+       IMG_CHAR *uiTextBInt = IMG_NULL;
+       RI_HANDLE psRIHandleInt = IMG_NULL;
+
+
+
+
+       if (psRIWriteMEMDESCEntryIN->ui32TextBSize != 0)
+       {
+               uiTextBInt = OSAllocMem(psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR));
+               if (!uiTextBInt)
+               {
+                       psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto RIWriteMEMDESCEntry_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRIWriteMEMDESCEntryIN->puiTextB, psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiTextBInt, psRIWriteMEMDESCEntryIN->puiTextB,
+                               psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto RIWriteMEMDESCEntry_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRIWriteMEMDESCEntryOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRHandleInt,
+                                                                                       psRIWriteMEMDESCEntryIN->hPMRHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RIWriteMEMDESCEntry_exit;
+                                       }
+                               }
+
+
+       psRIWriteMEMDESCEntryOUT->eError =
+               RIWriteMEMDESCEntryKM(
+                                       psPMRHandleInt,
+                                       psRIWriteMEMDESCEntryIN->ui32TextBSize,
+                                       uiTextBInt,
+                                       psRIWriteMEMDESCEntryIN->ui64Offset,
+                                       psRIWriteMEMDESCEntryIN->ui64Size,
+                                       psRIWriteMEMDESCEntryIN->bIsImport,
+                                       psRIWriteMEMDESCEntryIN->bIsExportable,
+                                       &psRIHandleInt);
+       /* Exit early if bridged call fails */
+       if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
+       {
+               goto RIWriteMEMDESCEntry_exit;
+       }
+
+
+       psRIWriteMEMDESCEntryOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psRIWriteMEMDESCEntryOUT->hRIHandle,
+                                                       (IMG_VOID *) psRIHandleInt,
+                                                       PVRSRV_HANDLE_TYPE_RI_HANDLE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&RIDeleteMEMDESCEntryKM);
+       if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
+       {
+               goto RIWriteMEMDESCEntry_exit;
+       }
+
+
+
+
+RIWriteMEMDESCEntry_exit:
+       if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
+       {
+               if (psRIHandleInt)
+               {
+                       RIDeleteMEMDESCEntryKM(psRIHandleInt);
+               }
+       }
+
+       if (uiTextBInt)
+               OSFreeMem(uiTextBInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIUpdateMEMDESCAddr(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrIN,
+                                         PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       RI_HANDLE psRIHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRIUpdateMEMDESCAddrOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psRIHandleInt,
+                                                                                       psRIUpdateMEMDESCAddrIN->hRIHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_RI_HANDLE);
+                                       if(psRIUpdateMEMDESCAddrOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RIUpdateMEMDESCAddr_exit;
+                                       }
+                               }
+
+
+       psRIUpdateMEMDESCAddrOUT->eError =
+               RIUpdateMEMDESCAddrKM(
+                                       psRIHandleInt,
+                                       psRIUpdateMEMDESCAddrIN->sAddr);
+
+
+
+
+RIUpdateMEMDESCAddr_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIDeleteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY *psRIDeleteMEMDESCEntryIN,
+                                         PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY *psRIDeleteMEMDESCEntryOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psRIDeleteMEMDESCEntryOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psRIDeleteMEMDESCEntryIN->hRIHandle,
+                                       PVRSRV_HANDLE_TYPE_RI_HANDLE);
+       if ((psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_OK) && (psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto RIDeleteMEMDESCEntry_exit;
+       }
+
+
+
+RIDeleteMEMDESCEntry_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIDumpList(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIDUMPLIST *psRIDumpListIN,
+                                         PVRSRV_BRIDGE_OUT_RIDUMPLIST *psRIDumpListOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRIDumpListOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRHandleInt,
+                                                                                       psRIDumpListIN->hPMRHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psRIDumpListOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RIDumpList_exit;
+                                       }
+                               }
+
+
+       psRIDumpListOUT->eError =
+               RIDumpListKM(
+                                       psPMRHandleInt);
+
+
+
+
+RIDumpList_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIDumpAll(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIDUMPALL *psRIDumpAllIN,
+                                         PVRSRV_BRIDGE_OUT_RIDUMPALL *psRIDumpAllOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psRIDumpAllIN);
+
+
+
+
+
+
+       psRIDumpAllOUT->eError =
+               RIDumpAllKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRIDumpProcess(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RIDUMPPROCESS *psRIDumpProcessIN,
+                                         PVRSRV_BRIDGE_OUT_RIDUMPPROCESS *psRIDumpProcessOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+       psRIDumpProcessOUT->eError =
+               RIDumpProcessKM(
+                                       psRIDumpProcessIN->ui32Pid);
+
+
+
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitRIBridge(IMG_VOID);
+PVRSRV_ERROR DeinitRIBridge(IMG_VOID);
+
+/*
+ * Register all RI functions with services
+ */
+PVRSRV_ERROR InitRIBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY, PVRSRVBridgeRIWritePMREntry,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY, PVRSRVBridgeRIWriteMEMDESCEntry,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR, PVRSRVBridgeRIUpdateMEMDESCAddr,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY, PVRSRVBridgeRIDeleteMEMDESCEntry,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPLIST, PVRSRVBridgeRIDumpList,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPALL, PVRSRVBridgeRIDumpAll,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_RI, PVRSRV_BRIDGE_RI_RIDUMPPROCESS, PVRSRVBridgeRIDumpProcess,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all ri functions with services
+ */
+PVRSRV_ERROR DeinitRIBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/smm_bridge/common_smm_bridge.h b/drivers/gpu/rogue_m/generated/smm_bridge/common_smm_bridge.h
new file mode 100644 (file)
index 0000000..52c5b1c
--- /dev/null
@@ -0,0 +1,115 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for smm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for smm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_SMM_BRIDGE_H
+#define COMMON_SMM_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+
+
+#define PVRSRV_BRIDGE_SMM_CMD_FIRST                    0
+#define PVRSRV_BRIDGE_SMM_PMRSECUREEXPORTPMR                   PVRSRV_BRIDGE_SMM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SMM_PMRSECUREUNEXPORTPMR                 PVRSRV_BRIDGE_SMM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SMM_PMRSECUREIMPORTPMR                   PVRSRV_BRIDGE_SMM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SMM_CMD_LAST                     (PVRSRV_BRIDGE_SMM_CMD_FIRST+2)
+
+
+/*******************************************
+            PMRSecureExportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRSecureExportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRSECUREEXPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRSECUREEXPORTPMR;
+
+
+/* Bridge out structure for PMRSecureExportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRSECUREEXPORTPMR_TAG
+{
+       IMG_SECURE_TYPE Export;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRSECUREEXPORTPMR;
+
+/*******************************************
+            PMRSecureUnexportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRSecureUnexportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRSECUREUNEXPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRSECUREUNEXPORTPMR;
+
+
+/* Bridge out structure for PMRSecureUnexportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRSECUREUNEXPORTPMR_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRSECUREUNEXPORTPMR;
+
+/*******************************************
+            PMRSecureImportPMR          
+ *******************************************/
+
+/* Bridge in structure for PMRSecureImportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRSECUREIMPORTPMR_TAG
+{
+       IMG_SECURE_TYPE Export;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PMRSECUREIMPORTPMR;
+
+
+/* Bridge out structure for PMRSecureImportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRSECUREIMPORTPMR_TAG
+{
+       IMG_HANDLE hPMR;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_DEVMEM_ALIGN_T sAlign;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PMRSECUREIMPORTPMR;
+
+#endif /* COMMON_SMM_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/smm_bridge/server_smm_bridge.c b/drivers/gpu/rogue_m/generated/smm_bridge/server_smm_bridge.c
new file mode 100644 (file)
index 0000000..4fb7d5c
--- /dev/null
@@ -0,0 +1,281 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for smm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for smm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "pmr.h"
+#include "secure_export.h"
+
+
+#include "common_smm_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgePMRSecureExportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRSECUREEXPORTPMR *psPMRSecureExportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRSECUREEXPORTPMR *psPMRSecureExportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+       PMR * psPMROutInt = IMG_NULL;
+       IMG_HANDLE hPMROutInt = IMG_NULL;
+       CONNECTION_DATA *psSecureConnection;
+
+
+
+
+
+       PMRLock();
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psPMRSecureExportPMROUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psPMRInt,
+                                                                                       psPMRSecureExportPMRIN->hPMR,
+                                                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+                                       if(psPMRSecureExportPMROUT->eError != PVRSRV_OK)
+                                       {
+                                               PMRUnlock();
+                                               goto PMRSecureExportPMR_exit;
+                                       }
+                               }
+
+
+       psPMRSecureExportPMROUT->eError =
+               PMRSecureExportPMR(psConnection,
+                                       psPMRInt,
+                                       &psPMRSecureExportPMROUT->Export,
+                                       &psPMROutInt, &psSecureConnection);
+       /* Exit early if bridged call fails */
+       if(psPMRSecureExportPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PMRSecureExportPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psPMRSecureExportPMROUT->eError = PVRSRVAllocHandle(psSecureConnection->psHandleBase,
+                                                       &hPMROutInt,
+                                                       (IMG_VOID *) psPMROutInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&PMRSecureUnexportPMR);
+       if (psPMRSecureExportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRSecureExportPMR_exit;
+       }
+
+
+
+
+PMRSecureExportPMR_exit:
+       if (psPMRSecureExportPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMROutInt)
+               {
+                       PMRSecureUnexportPMR(psPMROutInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRSecureUnexportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRSECUREUNEXPORTPMR *psPMRSecureUnexportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRSECUREUNEXPORTPMR *psPMRSecureUnexportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+       PMRLock();
+
+
+
+
+       psPMRSecureUnexportPMROUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psPMRSecureUnexportPMRIN->hPMR,
+                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT);
+       if ((psPMRSecureUnexportPMROUT->eError != PVRSRV_OK) && (psPMRSecureUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               PMRUnlock();
+               goto PMRSecureUnexportPMR_exit;
+       }
+
+       PMRUnlock();
+
+
+PMRSecureUnexportPMR_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgePMRSecureImportPMR(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_PMRSECUREIMPORTPMR *psPMRSecureImportPMRIN,
+                                         PVRSRV_BRIDGE_OUT_PMRSECUREIMPORTPMR *psPMRSecureImportPMROUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PMR * psPMRInt = IMG_NULL;
+
+
+
+
+
+       PMRLock();
+
+
+       psPMRSecureImportPMROUT->eError =
+               PMRSecureImportPMR(
+                                       psPMRSecureImportPMRIN->Export,
+                                       &psPMRInt,
+                                       &psPMRSecureImportPMROUT->uiSize,
+                                       &psPMRSecureImportPMROUT->sAlign);
+       /* Exit early if bridged call fails */
+       if(psPMRSecureImportPMROUT->eError != PVRSRV_OK)
+       {
+               PMRUnlock();
+               goto PMRSecureImportPMR_exit;
+       }
+       PMRUnlock();
+
+
+       psPMRSecureImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psPMRSecureImportPMROUT->hPMR,
+                                                       (IMG_VOID *) psPMRInt,
+                                                       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+       if (psPMRSecureImportPMROUT->eError != PVRSRV_OK)
+       {
+               goto PMRSecureImportPMR_exit;
+       }
+
+
+
+
+PMRSecureImportPMR_exit:
+       if (psPMRSecureImportPMROUT->eError != PVRSRV_OK)
+       {
+               if (psPMRInt)
+               {
+                       PMRUnrefPMR(psPMRInt);
+               }
+       }
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitSMMBridge(IMG_VOID);
+PVRSRV_ERROR DeinitSMMBridge(IMG_VOID);
+
+/*
+ * Register all SMM functions with services
+ */
+PVRSRV_ERROR InitSMMBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SMM, PVRSRV_BRIDGE_SMM_PMRSECUREEXPORTPMR, PVRSRVBridgePMRSecureExportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SMM, PVRSRV_BRIDGE_SMM_PMRSECUREUNEXPORTPMR, PVRSRVBridgePMRSecureUnexportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SMM, PVRSRV_BRIDGE_SMM_PMRSECUREIMPORTPMR, PVRSRVBridgePMRSecureImportPMR,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all smm functions with services
+ */
+PVRSRV_ERROR DeinitSMMBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/srvcore_bridge/common_srvcore_bridge.h b/drivers/gpu/rogue_m/generated/srvcore_bridge/common_srvcore_bridge.h
new file mode 100644 (file)
index 0000000..c37fb1c
--- /dev/null
@@ -0,0 +1,387 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for srvcore
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for srvcore
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_SRVCORE_BRIDGE_H
+#define COMMON_SRVCORE_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_device_types.h"
+#include "cache_external.h"
+
+
+#define PVRSRV_BRIDGE_SRVCORE_CMD_FIRST                        0
+#define PVRSRV_BRIDGE_SRVCORE_CONNECT                  PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SRVCORE_DISCONNECT                       PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SRVCORE_ENUMERATEDEVICES                 PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SRVCORE_ACQUIREDEVICEDATA                        PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+3
+#define PVRSRV_BRIDGE_SRVCORE_RELEASEDEVICEDATA                        PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+4
+#define PVRSRV_BRIDGE_SRVCORE_INITSRVDISCONNECT                        PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+5
+#define PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT                 PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+6
+#define PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT                 PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+7
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN                  PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+8
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT                  PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+9
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE                 PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+10
+#define PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO                    PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+11
+#define PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED                 PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+12
+#define PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT                      PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13
+#define PVRSRV_BRIDGE_SRVCORE_KICKDEVICES                      PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+14
+#define PVRSRV_BRIDGE_SRVCORE_RESETHWRLOGS                     PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+15
+#define PVRSRV_BRIDGE_SRVCORE_SOFTRESET                        PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16
+#define PVRSRV_BRIDGE_SRVCORE_CMD_LAST                 (PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16)
+
+
+/*******************************************
+            Connect          
+ *******************************************/
+
+/* Bridge in structure for Connect */
+typedef struct PVRSRV_BRIDGE_IN_CONNECT_TAG
+{
+       IMG_UINT32 ui32Flags;
+       IMG_UINT32 ui32ClientBuildOptions;
+       IMG_UINT32 ui32ClientDDKVersion;
+       IMG_UINT32 ui32ClientDDKBuild;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CONNECT;
+
+
+/* Bridge out structure for Connect */
+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_TAG
+{
+       IMG_UINT8 ui8KernelArch;
+       IMG_UINT32 ui32Log2PageSize;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CONNECT;
+
+/*******************************************
+            Disconnect          
+ *******************************************/
+
+/* Bridge in structure for Disconnect */
+typedef struct PVRSRV_BRIDGE_IN_DISCONNECT_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DISCONNECT;
+
+
+/* Bridge out structure for Disconnect */
+typedef struct PVRSRV_BRIDGE_OUT_DISCONNECT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DISCONNECT;
+
+/*******************************************
+            EnumerateDevices          
+ *******************************************/
+
+/* Bridge in structure for EnumerateDevices */
+typedef struct PVRSRV_BRIDGE_IN_ENUMERATEDEVICES_TAG
+{
+       /* Output pointer peDeviceType is also an implied input */
+       PVRSRV_DEVICE_TYPE * peDeviceType;
+       /* Output pointer peDeviceClass is also an implied input */
+       PVRSRV_DEVICE_CLASS * peDeviceClass;
+       /* Output pointer pui32DeviceIndex is also an implied input */
+       IMG_UINT32 * pui32DeviceIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_ENUMERATEDEVICES;
+
+
+/* Bridge out structure for EnumerateDevices */
+typedef struct PVRSRV_BRIDGE_OUT_ENUMERATEDEVICES_TAG
+{
+       IMG_UINT32 ui32NumDevices;
+       PVRSRV_DEVICE_TYPE * peDeviceType;
+       PVRSRV_DEVICE_CLASS * peDeviceClass;
+       IMG_UINT32 * pui32DeviceIndex;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_ENUMERATEDEVICES;
+
+/*******************************************
+            AcquireDeviceData          
+ *******************************************/
+
+/* Bridge in structure for AcquireDeviceData */
+typedef struct PVRSRV_BRIDGE_IN_ACQUIREDEVICEDATA_TAG
+{
+       IMG_UINT32 ui32DevIndex;
+       PVRSRV_DEVICE_TYPE eDeviceType;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_ACQUIREDEVICEDATA;
+
+
+/* Bridge out structure for AcquireDeviceData */
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIREDEVICEDATA_TAG
+{
+       IMG_HANDLE hDevCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_ACQUIREDEVICEDATA;
+
+/*******************************************
+            ReleaseDeviceData          
+ *******************************************/
+
+/* Bridge in structure for ReleaseDeviceData */
+typedef struct PVRSRV_BRIDGE_IN_RELEASEDEVICEDATA_TAG
+{
+       IMG_HANDLE hDevCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RELEASEDEVICEDATA;
+
+
+/* Bridge out structure for ReleaseDeviceData */
+typedef struct PVRSRV_BRIDGE_OUT_RELEASEDEVICEDATA_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RELEASEDEVICEDATA;
+
+/*******************************************
+            InitSrvDisconnect          
+ *******************************************/
+
+/* Bridge in structure for InitSrvDisconnect */
+typedef struct PVRSRV_BRIDGE_IN_INITSRVDISCONNECT_TAG
+{
+       IMG_BOOL bInitSuccesful;
+       IMG_UINT32 ui32ClientBuildOptions;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_INITSRVDISCONNECT;
+
+
+/* Bridge out structure for InitSrvDisconnect */
+typedef struct PVRSRV_BRIDGE_OUT_INITSRVDISCONNECT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_INITSRVDISCONNECT;
+
+/*******************************************
+            AcquireGlobalEventObject          
+ *******************************************/
+
+/* Bridge in structure for AcquireGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT;
+
+
+/* Bridge out structure for AcquireGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT_TAG
+{
+       IMG_HANDLE hGlobalEventObject;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT;
+
+/*******************************************
+            ReleaseGlobalEventObject          
+ *******************************************/
+
+/* Bridge in structure for ReleaseGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT_TAG
+{
+       IMG_HANDLE hGlobalEventObject;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT;
+
+
+/* Bridge out structure for ReleaseGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT;
+
+/*******************************************
+            EventObjectOpen          
+ *******************************************/
+
+/* Bridge in structure for EventObjectOpen */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN_TAG
+{
+       IMG_HANDLE hEventObject;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN;
+
+
+/* Bridge out structure for EventObjectOpen */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN_TAG
+{
+       IMG_HANDLE hOSEvent;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN;
+
+/*******************************************
+            EventObjectWait          
+ *******************************************/
+
+/* Bridge in structure for EventObjectWait */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT_TAG
+{
+       IMG_HANDLE hOSEventKM;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT;
+
+
+/* Bridge out structure for EventObjectWait */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT;
+
+/*******************************************
+            EventObjectClose          
+ *******************************************/
+
+/* Bridge in structure for EventObjectClose */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE_TAG
+{
+       IMG_HANDLE hOSEventKM;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE;
+
+
+/* Bridge out structure for EventObjectClose */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE;
+
+/*******************************************
+            DumpDebugInfo          
+ *******************************************/
+
+/* Bridge in structure for DumpDebugInfo */
+typedef struct PVRSRV_BRIDGE_IN_DUMPDEBUGINFO_TAG
+{
+       IMG_UINT32 ui32ui32VerbLevel;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DUMPDEBUGINFO;
+
+
+/* Bridge out structure for DumpDebugInfo */
+typedef struct PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO;
+
+/*******************************************
+            GetDevClockSpeed          
+ *******************************************/
+
+/* Bridge in structure for GetDevClockSpeed */
+typedef struct PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED;
+
+
+/* Bridge out structure for GetDevClockSpeed */
+typedef struct PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED_TAG
+{
+       IMG_UINT32 ui32ui32ClockSpeed;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED;
+
+/*******************************************
+            HWOpTimeout          
+ *******************************************/
+
+/* Bridge in structure for HWOpTimeout */
+typedef struct PVRSRV_BRIDGE_IN_HWOPTIMEOUT_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_HWOPTIMEOUT;
+
+
+/* Bridge out structure for HWOpTimeout */
+typedef struct PVRSRV_BRIDGE_OUT_HWOPTIMEOUT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_HWOPTIMEOUT;
+
+/*******************************************
+            KickDevices          
+ *******************************************/
+
+/* Bridge in structure for KickDevices */
+typedef struct PVRSRV_BRIDGE_IN_KICKDEVICES_TAG
+{
+        IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_KICKDEVICES;
+
+
+/* Bridge out structure for KickDevices */
+typedef struct PVRSRV_BRIDGE_OUT_KICKDEVICES_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_KICKDEVICES;
+
+/*******************************************
+            ResetHWRLogs          
+ *******************************************/
+
+/* Bridge in structure for ResetHWRLogs */
+typedef struct PVRSRV_BRIDGE_IN_RESETHWRLOGS_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RESETHWRLOGS;
+
+
+/* Bridge out structure for ResetHWRLogs */
+typedef struct PVRSRV_BRIDGE_OUT_RESETHWRLOGS_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RESETHWRLOGS;
+
+/*******************************************
+            SoftReset          
+ *******************************************/
+
+/* Bridge in structure for SoftReset */
+typedef struct PVRSRV_BRIDGE_IN_SOFTRESET_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT64 ui64ResetValue1;
+       IMG_UINT64 ui64ResetValue2;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SOFTRESET;
+
+
+/* Bridge out structure for SoftReset */
+typedef struct PVRSRV_BRIDGE_OUT_SOFTRESET_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SOFTRESET;
+
+#endif /* COMMON_SRVCORE_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/srvcore_bridge/server_srvcore_bridge.c b/drivers/gpu/rogue_m/generated/srvcore_bridge/server_srvcore_bridge.c
new file mode 100644 (file)
index 0000000..6b21060
--- /dev/null
@@ -0,0 +1,867 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for srvcore
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for srvcore
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "srvcore.h"
+#include "pvrsrv.h"
+
+
+#include "common_srvcore_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+static PVRSRV_ERROR ReleaseDevCookie(IMG_VOID *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       return PVRSRV_OK;
+}
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeConnect(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_CONNECT *psConnectIN,
+                                         PVRSRV_BRIDGE_OUT_CONNECT *psConnectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+       psConnectOUT->eError =
+               PVRSRVConnectKM(psConnection,
+                                       psConnectIN->ui32Flags,
+                                       psConnectIN->ui32ClientBuildOptions,
+                                       psConnectIN->ui32ClientDDKVersion,
+                                       psConnectIN->ui32ClientDDKBuild,
+                                       &psConnectOUT->ui8KernelArch,
+                                       &psConnectOUT->ui32Log2PageSize);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDisconnect(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DISCONNECT *psDisconnectIN,
+                                         PVRSRV_BRIDGE_OUT_DISCONNECT *psDisconnectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psDisconnectIN);
+
+
+
+
+
+
+       psDisconnectOUT->eError =
+               PVRSRVDisconnectKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeEnumerateDevices(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_ENUMERATEDEVICES *psEnumerateDevicesIN,
+                                         PVRSRV_BRIDGE_OUT_ENUMERATEDEVICES *psEnumerateDevicesOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       PVRSRV_DEVICE_TYPE *peDeviceTypeInt = IMG_NULL;
+       PVRSRV_DEVICE_CLASS *peDeviceClassInt = IMG_NULL;
+       IMG_UINT32 *pui32DeviceIndexInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psEnumerateDevicesIN);
+
+       psEnumerateDevicesOUT->peDeviceType = psEnumerateDevicesIN->peDeviceType;
+       psEnumerateDevicesOUT->peDeviceClass = psEnumerateDevicesIN->peDeviceClass;
+       psEnumerateDevicesOUT->pui32DeviceIndex = psEnumerateDevicesIN->pui32DeviceIndex;
+
+
+       
+       {
+               peDeviceTypeInt = OSAllocMem(PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_TYPE));
+               if (!peDeviceTypeInt)
+               {
+                       psEnumerateDevicesOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto EnumerateDevices_exit;
+               }
+       }
+
+       
+       {
+               peDeviceClassInt = OSAllocMem(PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_CLASS));
+               if (!peDeviceClassInt)
+               {
+                       psEnumerateDevicesOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto EnumerateDevices_exit;
+               }
+       }
+
+       
+       {
+               pui32DeviceIndexInt = OSAllocMem(PVRSRV_MAX_DEVICES * sizeof(IMG_UINT32));
+               if (!pui32DeviceIndexInt)
+               {
+                       psEnumerateDevicesOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto EnumerateDevices_exit;
+               }
+       }
+
+
+
+
+       psEnumerateDevicesOUT->eError =
+               PVRSRVEnumerateDevicesKM(
+                                       &psEnumerateDevicesOUT->ui32NumDevices,
+                                       peDeviceTypeInt,
+                                       peDeviceClassInt,
+                                       pui32DeviceIndexInt);
+
+
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psEnumerateDevicesOUT->peDeviceType, (PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_TYPE))) 
+               || (OSCopyToUser(NULL, psEnumerateDevicesOUT->peDeviceType, peDeviceTypeInt,
+               (PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_TYPE))) != PVRSRV_OK) )
+       {
+               psEnumerateDevicesOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto EnumerateDevices_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psEnumerateDevicesOUT->peDeviceClass, (PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_CLASS))) 
+               || (OSCopyToUser(NULL, psEnumerateDevicesOUT->peDeviceClass, peDeviceClassInt,
+               (PVRSRV_MAX_DEVICES * sizeof(PVRSRV_DEVICE_CLASS))) != PVRSRV_OK) )
+       {
+               psEnumerateDevicesOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto EnumerateDevices_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psEnumerateDevicesOUT->pui32DeviceIndex, (PVRSRV_MAX_DEVICES * sizeof(IMG_UINT32))) 
+               || (OSCopyToUser(NULL, psEnumerateDevicesOUT->pui32DeviceIndex, pui32DeviceIndexInt,
+               (PVRSRV_MAX_DEVICES * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+       {
+               psEnumerateDevicesOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto EnumerateDevices_exit;
+       }
+
+
+EnumerateDevices_exit:
+       if (peDeviceTypeInt)
+               OSFreeMem(peDeviceTypeInt);
+       if (peDeviceClassInt)
+               OSFreeMem(peDeviceClassInt);
+       if (pui32DeviceIndexInt)
+               OSFreeMem(pui32DeviceIndexInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeAcquireDeviceData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_ACQUIREDEVICEDATA *psAcquireDeviceDataIN,
+                                         PVRSRV_BRIDGE_OUT_ACQUIREDEVICEDATA *psAcquireDeviceDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+       psAcquireDeviceDataOUT->eError =
+               PVRSRVAcquireDeviceDataKM(
+                                       psAcquireDeviceDataIN->ui32DevIndex,
+                                       psAcquireDeviceDataIN->eDeviceType,
+                                       &hDevCookieInt);
+       /* Exit early if bridged call fails */
+       if(psAcquireDeviceDataOUT->eError != PVRSRV_OK)
+       {
+               goto AcquireDeviceData_exit;
+       }
+
+
+       psAcquireDeviceDataOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psAcquireDeviceDataOUT->hDevCookie,
+                                                       (IMG_VOID *) hDevCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_DEV_NODE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseDevCookie);
+       if (psAcquireDeviceDataOUT->eError != PVRSRV_OK)
+       {
+               goto AcquireDeviceData_exit;
+       }
+
+
+
+
+AcquireDeviceData_exit:
+       if (psAcquireDeviceDataOUT->eError != PVRSRV_OK)
+       {
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeReleaseDeviceData(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RELEASEDEVICEDATA *psReleaseDeviceDataIN,
+                                         PVRSRV_BRIDGE_OUT_RELEASEDEVICEDATA *psReleaseDeviceDataOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+       psReleaseDeviceDataOUT->eError =
+               PVRSRVReleaseDeviceDataKM(
+                                       hDevCookieInt);
+
+
+       psReleaseDeviceDataOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psReleaseDeviceDataIN->hDevCookie,
+                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+       if ((psReleaseDeviceDataOUT->eError != PVRSRV_OK) && (psReleaseDeviceDataOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto ReleaseDeviceData_exit;
+       }
+
+
+
+ReleaseDeviceData_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeInitSrvDisconnect(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_INITSRVDISCONNECT *psInitSrvDisconnectIN,
+                                         PVRSRV_BRIDGE_OUT_INITSRVDISCONNECT *psInitSrvDisconnectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+       psInitSrvDisconnectOUT->eError =
+               PVRSRVInitSrvDisconnectKM(psConnection,
+                                       psInitSrvDisconnectIN->bInitSuccesful,
+                                       psInitSrvDisconnectIN->ui32ClientBuildOptions);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeAcquireGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectIN,
+                                         PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hGlobalEventObjectInt = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(psAcquireGlobalEventObjectIN);
+
+
+
+
+
+
+       psAcquireGlobalEventObjectOUT->eError =
+               AcquireGlobalEventObjectServer(
+                                       &hGlobalEventObjectInt);
+       /* Exit early if bridged call fails */
+       if(psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
+       {
+               goto AcquireGlobalEventObject_exit;
+       }
+
+
+       psAcquireGlobalEventObjectOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psAcquireGlobalEventObjectOUT->hGlobalEventObject,
+                                                       (IMG_VOID *) hGlobalEventObjectInt,
+                                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&ReleaseGlobalEventObjectServer);
+       if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
+       {
+               goto AcquireGlobalEventObject_exit;
+       }
+
+
+
+
+AcquireGlobalEventObject_exit:
+       if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
+       {
+               if (hGlobalEventObjectInt)
+               {
+                       ReleaseGlobalEventObjectServer(hGlobalEventObjectInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeReleaseGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT *psReleaseGlobalEventObjectIN,
+                                         PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT *psReleaseGlobalEventObjectOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psReleaseGlobalEventObjectOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psReleaseGlobalEventObjectIN->hGlobalEventObject,
+                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+       if ((psReleaseGlobalEventObjectOUT->eError != PVRSRV_OK) && (psReleaseGlobalEventObjectOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto ReleaseGlobalEventObject_exit;
+       }
+
+
+
+ReleaseGlobalEventObject_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeEventObjectOpen(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN *psEventObjectOpenIN,
+                                         PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN *psEventObjectOpenOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hEventObjectInt = IMG_NULL;
+       IMG_HANDLE hOSEventInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psEventObjectOpenOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hEventObjectInt,
+                                                                                       psEventObjectOpenIN->hEventObject,
+                                                                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+                                       if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto EventObjectOpen_exit;
+                                       }
+                               }
+
+
+       psEventObjectOpenOUT->eError =
+               OSEventObjectOpen(
+                                       hEventObjectInt,
+                                       &hOSEventInt);
+       /* Exit early if bridged call fails */
+       if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+       {
+               goto EventObjectOpen_exit;
+       }
+
+
+       psEventObjectOpenOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psEventObjectOpenOUT->hOSEvent,
+                                                       (IMG_VOID *) hOSEventInt,
+                                                       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&OSEventObjectClose);
+       if (psEventObjectOpenOUT->eError != PVRSRV_OK)
+       {
+               goto EventObjectOpen_exit;
+       }
+
+
+
+
+EventObjectOpen_exit:
+       if (psEventObjectOpenOUT->eError != PVRSRV_OK)
+       {
+               if (hOSEventInt)
+               {
+                       OSEventObjectClose(hOSEventInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeEventObjectWait(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT *psEventObjectWaitIN,
+                                         PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT *psEventObjectWaitOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hOSEventKMInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psEventObjectWaitOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hOSEventKMInt,
+                                                                                       psEventObjectWaitIN->hOSEventKM,
+                                                                                       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+                                       if(psEventObjectWaitOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto EventObjectWait_exit;
+                                       }
+                               }
+
+
+       psEventObjectWaitOUT->eError =
+               OSEventObjectWait(
+                                       hOSEventKMInt);
+
+
+
+
+EventObjectWait_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeEventObjectClose(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE *psEventObjectCloseIN,
+                                         PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE *psEventObjectCloseOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psEventObjectCloseOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psEventObjectCloseIN->hOSEventKM,
+                                       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+       if ((psEventObjectCloseOUT->eError != PVRSRV_OK) && (psEventObjectCloseOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto EventObjectClose_exit;
+       }
+
+
+
+EventObjectClose_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeDumpDebugInfo(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_DUMPDEBUGINFO *psDumpDebugInfoIN,
+                                         PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO *psDumpDebugInfoOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+
+       psDumpDebugInfoOUT->eError =
+               PVRSRVDumpDebugInfoKM(
+                                       psDumpDebugInfoIN->ui32ui32VerbLevel);
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeGetDevClockSpeed(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED *psGetDevClockSpeedIN,
+                                         PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED *psGetDevClockSpeedOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psGetDevClockSpeedOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psGetDevClockSpeedIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psGetDevClockSpeedOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto GetDevClockSpeed_exit;
+                                       }
+                               }
+
+
+       psGetDevClockSpeedOUT->eError =
+               PVRSRVGetDevClockSpeedKM(
+                                       hDevNodeInt,
+                                       &psGetDevClockSpeedOUT->ui32ui32ClockSpeed);
+
+
+
+
+GetDevClockSpeed_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeHWOpTimeout(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_HWOPTIMEOUT *psHWOpTimeoutIN,
+                                         PVRSRV_BRIDGE_OUT_HWOPTIMEOUT *psHWOpTimeoutOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psHWOpTimeoutIN);
+
+
+
+
+
+
+       psHWOpTimeoutOUT->eError =
+               PVRSRVHWOpTimeoutKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeKickDevices(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_KICKDEVICES *psKickDevicesIN,
+                                         PVRSRV_BRIDGE_OUT_KICKDEVICES *psKickDevicesOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(psKickDevicesIN);
+
+
+
+
+
+
+       psKickDevicesOUT->eError =
+               PVRSRVKickDevicesKM(
+                                       );
+
+
+
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeResetHWRLogs(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RESETHWRLOGS *psResetHWRLogsIN,
+                                         PVRSRV_BRIDGE_OUT_RESETHWRLOGS *psResetHWRLogsOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psResetHWRLogsOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psResetHWRLogsIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psResetHWRLogsOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto ResetHWRLogs_exit;
+                                       }
+                               }
+
+
+       psResetHWRLogsOUT->eError =
+               PVRSRVResetHWRLogsKM(
+                                       hDevNodeInt);
+
+
+
+
+ResetHWRLogs_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSoftReset(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SOFTRESET *psSoftResetIN,
+                                         PVRSRV_BRIDGE_OUT_SOFTRESET *psSoftResetOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSoftResetOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psSoftResetIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psSoftResetOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SoftReset_exit;
+                                       }
+                               }
+
+
+       psSoftResetOUT->eError =
+               PVRSRVSoftResetKM(
+                                       hDevNodeInt,
+                                       psSoftResetIN->ui64ResetValue1,
+                                       psSoftResetIN->ui64ResetValue2);
+
+
+
+
+SoftReset_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitSRVCOREBridge(IMG_VOID);
+PVRSRV_ERROR DeinitSRVCOREBridge(IMG_VOID);
+
+/*
+ * Register all SRVCORE functions with services
+ */
+PVRSRV_ERROR InitSRVCOREBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_CONNECT, PVRSRVBridgeConnect,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DISCONNECT, PVRSRVBridgeDisconnect,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ENUMERATEDEVICES, PVRSRVBridgeEnumerateDevices,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ACQUIREDEVICEDATA, PVRSRVBridgeAcquireDeviceData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RELEASEDEVICEDATA, PVRSRVBridgeReleaseDeviceData,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_INITSRVDISCONNECT, PVRSRVBridgeInitSrvDisconnect,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT, PVRSRVBridgeAcquireGlobalEventObject,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT, PVRSRVBridgeReleaseGlobalEventObject,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN, PVRSRVBridgeEventObjectOpen,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT, PVRSRVBridgeEventObjectWait,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE, PVRSRVBridgeEventObjectClose,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO, PVRSRVBridgeDumpDebugInfo,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED, PVRSRVBridgeGetDevClockSpeed,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT, PVRSRVBridgeHWOpTimeout,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_KICKDEVICES, PVRSRVBridgeKickDevices,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RESETHWRLOGS, PVRSRVBridgeResetHWRLogs,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_SOFTRESET, PVRSRVBridgeSoftReset,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all srvcore functions with services
+ */
+PVRSRV_ERROR DeinitSRVCOREBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/sync_bridge/common_sync_bridge.h b/drivers/gpu/rogue_m/generated/sync_bridge/common_sync_bridge.h
new file mode 100644 (file)
index 0000000..dc28674
--- /dev/null
@@ -0,0 +1,481 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for sync
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for sync
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_SYNC_BRIDGE_H
+#define COMMON_SYNC_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "devicemem_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_SYNC_CMD_FIRST                   0
+#define PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK                     PVRSRV_BRIDGE_SYNC_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK                      PVRSRV_BRIDGE_SYNC_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMSET                 PVRSRV_BRIDGE_SYNC_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCPRIMSET                   PVRSRV_BRIDGE_SYNC_CMD_FIRST+3
+#define PVRSRV_BRIDGE_SYNC_SYNCRECORDREMOVEBYHANDLE                    PVRSRV_BRIDGE_SYNC_CMD_FIRST+4
+#define PVRSRV_BRIDGE_SYNC_SYNCRECORDADD                       PVRSRV_BRIDGE_SYNC_CMD_FIRST+5
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC                     PVRSRV_BRIDGE_SYNC_CMD_FIRST+6
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCFREE                      PVRSRV_BRIDGE_SYNC_CMD_FIRST+7
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCQUEUEHWOP                 PVRSRV_BRIDGE_SYNC_CMD_FIRST+8
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCGETSTATUS                 PVRSRV_BRIDGE_SYNC_CMD_FIRST+9
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCREATE                    PVRSRV_BRIDGE_SYNC_CMD_FIRST+10
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPTAKE                      PVRSRV_BRIDGE_SYNC_CMD_FIRST+11
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPREADY                     PVRSRV_BRIDGE_SYNC_CMD_FIRST+12
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCOMPLETE                  PVRSRV_BRIDGE_SYNC_CMD_FIRST+13
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPDESTROY                   PVRSRV_BRIDGE_SYNC_CMD_FIRST+14
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP                       PVRSRV_BRIDGE_SYNC_CMD_FIRST+15
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE                  PVRSRV_BRIDGE_SYNC_CMD_FIRST+16
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL                    PVRSRV_BRIDGE_SYNC_CMD_FIRST+17
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPPDUMPPOL                  PVRSRV_BRIDGE_SYNC_CMD_FIRST+18
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP                    PVRSRV_BRIDGE_SYNC_CMD_FIRST+19
+#define PVRSRV_BRIDGE_SYNC_CMD_LAST                    (PVRSRV_BRIDGE_SYNC_CMD_FIRST+19)
+
+
+/*******************************************
+            AllocSyncPrimitiveBlock          
+ *******************************************/
+
+/* Bridge in structure for AllocSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK;
+
+
+/* Bridge out structure for AllocSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32SyncPrimVAddr;
+       IMG_UINT32 ui32SyncPrimBlockSize;
+       DEVMEM_SERVER_EXPORTCOOKIE hExportCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK;
+
+/*******************************************
+            FreeSyncPrimitiveBlock          
+ *******************************************/
+
+/* Bridge in structure for FreeSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK_TAG
+{
+       IMG_HANDLE hSyncHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK;
+
+
+/* Bridge out structure for FreeSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK;
+
+/*******************************************
+            SyncPrimSet          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimSet */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSET_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Index;
+       IMG_UINT32 ui32Value;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMSET;
+
+
+/* Bridge out structure for SyncPrimSet */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSET_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMSET;
+
+/*******************************************
+            ServerSyncPrimSet          
+ *******************************************/
+
+/* Bridge in structure for ServerSyncPrimSet */
+typedef struct PVRSRV_BRIDGE_IN_SERVERSYNCPRIMSET_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Value;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SERVERSYNCPRIMSET;
+
+
+/* Bridge out structure for ServerSyncPrimSet */
+typedef struct PVRSRV_BRIDGE_OUT_SERVERSYNCPRIMSET_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SERVERSYNCPRIMSET;
+
+/*******************************************
+            SyncRecordRemoveByHandle          
+ *******************************************/
+
+/* Bridge in structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+       IMG_HANDLE hhRecord;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE;
+
+
+/* Bridge out structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE;
+
+/*******************************************
+            SyncRecordAdd          
+ *******************************************/
+
+/* Bridge in structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDADD_TAG
+{
+       IMG_HANDLE hhServerSyncPrimBlock;
+       IMG_UINT32 ui32ui32FwBlockAddr;
+       IMG_UINT32 ui32ui32SyncOffset;
+       IMG_BOOL bbServerSync;
+       IMG_UINT32 ui32ClassNameSize;
+       const IMG_CHAR * puiClassName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDADD;
+
+
+/* Bridge out structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDADD_TAG
+{
+       IMG_HANDLE hhRecord;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDADD;
+
+/*******************************************
+            ServerSyncAlloc          
+ *******************************************/
+
+/* Bridge in structure for ServerSyncAlloc */
+typedef struct PVRSRV_BRIDGE_IN_SERVERSYNCALLOC_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32ClassNameSize;
+       const IMG_CHAR * puiClassName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SERVERSYNCALLOC;
+
+
+/* Bridge out structure for ServerSyncAlloc */
+typedef struct PVRSRV_BRIDGE_OUT_SERVERSYNCALLOC_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32SyncPrimVAddr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SERVERSYNCALLOC;
+
+/*******************************************
+            ServerSyncFree          
+ *******************************************/
+
+/* Bridge in structure for ServerSyncFree */
+typedef struct PVRSRV_BRIDGE_IN_SERVERSYNCFREE_TAG
+{
+       IMG_HANDLE hSyncHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SERVERSYNCFREE;
+
+
+/* Bridge out structure for ServerSyncFree */
+typedef struct PVRSRV_BRIDGE_OUT_SERVERSYNCFREE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SERVERSYNCFREE;
+
+/*******************************************
+            ServerSyncQueueHWOp          
+ *******************************************/
+
+/* Bridge in structure for ServerSyncQueueHWOp */
+typedef struct PVRSRV_BRIDGE_IN_SERVERSYNCQUEUEHWOP_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_BOOL bbUpdate;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SERVERSYNCQUEUEHWOP;
+
+
+/* Bridge out structure for ServerSyncQueueHWOp */
+typedef struct PVRSRV_BRIDGE_OUT_SERVERSYNCQUEUEHWOP_TAG
+{
+       IMG_UINT32 ui32FenceValue;
+       IMG_UINT32 ui32UpdateValue;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SERVERSYNCQUEUEHWOP;
+
+/*******************************************
+            ServerSyncGetStatus          
+ *******************************************/
+
+/* Bridge in structure for ServerSyncGetStatus */
+typedef struct PVRSRV_BRIDGE_IN_SERVERSYNCGETSTATUS_TAG
+{
+       IMG_UINT32 ui32SyncCount;
+       IMG_HANDLE * phSyncHandle;
+       /* Output pointer pui32UID is also an implied input */
+       IMG_UINT32 * pui32UID;
+       /* Output pointer pui32FWAddr is also an implied input */
+       IMG_UINT32 * pui32FWAddr;
+       /* Output pointer pui32CurrentOp is also an implied input */
+       IMG_UINT32 * pui32CurrentOp;
+       /* Output pointer pui32NextOp is also an implied input */
+       IMG_UINT32 * pui32NextOp;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SERVERSYNCGETSTATUS;
+
+
+/* Bridge out structure for ServerSyncGetStatus */
+typedef struct PVRSRV_BRIDGE_OUT_SERVERSYNCGETSTATUS_TAG
+{
+       IMG_UINT32 * pui32UID;
+       IMG_UINT32 * pui32FWAddr;
+       IMG_UINT32 * pui32CurrentOp;
+       IMG_UINT32 * pui32NextOp;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SERVERSYNCGETSTATUS;
+
+/*******************************************
+            SyncPrimOpCreate          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpCreate */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPCREATE_TAG
+{
+       IMG_UINT32 ui32SyncBlockCount;
+       IMG_HANDLE * phBlockList;
+       IMG_UINT32 ui32ClientSyncCount;
+       IMG_UINT32 * pui32SyncBlockIndex;
+       IMG_UINT32 * pui32Index;
+       IMG_UINT32 ui32ServerSyncCount;
+       IMG_HANDLE * phServerSync;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPCREATE;
+
+
+/* Bridge out structure for SyncPrimOpCreate */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPCREATE_TAG
+{
+       IMG_HANDLE hServerCookie;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPCREATE;
+
+/*******************************************
+            SyncPrimOpTake          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpTake */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPTAKE_TAG
+{
+       IMG_HANDLE hServerCookie;
+       IMG_UINT32 ui32ClientSyncCount;
+       IMG_UINT32 * pui32Flags;
+       IMG_UINT32 * pui32FenceValue;
+       IMG_UINT32 * pui32UpdateValue;
+       IMG_UINT32 ui32ServerSyncCount;
+       IMG_UINT32 * pui32ServerFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPTAKE;
+
+
+/* Bridge out structure for SyncPrimOpTake */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPTAKE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPTAKE;
+
+/*******************************************
+            SyncPrimOpReady          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpReady */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPREADY_TAG
+{
+       IMG_HANDLE hServerCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPREADY;
+
+
+/* Bridge out structure for SyncPrimOpReady */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPREADY_TAG
+{
+       IMG_BOOL bReady;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPREADY;
+
+/*******************************************
+            SyncPrimOpComplete          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpComplete */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPCOMPLETE_TAG
+{
+       IMG_HANDLE hServerCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPCOMPLETE;
+
+
+/* Bridge out structure for SyncPrimOpComplete */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPCOMPLETE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPCOMPLETE;
+
+/*******************************************
+            SyncPrimOpDestroy          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpDestroy */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPDESTROY_TAG
+{
+       IMG_HANDLE hServerCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPDESTROY;
+
+
+/* Bridge out structure for SyncPrimOpDestroy */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPDESTROY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPDESTROY;
+
+/*******************************************
+            SyncPrimPDump          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDump */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Offset;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP;
+
+
+/* Bridge out structure for SyncPrimPDump */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP;
+
+/*******************************************
+            SyncPrimPDumpValue          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpValue */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Offset;
+       IMG_UINT32 ui32Value;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE;
+
+
+/* Bridge out structure for SyncPrimPDumpValue */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE;
+
+/*******************************************
+            SyncPrimPDumpPol          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpPol */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Offset;
+       IMG_UINT32 ui32Value;
+       IMG_UINT32 ui32Mask;
+       PDUMP_POLL_OPERATOR eOperator;
+       PDUMP_FLAGS_T uiPDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL;
+
+
+/* Bridge out structure for SyncPrimPDumpPol */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL;
+
+/*******************************************
+            SyncPrimOpPDumpPol          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimOpPDumpPol */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMOPPDUMPPOL_TAG
+{
+       IMG_HANDLE hServerCookie;
+       PDUMP_POLL_OPERATOR eOperator;
+       PDUMP_FLAGS_T uiPDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMOPPDUMPPOL;
+
+
+/* Bridge out structure for SyncPrimOpPDumpPol */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMOPPDUMPPOL_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMOPPDUMPPOL;
+
+/*******************************************
+            SyncPrimPDumpCBP          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpCBP */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32Offset;
+       IMG_DEVMEM_OFFSET_T uiWriteOffset;
+       IMG_DEVMEM_SIZE_T uiPacketSize;
+       IMG_DEVMEM_SIZE_T uiBufferSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP;
+
+
+/* Bridge out structure for SyncPrimPDumpCBP */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP;
+
+#endif /* COMMON_SYNC_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/sync_bridge/server_sync_bridge.c b/drivers/gpu/rogue_m/generated/sync_bridge/server_sync_bridge.c
new file mode 100644 (file)
index 0000000..a7f79c4
--- /dev/null
@@ -0,0 +1,1548 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for sync
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for sync
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "sync_server.h"
+#include "pdump.h"
+
+
+#include "common_sync_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeAllocSyncPrimitiveBlock(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockIN,
+                                         PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+       DEVMEM_EXPORTCOOKIE * psExportCookieInt = IMG_NULL;
+
+
+
+       psAllocSyncPrimitiveBlockOUT->hSyncHandle = IMG_NULL;
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psAllocSyncPrimitiveBlockOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psAllocSyncPrimitiveBlockIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto AllocSyncPrimitiveBlock_exit;
+                                       }
+                               }
+
+
+       psAllocSyncPrimitiveBlockOUT->eError =
+               PVRSRVAllocSyncPrimitiveBlockKM(psConnection,
+                                       hDevNodeInt,
+                                       &psSyncHandleInt,
+                                       &psAllocSyncPrimitiveBlockOUT->ui32SyncPrimVAddr,
+                                       &psAllocSyncPrimitiveBlockOUT->ui32SyncPrimBlockSize,
+                                       &psExportCookieInt);
+       /* Exit early if bridged call fails */
+       if(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
+       {
+               goto AllocSyncPrimitiveBlock_exit;
+       }
+
+
+       psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psAllocSyncPrimitiveBlockOUT->hSyncHandle,
+                                                       (IMG_VOID *) psSyncHandleInt,
+                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVFreeSyncPrimitiveBlockKM);
+       if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
+       {
+               goto AllocSyncPrimitiveBlock_exit;
+       }
+
+
+       psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+                                                       &psAllocSyncPrimitiveBlockOUT->hExportCookie,
+                                                       (IMG_VOID *) psExportCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,psAllocSyncPrimitiveBlockOUT->hSyncHandle);
+       if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
+       {
+               goto AllocSyncPrimitiveBlock_exit;
+       }
+
+
+
+
+AllocSyncPrimitiveBlock_exit:
+       if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
+       {
+               if (psAllocSyncPrimitiveBlockOUT->hSyncHandle)
+               {
+                       PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                               (IMG_HANDLE) psAllocSyncPrimitiveBlockOUT->hSyncHandle,
+                                               PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+
+                       /* Releasing the handle should free/destroy/release the resource. This should never fail... */
+                       PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+                       /* Avoid freeing/destroying/releasing the resource a second time below */
+                       psSyncHandleInt = IMG_NULL;
+               }
+
+
+               if (psSyncHandleInt)
+               {
+                       PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeFreeSyncPrimitiveBlock(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK *psFreeSyncPrimitiveBlockIN,
+                                         PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK *psFreeSyncPrimitiveBlockOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psFreeSyncPrimitiveBlockOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psFreeSyncPrimitiveBlockIN->hSyncHandle,
+                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+       if ((psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_OK) && (psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto FreeSyncPrimitiveBlock_exit;
+       }
+
+
+
+FreeSyncPrimitiveBlock_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimSet(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMSET *psSyncPrimSetIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMSET *psSyncPrimSetOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimSetOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimSetIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimSetOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimSet_exit;
+                                       }
+                               }
+
+
+       psSyncPrimSetOUT->eError =
+               PVRSRVSyncPrimSetKM(
+                                       psSyncHandleInt,
+                                       psSyncPrimSetIN->ui32Index,
+                                       psSyncPrimSetIN->ui32Value);
+
+
+
+
+SyncPrimSet_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeServerSyncPrimSet(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SERVERSYNCPRIMSET *psServerSyncPrimSetIN,
+                                         PVRSRV_BRIDGE_OUT_SERVERSYNCPRIMSET *psServerSyncPrimSetOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psServerSyncPrimSetOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psServerSyncPrimSetIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psServerSyncPrimSetOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto ServerSyncPrimSet_exit;
+                                       }
+                               }
+
+
+       psServerSyncPrimSetOUT->eError =
+               PVRSRVServerSyncPrimSetKM(
+                                       psSyncHandleInt,
+                                       psServerSyncPrimSetIN->ui32Value);
+
+
+
+
+ServerSyncPrimSet_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncRecordRemoveByHandle(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psSyncRecordRemoveByHandleOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psSyncRecordRemoveByHandleIN->hhRecord,
+                                       PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE);
+       if ((psSyncRecordRemoveByHandleOUT->eError != PVRSRV_OK) && (psSyncRecordRemoveByHandleOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto SyncRecordRemoveByHandle_exit;
+       }
+
+
+
+SyncRecordRemoveByHandle_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncRecordAdd(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCRECORDADD *psSyncRecordAddIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCRECORDADD *psSyncRecordAddOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_RECORD_HANDLE pshRecordInt = IMG_NULL;
+       SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt = IMG_NULL;
+       IMG_CHAR *uiClassNameInt = IMG_NULL;
+
+
+
+
+       if (psSyncRecordAddIN->ui32ClassNameSize != 0)
+       {
+               uiClassNameInt = OSAllocMem(psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR));
+               if (!uiClassNameInt)
+               {
+                       psSyncRecordAddOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncRecordAdd_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncRecordAddIN->puiClassName, psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiClassNameInt, psSyncRecordAddIN->puiClassName,
+                               psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psSyncRecordAddOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncRecordAdd_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncRecordAddOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &pshServerSyncPrimBlockInt,
+                                                                                       psSyncRecordAddIN->hhServerSyncPrimBlock,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncRecordAddOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncRecordAdd_exit;
+                                       }
+                               }
+
+
+       psSyncRecordAddOUT->eError =
+               PVRSRVSyncRecordAddKM(
+                                       &pshRecordInt,
+                                       pshServerSyncPrimBlockInt,
+                                       psSyncRecordAddIN->ui32ui32FwBlockAddr,
+                                       psSyncRecordAddIN->ui32ui32SyncOffset,
+                                       psSyncRecordAddIN->bbServerSync,
+                                       psSyncRecordAddIN->ui32ClassNameSize,
+                                       uiClassNameInt);
+       /* Exit early if bridged call fails */
+       if(psSyncRecordAddOUT->eError != PVRSRV_OK)
+       {
+               goto SyncRecordAdd_exit;
+       }
+
+
+       psSyncRecordAddOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psSyncRecordAddOUT->hhRecord,
+                                                       (IMG_VOID *) pshRecordInt,
+                                                       PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVSyncRecordRemoveByHandleKM);
+       if (psSyncRecordAddOUT->eError != PVRSRV_OK)
+       {
+               goto SyncRecordAdd_exit;
+       }
+
+
+
+
+SyncRecordAdd_exit:
+       if (psSyncRecordAddOUT->eError != PVRSRV_OK)
+       {
+               if (pshRecordInt)
+               {
+                       PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt);
+               }
+       }
+
+       if (uiClassNameInt)
+               OSFreeMem(uiClassNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeServerSyncAlloc(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SERVERSYNCALLOC *psServerSyncAllocIN,
+                                         PVRSRV_BRIDGE_OUT_SERVERSYNCALLOC *psServerSyncAllocOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
+       IMG_CHAR *uiClassNameInt = IMG_NULL;
+
+
+
+
+       if (psServerSyncAllocIN->ui32ClassNameSize != 0)
+       {
+               uiClassNameInt = OSAllocMem(psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR));
+               if (!uiClassNameInt)
+               {
+                       psServerSyncAllocOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncAlloc_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psServerSyncAllocIN->puiClassName, psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR))
+                               || (OSCopyFromUser(NULL, uiClassNameInt, psServerSyncAllocIN->puiClassName,
+                               psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+                       {
+                               psServerSyncAllocOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto ServerSyncAlloc_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psServerSyncAllocOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psServerSyncAllocIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psServerSyncAllocOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto ServerSyncAlloc_exit;
+                                       }
+                               }
+
+
+       psServerSyncAllocOUT->eError =
+               PVRSRVServerSyncAllocKM(
+                                       hDevNodeInt,
+                                       &psSyncHandleInt,
+                                       &psServerSyncAllocOUT->ui32SyncPrimVAddr,
+                                       psServerSyncAllocIN->ui32ClassNameSize,
+                                       uiClassNameInt);
+       /* Exit early if bridged call fails */
+       if(psServerSyncAllocOUT->eError != PVRSRV_OK)
+       {
+               goto ServerSyncAlloc_exit;
+       }
+
+
+       psServerSyncAllocOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psServerSyncAllocOUT->hSyncHandle,
+                                                       (IMG_VOID *) psSyncHandleInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVServerSyncFreeKM);
+       if (psServerSyncAllocOUT->eError != PVRSRV_OK)
+       {
+               goto ServerSyncAlloc_exit;
+       }
+
+
+
+
+ServerSyncAlloc_exit:
+       if (psServerSyncAllocOUT->eError != PVRSRV_OK)
+       {
+               if (psSyncHandleInt)
+               {
+                       PVRSRVServerSyncFreeKM(psSyncHandleInt);
+               }
+       }
+
+       if (uiClassNameInt)
+               OSFreeMem(uiClassNameInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeServerSyncFree(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SERVERSYNCFREE *psServerSyncFreeIN,
+                                         PVRSRV_BRIDGE_OUT_SERVERSYNCFREE *psServerSyncFreeOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psServerSyncFreeOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psServerSyncFreeIN->hSyncHandle,
+                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+       if ((psServerSyncFreeOUT->eError != PVRSRV_OK) && (psServerSyncFreeOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto ServerSyncFree_exit;
+       }
+
+
+
+ServerSyncFree_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeServerSyncQueueHWOp(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SERVERSYNCQUEUEHWOP *psServerSyncQueueHWOpIN,
+                                         PVRSRV_BRIDGE_OUT_SERVERSYNCQUEUEHWOP *psServerSyncQueueHWOpOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psServerSyncQueueHWOpOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psServerSyncQueueHWOpIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psServerSyncQueueHWOpOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto ServerSyncQueueHWOp_exit;
+                                       }
+                               }
+
+
+       psServerSyncQueueHWOpOUT->eError =
+               PVRSRVServerSyncQueueHWOpKM(
+                                       psSyncHandleInt,
+                                       psServerSyncQueueHWOpIN->bbUpdate,
+                                       &psServerSyncQueueHWOpOUT->ui32FenceValue,
+                                       &psServerSyncQueueHWOpOUT->ui32UpdateValue);
+
+
+
+
+ServerSyncQueueHWOp_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeServerSyncGetStatus(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SERVERSYNCGETSTATUS *psServerSyncGetStatusIN,
+                                         PVRSRV_BRIDGE_OUT_SERVERSYNCGETSTATUS *psServerSyncGetStatusOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_SYNC_PRIMITIVE * *psSyncHandleInt = IMG_NULL;
+       IMG_HANDLE *hSyncHandleInt2 = IMG_NULL;
+       IMG_UINT32 *pui32UIDInt = IMG_NULL;
+       IMG_UINT32 *pui32FWAddrInt = IMG_NULL;
+       IMG_UINT32 *pui32CurrentOpInt = IMG_NULL;
+       IMG_UINT32 *pui32NextOpInt = IMG_NULL;
+
+
+       psServerSyncGetStatusOUT->pui32UID = psServerSyncGetStatusIN->pui32UID;
+       psServerSyncGetStatusOUT->pui32FWAddr = psServerSyncGetStatusIN->pui32FWAddr;
+       psServerSyncGetStatusOUT->pui32CurrentOp = psServerSyncGetStatusIN->pui32CurrentOp;
+       psServerSyncGetStatusOUT->pui32NextOp = psServerSyncGetStatusIN->pui32NextOp;
+
+
+       if (psServerSyncGetStatusIN->ui32SyncCount != 0)
+       {
+               psSyncHandleInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psSyncHandleInt)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+               hSyncHandleInt2 = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE));
+               if (!hSyncHandleInt2)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psServerSyncGetStatusIN->phSyncHandle, psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hSyncHandleInt2, psServerSyncGetStatusIN->phSyncHandle,
+                               psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto ServerSyncGetStatus_exit;
+                       }
+       if (psServerSyncGetStatusIN->ui32SyncCount != 0)
+       {
+               pui32UIDInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
+               if (!pui32UIDInt)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+       }
+
+       if (psServerSyncGetStatusIN->ui32SyncCount != 0)
+       {
+               pui32FWAddrInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
+               if (!pui32FWAddrInt)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+       }
+
+       if (psServerSyncGetStatusIN->ui32SyncCount != 0)
+       {
+               pui32CurrentOpInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
+               if (!pui32CurrentOpInt)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+       }
+
+       if (psServerSyncGetStatusIN->ui32SyncCount != 0)
+       {
+               pui32NextOpInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
+               if (!pui32NextOpInt)
+               {
+                       psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto ServerSyncGetStatus_exit;
+               }
+       }
+
+
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psServerSyncGetStatusIN->ui32SyncCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psServerSyncGetStatusOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt[i],
+                                                                                       hSyncHandleInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psServerSyncGetStatusOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto ServerSyncGetStatus_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psServerSyncGetStatusOUT->eError =
+               PVRSRVServerSyncGetStatusKM(
+                                       psServerSyncGetStatusIN->ui32SyncCount,
+                                       psSyncHandleInt,
+                                       pui32UIDInt,
+                                       pui32FWAddrInt,
+                                       pui32CurrentOpInt,
+                                       pui32NextOpInt);
+
+
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32UID, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) 
+               || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32UID, pui32UIDInt,
+               (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+       {
+               psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto ServerSyncGetStatus_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32FWAddr, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) 
+               || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32FWAddr, pui32FWAddrInt,
+               (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+       {
+               psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto ServerSyncGetStatus_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32CurrentOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) 
+               || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32CurrentOp, pui32CurrentOpInt,
+               (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+       {
+               psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto ServerSyncGetStatus_exit;
+       }
+
+       if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32NextOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) 
+               || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32NextOp, pui32NextOpInt,
+               (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+       {
+               psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+               goto ServerSyncGetStatus_exit;
+       }
+
+
+ServerSyncGetStatus_exit:
+       if (psSyncHandleInt)
+               OSFreeMem(psSyncHandleInt);
+       if (hSyncHandleInt2)
+               OSFreeMem(hSyncHandleInt2);
+       if (pui32UIDInt)
+               OSFreeMem(pui32UIDInt);
+       if (pui32FWAddrInt)
+               OSFreeMem(pui32FWAddrInt);
+       if (pui32CurrentOpInt)
+               OSFreeMem(pui32CurrentOpInt);
+       if (pui32NextOpInt)
+               OSFreeMem(pui32NextOpInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpCreate(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPCREATE *psSyncPrimOpCreateIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPCREATE *psSyncPrimOpCreateOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * *psBlockListInt = IMG_NULL;
+       IMG_HANDLE *hBlockListInt2 = IMG_NULL;
+       IMG_UINT32 *ui32SyncBlockIndexInt = IMG_NULL;
+       IMG_UINT32 *ui32IndexInt = IMG_NULL;
+       SERVER_SYNC_PRIMITIVE * *psServerSyncInt = IMG_NULL;
+       IMG_HANDLE *hServerSyncInt2 = IMG_NULL;
+       SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
+
+
+
+
+       if (psSyncPrimOpCreateIN->ui32SyncBlockCount != 0)
+       {
+               psBlockListInt = OSAllocMem(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
+               if (!psBlockListInt)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+               hBlockListInt2 = OSAllocMem(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE));
+               if (!hBlockListInt2)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->phBlockList, psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hBlockListInt2, psSyncPrimOpCreateIN->phBlockList,
+                               psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpCreate_exit;
+                       }
+       if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
+       {
+               ui32SyncBlockIndexInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
+               if (!ui32SyncBlockIndexInt)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->pui32SyncBlockIndex, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32SyncBlockIndexInt, psSyncPrimOpCreateIN->pui32SyncBlockIndex,
+                               psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpCreate_exit;
+                       }
+       if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
+       {
+               ui32IndexInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
+               if (!ui32IndexInt)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->pui32Index, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32IndexInt, psSyncPrimOpCreateIN->pui32Index,
+                               psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpCreate_exit;
+                       }
+       if (psSyncPrimOpCreateIN->ui32ServerSyncCount != 0)
+       {
+               psServerSyncInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
+               if (!psServerSyncInt)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+               hServerSyncInt2 = OSAllocMem(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
+               if (!hServerSyncInt2)
+               {
+                       psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpCreate_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->phServerSync, psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
+                               || (OSCopyFromUser(NULL, hServerSyncInt2, psSyncPrimOpCreateIN->phServerSync,
+                               psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpCreate_exit;
+                       }
+
+
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psSyncPrimOpCreateIN->ui32SyncBlockCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpCreateOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psBlockListInt[i],
+                                                                                       hBlockListInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpCreate_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       {
+               IMG_UINT32 i;
+
+               for (i=0;i<psSyncPrimOpCreateIN->ui32ServerSyncCount;i++)
+               {
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpCreateOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerSyncInt[i],
+                                                                                       hServerSyncInt2[i],
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpCreate_exit;
+                                       }
+                               }
+
+               }
+       }
+
+       psSyncPrimOpCreateOUT->eError =
+               PVRSRVSyncPrimOpCreateKM(
+                                       psSyncPrimOpCreateIN->ui32SyncBlockCount,
+                                       psBlockListInt,
+                                       psSyncPrimOpCreateIN->ui32ClientSyncCount,
+                                       ui32SyncBlockIndexInt,
+                                       ui32IndexInt,
+                                       psSyncPrimOpCreateIN->ui32ServerSyncCount,
+                                       psServerSyncInt,
+                                       &psServerCookieInt);
+       /* Exit early if bridged call fails */
+       if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimOpCreate_exit;
+       }
+
+
+       psSyncPrimOpCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psSyncPrimOpCreateOUT->hServerCookie,
+                                                       (IMG_VOID *) psServerCookieInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVSyncPrimOpDestroyKM);
+       if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimOpCreate_exit;
+       }
+
+
+
+
+SyncPrimOpCreate_exit:
+       if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
+       {
+               if (psServerCookieInt)
+               {
+                       PVRSRVSyncPrimOpDestroyKM(psServerCookieInt);
+               }
+       }
+
+       if (psBlockListInt)
+               OSFreeMem(psBlockListInt);
+       if (hBlockListInt2)
+               OSFreeMem(hBlockListInt2);
+       if (ui32SyncBlockIndexInt)
+               OSFreeMem(ui32SyncBlockIndexInt);
+       if (ui32IndexInt)
+               OSFreeMem(ui32IndexInt);
+       if (psServerSyncInt)
+               OSFreeMem(psServerSyncInt);
+       if (hServerSyncInt2)
+               OSFreeMem(hServerSyncInt2);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpTake(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPTAKE *psSyncPrimOpTakeIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPTAKE *psSyncPrimOpTakeOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
+       IMG_UINT32 *ui32FlagsInt = IMG_NULL;
+       IMG_UINT32 *ui32FenceValueInt = IMG_NULL;
+       IMG_UINT32 *ui32UpdateValueInt = IMG_NULL;
+       IMG_UINT32 *ui32ServerFlagsInt = IMG_NULL;
+
+
+
+
+       if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
+       {
+               ui32FlagsInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
+               if (!ui32FlagsInt)
+               {
+                       psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpTake_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32Flags, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32FlagsInt, psSyncPrimOpTakeIN->pui32Flags,
+                               psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpTake_exit;
+                       }
+       if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
+       {
+               ui32FenceValueInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
+               if (!ui32FenceValueInt)
+               {
+                       psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpTake_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32FenceValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32FenceValueInt, psSyncPrimOpTakeIN->pui32FenceValue,
+                               psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpTake_exit;
+                       }
+       if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
+       {
+               ui32UpdateValueInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
+               if (!ui32UpdateValueInt)
+               {
+                       psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpTake_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32UpdateValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32UpdateValueInt, psSyncPrimOpTakeIN->pui32UpdateValue,
+                               psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpTake_exit;
+                       }
+       if (psSyncPrimOpTakeIN->ui32ServerSyncCount != 0)
+       {
+               ui32ServerFlagsInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
+               if (!ui32ServerFlagsInt)
+               {
+                       psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                       goto SyncPrimOpTake_exit;
+               }
+       }
+
+                       /* Copy the data over */
+                       if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32ServerFlags, psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
+                               || (OSCopyFromUser(NULL, ui32ServerFlagsInt, psSyncPrimOpTakeIN->pui32ServerFlags,
+                               psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+                       {
+                               psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+                               goto SyncPrimOpTake_exit;
+                       }
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpTakeOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerCookieInt,
+                                                                                       psSyncPrimOpTakeIN->hServerCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+                                       if(psSyncPrimOpTakeOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpTake_exit;
+                                       }
+                               }
+
+
+       psSyncPrimOpTakeOUT->eError =
+               PVRSRVSyncPrimOpTakeKM(
+                                       psServerCookieInt,
+                                       psSyncPrimOpTakeIN->ui32ClientSyncCount,
+                                       ui32FlagsInt,
+                                       ui32FenceValueInt,
+                                       ui32UpdateValueInt,
+                                       psSyncPrimOpTakeIN->ui32ServerSyncCount,
+                                       ui32ServerFlagsInt);
+
+
+
+
+SyncPrimOpTake_exit:
+       if (ui32FlagsInt)
+               OSFreeMem(ui32FlagsInt);
+       if (ui32FenceValueInt)
+               OSFreeMem(ui32FenceValueInt);
+       if (ui32UpdateValueInt)
+               OSFreeMem(ui32UpdateValueInt);
+       if (ui32ServerFlagsInt)
+               OSFreeMem(ui32ServerFlagsInt);
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpReady(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPREADY *psSyncPrimOpReadyIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPREADY *psSyncPrimOpReadyOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpReadyOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerCookieInt,
+                                                                                       psSyncPrimOpReadyIN->hServerCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+                                       if(psSyncPrimOpReadyOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpReady_exit;
+                                       }
+                               }
+
+
+       psSyncPrimOpReadyOUT->eError =
+               PVRSRVSyncPrimOpReadyKM(
+                                       psServerCookieInt,
+                                       &psSyncPrimOpReadyOUT->bReady);
+
+
+
+
+SyncPrimOpReady_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpComplete(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPCOMPLETE *psSyncPrimOpCompleteIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPCOMPLETE *psSyncPrimOpCompleteOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpCompleteOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerCookieInt,
+                                                                                       psSyncPrimOpCompleteIN->hServerCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+                                       if(psSyncPrimOpCompleteOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpComplete_exit;
+                                       }
+                               }
+
+
+       psSyncPrimOpCompleteOUT->eError =
+               PVRSRVSyncPrimOpCompleteKM(
+                                       psServerCookieInt);
+
+
+
+
+SyncPrimOpComplete_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpDestroy(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPDESTROY *psSyncPrimOpDestroyIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPDESTROY *psSyncPrimOpDestroyOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psSyncPrimOpDestroyOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psSyncPrimOpDestroyIN->hServerCookie,
+                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+       if ((psSyncPrimOpDestroyOUT->eError != PVRSRV_OK) && (psSyncPrimOpDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto SyncPrimOpDestroy_exit;
+       }
+
+
+
+SyncPrimOpDestroy_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimPDump(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP *psSyncPrimPDumpIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP *psSyncPrimPDumpOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimPDumpOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimPDumpIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimPDumpOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimPDump_exit;
+                                       }
+                               }
+
+
+       psSyncPrimPDumpOUT->eError =
+               PVRSRVSyncPrimPDumpKM(
+                                       psSyncHandleInt,
+                                       psSyncPrimPDumpIN->ui32Offset);
+
+
+
+
+SyncPrimPDump_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimPDumpValue(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimPDumpValueOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimPDumpValueIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimPDumpValueOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimPDumpValue_exit;
+                                       }
+                               }
+
+
+       psSyncPrimPDumpValueOUT->eError =
+               PVRSRVSyncPrimPDumpValueKM(
+                                       psSyncHandleInt,
+                                       psSyncPrimPDumpValueIN->ui32Offset,
+                                       psSyncPrimPDumpValueIN->ui32Value);
+
+
+
+
+SyncPrimPDumpValue_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimPDumpPol(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimPDumpPolOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimPDumpPolIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimPDumpPolOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimPDumpPol_exit;
+                                       }
+                               }
+
+
+       psSyncPrimPDumpPolOUT->eError =
+               PVRSRVSyncPrimPDumpPolKM(
+                                       psSyncHandleInt,
+                                       psSyncPrimPDumpPolIN->ui32Offset,
+                                       psSyncPrimPDumpPolIN->ui32Value,
+                                       psSyncPrimPDumpPolIN->ui32Mask,
+                                       psSyncPrimPDumpPolIN->eOperator,
+                                       psSyncPrimPDumpPolIN->uiPDumpFlags);
+
+
+
+
+SyncPrimPDumpPol_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimOpPDumpPol(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMOPPDUMPPOL *psSyncPrimOpPDumpPolIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMOPPDUMPPOL *psSyncPrimOpPDumpPolOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimOpPDumpPolOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psServerCookieInt,
+                                                                                       psSyncPrimOpPDumpPolIN->hServerCookie,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+                                       if(psSyncPrimOpPDumpPolOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimOpPDumpPol_exit;
+                                       }
+                               }
+
+
+       psSyncPrimOpPDumpPolOUT->eError =
+               PVRSRVSyncPrimOpPDumpPolKM(
+                                       psServerCookieInt,
+                                       psSyncPrimOpPDumpPolIN->eOperator,
+                                       psSyncPrimOpPDumpPolIN->uiPDumpFlags);
+
+
+
+
+SyncPrimOpPDumpPol_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimPDumpCBP(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimPDumpCBPOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimPDumpCBPIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+                                       if(psSyncPrimPDumpCBPOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimPDumpCBP_exit;
+                                       }
+                               }
+
+
+       psSyncPrimPDumpCBPOUT->eError =
+               PVRSRVSyncPrimPDumpCBPKM(
+                                       psSyncHandleInt,
+                                       psSyncPrimPDumpCBPIN->ui32Offset,
+                                       psSyncPrimPDumpCBPIN->uiWriteOffset,
+                                       psSyncPrimPDumpCBPIN->uiPacketSize,
+                                       psSyncPrimPDumpCBPIN->uiBufferSize);
+
+
+
+
+SyncPrimPDumpCBP_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitSYNCBridge(IMG_VOID);
+PVRSRV_ERROR DeinitSYNCBridge(IMG_VOID);
+
+/*
+ * Register all SYNC functions with services
+ */
+PVRSRV_ERROR InitSYNCBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK, PVRSRVBridgeAllocSyncPrimitiveBlock,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK, PVRSRVBridgeFreeSyncPrimitiveBlock,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMSET, PVRSRVBridgeSyncPrimSet,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCPRIMSET, PVRSRVBridgeServerSyncPrimSet,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCRECORDREMOVEBYHANDLE, PVRSRVBridgeSyncRecordRemoveByHandle,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCRECORDADD, PVRSRVBridgeSyncRecordAdd,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC, PVRSRVBridgeServerSyncAlloc,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCFREE, PVRSRVBridgeServerSyncFree,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCQUEUEHWOP, PVRSRVBridgeServerSyncQueueHWOp,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCGETSTATUS, PVRSRVBridgeServerSyncGetStatus,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCREATE, PVRSRVBridgeSyncPrimOpCreate,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPTAKE, PVRSRVBridgeSyncPrimOpTake,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPREADY, PVRSRVBridgeSyncPrimOpReady,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCOMPLETE, PVRSRVBridgeSyncPrimOpComplete,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPDESTROY, PVRSRVBridgeSyncPrimOpDestroy,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP, PVRSRVBridgeSyncPrimPDump,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE, PVRSRVBridgeSyncPrimPDumpValue,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL, PVRSRVBridgeSyncPrimPDumpPol,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPPDUMPPOL, PVRSRVBridgeSyncPrimOpPDumpPol,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP, PVRSRVBridgeSyncPrimPDumpCBP,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all sync functions with services
+ */
+PVRSRV_ERROR DeinitSYNCBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/syncsexport_bridge/common_syncsexport_bridge.h b/drivers/gpu/rogue_m/generated/syncsexport_bridge/common_syncsexport_bridge.h
new file mode 100644 (file)
index 0000000..978b143
--- /dev/null
@@ -0,0 +1,114 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for syncsexport
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for syncsexport
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_SYNCSEXPORT_BRIDGE_H
+#define COMMON_SYNCSEXPORT_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+
+
+#define PVRSRV_BRIDGE_SYNCSEXPORT_CMD_FIRST                    0
+#define PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREEXPORT                   PVRSRV_BRIDGE_SYNCSEXPORT_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREUNEXPORT                 PVRSRV_BRIDGE_SYNCSEXPORT_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREIMPORT                   PVRSRV_BRIDGE_SYNCSEXPORT_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SYNCSEXPORT_CMD_LAST                     (PVRSRV_BRIDGE_SYNCSEXPORT_CMD_FIRST+2)
+
+
+/*******************************************
+            SyncPrimServerSecureExport          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimServerSecureExport */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREEXPORT_TAG
+{
+       IMG_HANDLE hSyncHandle;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREEXPORT;
+
+
+/* Bridge out structure for SyncPrimServerSecureExport */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREEXPORT_TAG
+{
+       IMG_SECURE_TYPE Export;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREEXPORT;
+
+/*******************************************
+            SyncPrimServerSecureUnexport          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimServerSecureUnexport */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREUNEXPORT_TAG
+{
+       IMG_HANDLE hExport;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREUNEXPORT;
+
+
+/* Bridge out structure for SyncPrimServerSecureUnexport */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREUNEXPORT_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREUNEXPORT;
+
+/*******************************************
+            SyncPrimServerSecureImport          
+ *******************************************/
+
+/* Bridge in structure for SyncPrimServerSecureImport */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREIMPORT_TAG
+{
+       IMG_SECURE_TYPE Export;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREIMPORT;
+
+
+/* Bridge out structure for SyncPrimServerSecureImport */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREIMPORT_TAG
+{
+       IMG_HANDLE hSyncHandle;
+       IMG_UINT32 ui32SyncPrimVAddr;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREIMPORT;
+
+#endif /* COMMON_SYNCSEXPORT_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/syncsexport_bridge/server_syncsexport_bridge.c b/drivers/gpu/rogue_m/generated/syncsexport_bridge/server_syncsexport_bridge.c
new file mode 100644 (file)
index 0000000..095cbd7
--- /dev/null
@@ -0,0 +1,269 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for syncsexport
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for syncsexport
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "sync_server.h"
+
+
+#include "common_syncsexport_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeSyncPrimServerSecureExport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREEXPORT *psSyncPrimServerSecureExportIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREEXPORT *psSyncPrimServerSecureExportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
+       SERVER_SYNC_EXPORT * psExportInt = IMG_NULL;
+       IMG_HANDLE hExportInt = IMG_NULL;
+       CONNECTION_DATA *psSecureConnection;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psSyncPrimServerSecureExportOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &psSyncHandleInt,
+                                                                                       psSyncPrimServerSecureExportIN->hSyncHandle,
+                                                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+                                       if(psSyncPrimServerSecureExportOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto SyncPrimServerSecureExport_exit;
+                                       }
+                               }
+
+
+       psSyncPrimServerSecureExportOUT->eError =
+               PVRSRVSyncPrimServerSecureExportKM(psConnection,
+                                       psSyncHandleInt,
+                                       &psSyncPrimServerSecureExportOUT->Export,
+                                       &psExportInt, &psSecureConnection);
+       /* Exit early if bridged call fails */
+       if(psSyncPrimServerSecureExportOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimServerSecureExport_exit;
+       }
+
+
+       psSyncPrimServerSecureExportOUT->eError = PVRSRVAllocHandle(psSecureConnection->psHandleBase,
+                                                       &hExportInt,
+                                                       (IMG_VOID *) psExportInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_EXPORT,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVSyncPrimServerSecureUnexportKM);
+       if (psSyncPrimServerSecureExportOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimServerSecureExport_exit;
+       }
+
+
+
+
+SyncPrimServerSecureExport_exit:
+       if (psSyncPrimServerSecureExportOUT->eError != PVRSRV_OK)
+       {
+               if (psExportInt)
+               {
+                       PVRSRVSyncPrimServerSecureUnexportKM(psExportInt);
+               }
+       }
+
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimServerSecureUnexport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREUNEXPORT *psSyncPrimServerSecureUnexportIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREUNEXPORT *psSyncPrimServerSecureUnexportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+       psSyncPrimServerSecureUnexportOUT->eError =
+               PVRSRVReleaseHandle(psConnection->psHandleBase,
+                                       (IMG_HANDLE) psSyncPrimServerSecureUnexportIN->hExport,
+                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_EXPORT);
+       if ((psSyncPrimServerSecureUnexportOUT->eError != PVRSRV_OK) && (psSyncPrimServerSecureUnexportOUT->eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_ASSERT(0);
+               goto SyncPrimServerSecureUnexport_exit;
+       }
+
+
+
+SyncPrimServerSecureUnexport_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeSyncPrimServerSecureImport(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_SYNCPRIMSERVERSECUREIMPORT *psSyncPrimServerSecureImportIN,
+                                         PVRSRV_BRIDGE_OUT_SYNCPRIMSERVERSECUREIMPORT *psSyncPrimServerSecureImportOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
+
+
+
+
+
+
+
+       psSyncPrimServerSecureImportOUT->eError =
+               PVRSRVSyncPrimServerSecureImportKM(
+                                       psSyncPrimServerSecureImportIN->Export,
+                                       &psSyncHandleInt,
+                                       &psSyncPrimServerSecureImportOUT->ui32SyncPrimVAddr);
+       /* Exit early if bridged call fails */
+       if(psSyncPrimServerSecureImportOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimServerSecureImport_exit;
+       }
+
+
+       psSyncPrimServerSecureImportOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+                                                       &psSyncPrimServerSecureImportOUT->hSyncHandle,
+                                                       (IMG_VOID *) psSyncHandleInt,
+                                                       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+                                                       PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+                                                       ,(PFN_HANDLE_RELEASE)&PVRSRVServerSyncFreeKM);
+       if (psSyncPrimServerSecureImportOUT->eError != PVRSRV_OK)
+       {
+               goto SyncPrimServerSecureImport_exit;
+       }
+
+
+
+
+SyncPrimServerSecureImport_exit:
+       if (psSyncPrimServerSecureImportOUT->eError != PVRSRV_OK)
+       {
+               if (psSyncHandleInt)
+               {
+                       PVRSRVServerSyncFreeKM(psSyncHandleInt);
+               }
+       }
+
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitSYNCSEXPORTBridge(IMG_VOID);
+PVRSRV_ERROR DeinitSYNCSEXPORTBridge(IMG_VOID);
+
+/*
+ * Register all SYNCSEXPORT functions with services
+ */
+PVRSRV_ERROR InitSYNCSEXPORTBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCSEXPORT, PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREEXPORT, PVRSRVBridgeSyncPrimServerSecureExport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCSEXPORT, PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREUNEXPORT, PVRSRVBridgeSyncPrimServerSecureUnexport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCSEXPORT, PVRSRV_BRIDGE_SYNCSEXPORT_SYNCPRIMSERVERSECUREIMPORT, PVRSRVBridgeSyncPrimServerSecureImport,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all syncsexport functions with services
+ */
+PVRSRV_ERROR DeinitSYNCSEXPORTBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/generated/timerquery_bridge/common_timerquery_bridge.h b/drivers/gpu/rogue_m/generated/timerquery_bridge/common_timerquery_bridge.h
new file mode 100644 (file)
index 0000000..ffd457a
--- /dev/null
@@ -0,0 +1,135 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for timerquery
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures that are used by both
+                the client and sever side of the bridge for timerquery
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_TIMERQUERY_BRIDGE_H
+#define COMMON_TIMERQUERY_BRIDGE_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+
+#define PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST                     0
+#define PVRSRV_BRIDGE_TIMERQUERY_RGXBEGINTIMERQUERY                    PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST+0
+#define PVRSRV_BRIDGE_TIMERQUERY_RGXENDTIMERQUERY                      PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST+1
+#define PVRSRV_BRIDGE_TIMERQUERY_RGXQUERYTIMER                 PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST+2
+#define PVRSRV_BRIDGE_TIMERQUERY_RGXCURRENTTIME                        PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST+3
+#define PVRSRV_BRIDGE_TIMERQUERY_CMD_LAST                      (PVRSRV_BRIDGE_TIMERQUERY_CMD_FIRST+3)
+
+
+/*******************************************
+            RGXBeginTimerQuery          
+ *******************************************/
+
+/* Bridge in structure for RGXBeginTimerQuery */
+typedef struct PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32QueryId;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY;
+
+
+/* Bridge out structure for RGXBeginTimerQuery */
+typedef struct PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY;
+
+/*******************************************
+            RGXEndTimerQuery          
+ *******************************************/
+
+/* Bridge in structure for RGXEndTimerQuery */
+typedef struct PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY;
+
+
+/* Bridge out structure for RGXEndTimerQuery */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY_TAG
+{
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY;
+
+/*******************************************
+            RGXQueryTimer          
+ *******************************************/
+
+/* Bridge in structure for RGXQueryTimer */
+typedef struct PVRSRV_BRIDGE_IN_RGXQUERYTIMER_TAG
+{
+       IMG_HANDLE hDevNode;
+       IMG_UINT32 ui32QueryId;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXQUERYTIMER;
+
+
+/* Bridge out structure for RGXQueryTimer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXQUERYTIMER_TAG
+{
+       IMG_UINT64 ui64StartTime;
+       IMG_UINT64 ui64EndTime;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXQUERYTIMER;
+
+/*******************************************
+            RGXCurrentTime          
+ *******************************************/
+
+/* Bridge in structure for RGXCurrentTime */
+typedef struct PVRSRV_BRIDGE_IN_RGXCURRENTTIME_TAG
+{
+       IMG_HANDLE hDevNode;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCURRENTTIME;
+
+
+/* Bridge out structure for RGXCurrentTime */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCURRENTTIME_TAG
+{
+       IMG_UINT64 ui64Time;
+       PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCURRENTTIME;
+
+#endif /* COMMON_TIMERQUERY_BRIDGE_H */
diff --git a/drivers/gpu/rogue_m/generated/timerquery_bridge/server_timerquery_bridge.c b/drivers/gpu/rogue_m/generated/timerquery_bridge/server_timerquery_bridge.c
new file mode 100644 (file)
index 0000000..6b64f9d
--- /dev/null
@@ -0,0 +1,283 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for timerquery
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for timerquery
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxtimerquery.h"
+
+
+#include "common_timerquery_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#if defined (SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#include <linux/slab.h>
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+static IMG_INT
+PVRSRVBridgeRGXBeginTimerQuery(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY *psRGXBeginTimerQueryIN,
+                                         PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY *psRGXBeginTimerQueryOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXBeginTimerQueryOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXBeginTimerQueryIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXBeginTimerQueryOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXBeginTimerQuery_exit;
+                                       }
+                               }
+
+
+       psRGXBeginTimerQueryOUT->eError =
+               PVRSRVRGXBeginTimerQueryKM(
+                                       hDevNodeInt,
+                                       psRGXBeginTimerQueryIN->ui32QueryId);
+
+
+
+
+RGXBeginTimerQuery_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXEndTimerQuery(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY *psRGXEndTimerQueryIN,
+                                         PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY *psRGXEndTimerQueryOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXEndTimerQueryOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXEndTimerQueryIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXEndTimerQueryOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXEndTimerQuery_exit;
+                                       }
+                               }
+
+
+       psRGXEndTimerQueryOUT->eError =
+               PVRSRVRGXEndTimerQueryKM(
+                                       hDevNodeInt);
+
+
+
+
+RGXEndTimerQuery_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXQueryTimer(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXQUERYTIMER *psRGXQueryTimerIN,
+                                         PVRSRV_BRIDGE_OUT_RGXQUERYTIMER *psRGXQueryTimerOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXQueryTimerOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXQueryTimerIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXQueryTimerOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXQueryTimer_exit;
+                                       }
+                               }
+
+
+       psRGXQueryTimerOUT->eError =
+               PVRSRVRGXQueryTimerKM(
+                                       hDevNodeInt,
+                                       psRGXQueryTimerIN->ui32QueryId,
+                                       &psRGXQueryTimerOUT->ui64StartTime,
+                                       &psRGXQueryTimerOUT->ui64EndTime);
+
+
+
+
+RGXQueryTimer_exit:
+
+       return 0;
+}
+
+static IMG_INT
+PVRSRVBridgeRGXCurrentTime(IMG_UINT32 ui32DispatchTableEntry,
+                                         PVRSRV_BRIDGE_IN_RGXCURRENTTIME *psRGXCurrentTimeIN,
+                                         PVRSRV_BRIDGE_OUT_RGXCURRENTTIME *psRGXCurrentTimeOUT,
+                                        CONNECTION_DATA *psConnection)
+{
+       IMG_HANDLE hDevNodeInt = IMG_NULL;
+
+
+
+
+
+
+
+                               {
+                                       /* Look up the address from the handle */
+                                       psRGXCurrentTimeOUT->eError =
+                                               PVRSRVLookupHandle(psConnection->psHandleBase,
+                                                                                       (IMG_VOID **) &hDevNodeInt,
+                                                                                       psRGXCurrentTimeIN->hDevNode,
+                                                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
+                                       if(psRGXCurrentTimeOUT->eError != PVRSRV_OK)
+                                       {
+                                               goto RGXCurrentTime_exit;
+                                       }
+                               }
+
+
+       psRGXCurrentTimeOUT->eError =
+               PVRSRVRGXCurrentTime(
+                                       hDevNodeInt,
+                                       &psRGXCurrentTimeOUT->ui64Time);
+
+
+
+
+RGXCurrentTime_exit:
+
+       return 0;
+}
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+
+PVRSRV_ERROR InitTIMERQUERYBridge(IMG_VOID);
+PVRSRV_ERROR DeinitTIMERQUERYBridge(IMG_VOID);
+
+/*
+ * Register all TIMERQUERY functions with services
+ */
+PVRSRV_ERROR InitTIMERQUERYBridge(IMG_VOID)
+{
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_TIMERQUERY, PVRSRV_BRIDGE_TIMERQUERY_RGXBEGINTIMERQUERY, PVRSRVBridgeRGXBeginTimerQuery,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_TIMERQUERY, PVRSRV_BRIDGE_TIMERQUERY_RGXENDTIMERQUERY, PVRSRVBridgeRGXEndTimerQuery,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_TIMERQUERY, PVRSRV_BRIDGE_TIMERQUERY_RGXQUERYTIMER, PVRSRVBridgeRGXQueryTimer,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+       SetDispatchTableEntry(PVRSRV_BRIDGE_TIMERQUERY, PVRSRV_BRIDGE_TIMERQUERY_RGXCURRENTTIME, PVRSRVBridgeRGXCurrentTime,
+                                       IMG_NULL, IMG_NULL,
+                                       0, 0);
+
+
+       return PVRSRV_OK;
+}
+
+/*
+ * Unregister all timerquery functions with services
+ */
+PVRSRV_ERROR DeinitTIMERQUERYBridge(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.0.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.0.h
new file mode 100644 (file)
index 0000000..78a8b4c
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.2.0
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_2_0_H_
+#define _RGXCONFIG_KM_1_V_2_0_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 0
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_2_0_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.20.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.20.h
new file mode 100644 (file)
index 0000000..ea00da1
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.2.20
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_2_20_H_
+#define _RGXCONFIG_KM_1_V_2_20_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 20
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_2_20_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.30.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.30.h
new file mode 100644 (file)
index 0000000..83e5408
--- /dev/null
@@ -0,0 +1,70 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.2.30
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_2_30_H_
+#define _RGXCONFIG_KM_1_V_2_30_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 30
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_2_30_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.5.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.2.5.h
new file mode 100644 (file)
index 0000000..35dbddc
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.2.5
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_2_5_H_
+#define _RGXCONFIG_KM_1_V_2_5_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 5
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_2_5_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.12.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.12.h
new file mode 100644 (file)
index 0000000..be9f47d
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.4.12
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_4_12_H_
+#define _RGXCONFIG_KM_1_V_4_12_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 12
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (256*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_4_12_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.15.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.15.h
new file mode 100644 (file)
index 0000000..7238641
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.4.15
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_4_15_H_
+#define _RGXCONFIG_KM_1_V_4_15_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 15
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (256*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_4_15_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.19.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.19.h
new file mode 100644 (file)
index 0000000..34fa658
--- /dev/null
@@ -0,0 +1,70 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.4.19
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_4_19_H_
+#define _RGXCONFIG_KM_1_V_4_19_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 19
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_4_19_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.5.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.5.h
new file mode 100644 (file)
index 0000000..7c52ec4
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.4.5
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_4_5_H_
+#define _RGXCONFIG_KM_1_V_4_5_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 5
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_4_5_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.6.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_1.V.4.6.h
new file mode 100644 (file)
index 0000000..a385f5d
--- /dev/null
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 1.V.4.6
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_1_V_4_6_H_
+#define _RGXCONFIG_KM_1_V_4_6_H_
+
+/***** Automatically generated file (3/25/2015 5:08:35 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:35 AM)************************************************************/
+
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 6
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_1_V_4_6_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h
new file mode 100644 (file)
index 0000000..0f5ef18
--- /dev/null
@@ -0,0 +1,67 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 12.V.1.20
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_12_V_1_20_H_
+#define _RGXCONFIG_KM_12_V_1_20_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 12
+#define RGX_BNC_KM_N 1
+#define RGX_BNC_KM_C 20
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_NUM_CLUSTERS (1)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
+#define RGX_FEATURE_META (LTP217)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (0*1024)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_12_V_1_20_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.51.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.51.h
new file mode 100644 (file)
index 0000000..3230b74
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.2.51
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_2_51_H_
+#define _RGXCONFIG_KM_4_V_2_51_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 51
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_2_51_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
new file mode 100644 (file)
index 0000000..dc439c2
--- /dev/null
@@ -0,0 +1,73 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.2.52
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_2_52_H_
+#define _RGXCONFIG_KM_4_V_2_52_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 52
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_2_52_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.57.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.57.h
new file mode 100644 (file)
index 0000000..55f9261
--- /dev/null
@@ -0,0 +1,73 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.2.57
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_2_57_H_
+#define _RGXCONFIG_KM_4_V_2_57_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 57
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_2_57_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.58.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.2.58.h
new file mode 100644 (file)
index 0000000..8c44433
--- /dev/null
@@ -0,0 +1,73 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.2.58
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_2_58_H_
+#define _RGXCONFIG_KM_4_V_2_58_H_
+
+/***** Automatically generated file (3/25/2015 5:08:37 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:37 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 58
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_2_58_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.4.53.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.4.53.h
new file mode 100644 (file)
index 0000000..2b408a3
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.4.53
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_4_53_H_
+#define _RGXCONFIG_KM_4_V_4_53_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 53
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_4_53_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.6.62.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_4.V.6.62.h
new file mode 100644 (file)
index 0000000..5ef29d2
--- /dev/null
@@ -0,0 +1,74 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 4.V.6.62
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_4_V_6_62_H_
+#define _RGXCONFIG_KM_4_V_6_62_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_N 6
+#define RGX_BNC_KM_C 62
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_NUM_CLUSTERS (6)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_SLC_BANKS (4)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_4_V_6_62_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h
new file mode 100644 (file)
index 0000000..64541c4
--- /dev/null
@@ -0,0 +1,70 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 5.V.1.46
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_5_V_1_46_H_
+#define _RGXCONFIG_KM_5_V_1_46_H_
+
+/***** Automatically generated file (3/25/2015 5:08:36 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:36 AM)************************************************************/
+
+#define RGX_BNC_KM_B 5
+#define RGX_BNC_KM_N 1
+#define RGX_BNC_KM_C 46
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_NUM_CLUSTERS (1)
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
+#define RGX_FEATURE_META (LTP217)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_5_V_1_46_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.2.34.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.2.34.h
new file mode 100644 (file)
index 0000000..1df1eb7
--- /dev/null
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 8.V.2.34
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_8_V_2_34_H_
+#define _RGXCONFIG_KM_8_V_2_34_H_
+
+/***** Automatically generated file (3/25/2015 5:08:37 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:37 AM)************************************************************/
+
+#define RGX_BNC_KM_B 8
+#define RGX_BNC_KM_N 2
+#define RGX_BNC_KM_C 34
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_SCALABLE_TE_ARCH (1)
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (4)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_SLC_VIVT 
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (128)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_S7_CACHE_HIERARCHY 
+#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_SLC_BANKS (2)
+#define RGX_FEATURE_META_DMA_CHANNEL_COUNT (4)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (3)
+#define RGX_FEATURE_META_COREMEM_BANKS (8)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_DMA 
+#define RGX_FEATURE_META_COREMEM_SIZE (64)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_8_V_2_34_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.4.38.h b/drivers/gpu/rogue_m/hwdefs/km/configs/rgxconfig_km_8.V.4.38.h
new file mode 100644 (file)
index 0000000..c2f3365
--- /dev/null
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@Title          RGX Config BVNC 8.V.4.38
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCONFIG_KM_8_V_4_38_H_
+#define _RGXCONFIG_KM_8_V_4_38_H_
+
+/***** Automatically generated file (3/25/2015 5:08:37 AM): Do not edit manually ********************/
+/***** Timestamp:  (3/25/2015 5:08:37 AM)************************************************************/
+
+#define RGX_BNC_KM_B 8
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 38
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_AXI_ACELITE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_SCALABLE_TE_ARCH (1)
+#define RGX_FEATURE_GS_RTA_SUPPORT 
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_META (LTP218)
+#define RGX_FEATURE_SLC_VIVT 
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (256)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_S7_CACHE_HIERARCHY 
+#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_SLC_BANKS (2)
+#define RGX_FEATURE_META_DMA_CHANNEL_COUNT (4)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (3)
+#define RGX_FEATURE_META_COREMEM_BANKS (8)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_META_DMA 
+#define RGX_FEATURE_META_COREMEM_SIZE (64)
+#define RGX_FEATURE_COMPUTE 
+
+
+#endif /* _RGXCONFIG_8_V_4_38_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.32.4.19.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.32.4.19.h
new file mode 100644 (file)
index 0000000..f078e42
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.32.4.19
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_32_4_19_H_
+#define _RGXCORE_KM_1_32_4_19_H_
+
+/***** Automatically generated file (3/4/2015 2:27:37 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:37 PM)************************************************************/
+/***** CS: @2615289 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.32.4.19 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 32
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 19
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_32_4_19_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.33.2.5.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.33.2.5.h
new file mode 100644 (file)
index 0000000..f9939a1
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.33.2.5
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_33_2_5_H_
+#define _RGXCORE_KM_1_33_2_5_H_
+
+/***** Automatically generated file (3/4/2015 2:27:36 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:36 PM)************************************************************/
+/***** CS: @2106753 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.33.2.5 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 33
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 5
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_33_2_5_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.39.4.19.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.39.4.19.h
new file mode 100644 (file)
index 0000000..cd293a5
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.39.4.19
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_39_4_19_H_
+#define _RGXCORE_KM_1_39_4_19_H_
+
+/***** Automatically generated file (3/4/2015 2:27:37 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:37 PM)************************************************************/
+/***** CS: @2784771 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.39.4.19 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 39
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 19
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_39_4_19_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.48.2.0.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.48.2.0.h
new file mode 100644 (file)
index 0000000..e970ddb
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.48.2.0
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_48_2_0_H_
+#define _RGXCORE_KM_1_48_2_0_H_
+
+/***** Automatically generated file (3/4/2015 2:27:36 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:36 PM)************************************************************/
+/***** CS: @2523218 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.48.2.0 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 48
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 0
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_48_2_0_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.72.4.12.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.72.4.12.h
new file mode 100644 (file)
index 0000000..5dc662d
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.72.4.12
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_72_4_12_H_
+#define _RGXCORE_KM_1_72_4_12_H_
+
+/***** Automatically generated file (3/4/2015 2:27:34 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:34 PM)************************************************************/
+/***** CS: @2646650 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.72.4.12 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 72
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 12
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_72_4_12_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.20.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.20.h
new file mode 100644 (file)
index 0000000..ece76e0
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.75.2.20
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_75_2_20_H_
+#define _RGXCORE_KM_1_75_2_20_H_
+
+/***** Automatically generated file (3/4/2015 2:27:36 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:36 PM)************************************************************/
+/***** CS: @2309075 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.75.2.20 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 75
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 20
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_75_2_20_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.30.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.75.2.30.h
new file mode 100644 (file)
index 0000000..f03f0a5
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.75.2.30
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_75_2_30_H_
+#define _RGXCORE_KM_1_75_2_30_H_
+
+/***** Automatically generated file (3/4/2015 2:27:33 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:33 PM)************************************************************/
+/***** CS: @2309075 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.75.2.30 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 75
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 30
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_75_2_30_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.76.4.6.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.76.4.6.h
new file mode 100644 (file)
index 0000000..1ba4058
--- /dev/null
@@ -0,0 +1,73 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.76.4.6
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_76_4_6_H_
+#define _RGXCORE_KM_1_76_4_6_H_
+
+/***** Automatically generated file (3/4/2015 2:27:34 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:34 PM)************************************************************/
+/***** CS: @2318404 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.76.4.6 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 76
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 6
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+#define FIX_HW_BRN_42480
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_76_4_6_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.81.4.15.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.81.4.15.h
new file mode 100644 (file)
index 0000000..c285483
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.81.4.15
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_81_4_15_H_
+#define _RGXCORE_KM_1_81_4_15_H_
+
+/***** Automatically generated file (3/4/2015 2:27:36 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:36 PM)************************************************************/
+/***** CS: @2373516 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.81.4.15 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 81
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 15
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_81_4_15_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.82.4.5.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_1.82.4.5.h
new file mode 100644 (file)
index 0000000..5254ea8
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 1.82.4.5
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_1_82_4_5_H_
+#define _RGXCORE_KM_1_82_4_5_H_
+
+/***** Automatically generated file (3/4/2015 2:27:34 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:34 PM)************************************************************/
+/***** CS: @2503111 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 1.82.4.5 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 82
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 5
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_1_82_4_5_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_12.5.1.20.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_12.5.1.20.h
new file mode 100644 (file)
index 0000000..79d82e1
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 12.5.1.20
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_12_5_1_20_H_
+#define _RGXCORE_KM_12_5_1_20_H_
+
+/***** Automatically generated file (4/27/2015 2:03:36 PM): Do not edit manually ********************/
+/***** Timestamp:  (4/27/2015 2:03:36 PM)************************************************************/
+/***** CS: @3146507 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 12.5.1.20 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 12
+#define RGX_BVNC_KM_V 5
+#define RGX_BVNC_KM_N 1
+#define RGX_BVNC_KM_C 20
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_12_5_1_20_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.29.2.51.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.29.2.51.h
new file mode 100644 (file)
index 0000000..404004d
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.29.2.51
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_29_2_51_H_
+#define _RGXCORE_KM_4_29_2_51_H_
+
+/***** Automatically generated file (3/2/2015 6:26:08 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:08 PM)************************************************************/
+/***** CS: @2944502 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.29.2.51 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 29
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 51
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_29_2_51_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
new file mode 100644 (file)
index 0000000..2c396dc
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.32.2.52
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_32_2_52_H_
+#define _RGXCORE_KM_4_32_2_52_H_
+
+/***** Automatically generated file (3/2/2015 6:26:04 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:04 PM)************************************************************/
+/***** CS: @2966609 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.32.2.52 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 32
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 52
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_32_2_52_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.40.2.51.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.40.2.51.h
new file mode 100644 (file)
index 0000000..98348b2
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.40.2.51
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_40_2_51_H_
+#define _RGXCORE_KM_4_40_2_51_H_
+
+/***** Automatically generated file (3/2/2015 6:26:02 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:02 PM)************************************************************/
+/***** CS: @3254374 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.40.2.51 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 40
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 51
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_40_2_51_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.41.2.57.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.41.2.57.h
new file mode 100644 (file)
index 0000000..f9b8c3f
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.41.2.57
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_41_2_57_H_
+#define _RGXCORE_KM_4_41_2_57_H_
+
+/***** Automatically generated file (3/2/2015 6:26:02 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:02 PM)************************************************************/
+/***** CS: @3254338 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.41.2.57 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 41
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 57
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_41_2_57_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.42.4.53.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.42.4.53.h
new file mode 100644 (file)
index 0000000..6e9ded9
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.42.4.53
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_42_4_53_H_
+#define _RGXCORE_KM_4_42_4_53_H_
+
+/***** Automatically generated file (3/2/2015 6:26:02 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:02 PM)************************************************************/
+/***** CS: @3250390 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.42.4.53 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 42
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 53
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_42_4_53_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.43.6.62.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.43.6.62.h
new file mode 100644 (file)
index 0000000..5bfa76a
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.43.6.62
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_43_6_62_H_
+#define _RGXCORE_KM_4_43_6_62_H_
+
+/***** Automatically generated file (3/2/2015 6:26:02 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/2/2015 6:26:02 PM)************************************************************/
+/***** CS: @3253129 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.43.6.62 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 43
+#define RGX_BVNC_KM_N 6
+#define RGX_BVNC_KM_C 62
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_43_6_62_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.45.2.58.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_4.45.2.58.h
new file mode 100644 (file)
index 0000000..66eb624
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 4.45.2.58
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_4_45_2_58_H_
+#define _RGXCORE_KM_4_45_2_58_H_
+
+/***** Automatically generated file (3/23/2015 2:49:16 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/23/2015 2:49:16 PM)************************************************************/
+/***** CS: @3478233 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 4.45.2.58 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_V 45
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 58
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_57193
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_4_45_2_58_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.11.1.46.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.11.1.46.h
new file mode 100644 (file)
index 0000000..ef21655
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 5.11.1.46
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_5_11_1_46_H_
+#define _RGXCORE_KM_5_11_1_46_H_
+
+/***** Automatically generated file (4/2/2015 11:53:03 AM): Do not edit manually ********************/
+/***** Timestamp:  (4/2/2015 11:53:03 AM)************************************************************/
+/***** CS: @3485232 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 5.11.1.46 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 5
+#define RGX_BVNC_KM_V 11
+#define RGX_BVNC_KM_N 1
+#define RGX_BVNC_KM_C 46
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_42480
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_5_11_1_46_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.9.1.46.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_5.9.1.46.h
new file mode 100644 (file)
index 0000000..9105e8c
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 5.9.1.46
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_5_9_1_46_H_
+#define _RGXCORE_KM_5_9_1_46_H_
+
+/***** Automatically generated file (3/4/2015 2:27:37 PM): Do not edit manually ********************/
+/***** Timestamp:  (3/4/2015 2:27:37 PM)************************************************************/
+/***** CS: @2967148 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 5.9.1.46 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 5
+#define RGX_BVNC_KM_V 9
+#define RGX_BVNC_KM_N 1
+#define RGX_BVNC_KM_C 46
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+#define FIX_HW_BRN_38344
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+
+
+
+#endif /* _RGXCORE_KM_5_9_1_46_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.21.2.34.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.21.2.34.h
new file mode 100644 (file)
index 0000000..11fb9bc
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 8.21.2.34
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_8_21_2_34_H_
+#define _RGXCORE_KM_8_21_2_34_H_
+
+/***** Automatically generated file (21/04/2015 18:47:55): Do not edit manually ********************/
+/***** Timestamp:  (21/04/2015 18:47:55)************************************************************/
+/***** CS: @3480967 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 8.21.2.34 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 8
+#define RGX_BVNC_KM_V 21
+#define RGX_BVNC_KM_N 2
+#define RGX_BVNC_KM_C 34
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+#define HW_ERN_45914
+
+
+
+#endif /* _RGXCORE_KM_8_21_2_34_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.41.4.38.h b/drivers/gpu/rogue_m/hwdefs/km/cores/rgxcore_km_8.41.4.38.h
new file mode 100644 (file)
index 0000000..5d26a7f
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title          RGX Core BVNC 8.41.4.38
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXCORE_KM_8_41_4_38_H_
+#define _RGXCORE_KM_8_41_4_38_H_
+
+/***** Automatically generated file (5/12/2015 5:46:10 AM): Do not edit manually ********************/
+/***** Timestamp:  (5/12/2015 5:46:10 AM)************************************************************/
+/***** CS: @3498807 ******************************************************************/
+
+
+/******************************************************************************
+ * BVNC = 8.41.4.38 
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 8
+#define RGX_BVNC_KM_V 41
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 38
+
+/******************************************************************************
+ * Errata 
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Enhancements 
+ *****************************************************************************/
+#define HW_ERN_45914
+
+
+
+#endif /* _RGXCORE_KM_8_41_4_38_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/rgx_cr_defs_km.h b/drivers/gpu/rogue_m/hwdefs/km/rgx_cr_defs_km.h
new file mode 100644 (file)
index 0000000..6b0c403
--- /dev/null
@@ -0,0 +1,3836 @@
+/*************************************************************************/ /*!
+@Title          Hardware definition file rgx_cr_defs_km.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/*               ****   Autogenerated C -- do not edit    ****               */
+
+/*
+ * Generated by regconv version MAIN@3250555
+ *   from files:
+ */
+
+#if !defined(__IMG_EXPLICIT_INCLUDE_HWDEFS)
+#error This file may only be included if explicitly defined
+#endif
+
+#ifndef _RGX_CR_DEFS_KM_H_
+#define _RGX_CR_DEFS_KM_H_
+
+#include "img_types.h"
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_CLK_CTRL
+*/
+#define RGX_CR_CLK_CTRL                                   (0x0000U)
+#define RGX_CR_CLK_CTRL_MASKFULL                          (IMG_UINT64_C(0xFFFFC3003F3F3F0F))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT                   (62U)
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK                  (IMG_UINT64_C(0X3FFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_SHIFT                         (60U)
+#define RGX_CR_CLK_CTRL_IPP_CLRMSK                        (IMG_UINT64_C(0XCFFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_IPP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_ON                            (IMG_UINT64_C(0x1000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_AUTO                          (IMG_UINT64_C(0x2000000000000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_CLK_CTRL_FBC_SHIFT                         (58U)
+#define RGX_CR_CLK_CTRL_FBC_CLRMSK                        (IMG_UINT64_C(0XF3FFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))
+#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_SHIFT                        (56U)
+#define RGX_CR_CLK_CTRL_FBDC_CLRMSK                       (IMG_UINT64_C(0XFCFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT                  (54U)
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK                 (IMG_UINT64_C(0XFF3FFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))
+#define RGX_CR_CLK_CTRL_USCS_SHIFT                        (52U)
+#define RGX_CR_CLK_CTRL_USCS_CLRMSK                       (IMG_UINT64_C(0XFFCFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_USCS_OFF                          (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_USCS_ON                           (IMG_UINT64_C(0x0010000000000000))
+#define RGX_CR_CLK_CTRL_USCS_AUTO                         (IMG_UINT64_C(0x0020000000000000))
+#define RGX_CR_CLK_CTRL_PBE_SHIFT                         (50U)
+#define RGX_CR_CLK_CTRL_PBE_CLRMSK                        (IMG_UINT64_C(0XFFF3FFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))
+#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_SHIFT                      (48U)
+#define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK                     (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))
+#define RGX_CR_CLK_CTRL_CDM_SHIFT                         (46U)
+#define RGX_CR_CLK_CTRL_CDM_CLRMSK                        (IMG_UINT64_C(0XFFFF3FFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_CDM_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_CDM_ON                            (IMG_UINT64_C(0x0000400000000000))
+#define RGX_CR_CLK_CTRL_CDM_AUTO                          (IMG_UINT64_C(0x0000800000000000))
+#define RGX_CR_CLK_CTRL_BIF_SHIFT                         (40U)
+#define RGX_CR_CLK_CTRL_BIF_CLRMSK                        (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))
+#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_SHIFT               (28U)
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF                 (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON                  (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO                (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_SHIFT                      (26U)
+#define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
+#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_CTRL_TPU_SHIFT                         (24U)
+#define RGX_CR_CLK_CTRL_TPU_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
+#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))
+#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_CTRL_USC_SHIFT                         (20U)
+#define RGX_CR_CLK_CTRL_USC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
+#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_CTRL_TLA_SHIFT                         (18U)
+#define RGX_CR_CLK_CTRL_TLA_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
+#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))
+#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))
+#define RGX_CR_CLK_CTRL_SLC_SHIFT                         (16U)
+#define RGX_CR_CLK_CTRL_SLC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
+#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))
+#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))
+#define RGX_CR_CLK_CTRL_PDS_SHIFT                         (12U)
+#define RGX_CR_CLK_CTRL_PDS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
+#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_CTRL_VDM_SHIFT                         (10U)
+#define RGX_CR_CLK_CTRL_VDM_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
+#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))
+#define RGX_CR_CLK_CTRL_PM_SHIFT                          (8U)
+#define RGX_CR_CLK_CTRL_PM_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_CTRL_TSP_SHIFT                         (2U)
+#define RGX_CR_CLK_CTRL_TSP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
+#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_CTRL_ISP_SHIFT                         (0U)
+#define RGX_CR_CLK_CTRL_ISP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))
+#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
+
+
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_CLK_CTRL
+*/
+#define RGX_CR_CLK_CTRL                                   (0x0000U)
+#define RGX_CR_CLK_CTRL_MASKFULL                          (IMG_UINT64_C(0xFFFFFF003F3FFFFF))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT                   (62U)
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK                  (IMG_UINT64_C(0X3FFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_SHIFT                         (60U)
+#define RGX_CR_CLK_CTRL_IPP_CLRMSK                        (IMG_UINT64_C(0XCFFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_IPP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_ON                            (IMG_UINT64_C(0x1000000000000000))
+#define RGX_CR_CLK_CTRL_IPP_AUTO                          (IMG_UINT64_C(0x2000000000000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_CLK_CTRL_FBC_SHIFT                         (58U)
+#define RGX_CR_CLK_CTRL_FBC_CLRMSK                        (IMG_UINT64_C(0XF3FFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))
+#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_SHIFT                        (56U)
+#define RGX_CR_CLK_CTRL_FBDC_CLRMSK                       (IMG_UINT64_C(0XFCFFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT                  (54U)
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK                 (IMG_UINT64_C(0XFF3FFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))
+#define RGX_CR_CLK_CTRL_USCS_SHIFT                        (52U)
+#define RGX_CR_CLK_CTRL_USCS_CLRMSK                       (IMG_UINT64_C(0XFFCFFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_USCS_OFF                          (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_USCS_ON                           (IMG_UINT64_C(0x0010000000000000))
+#define RGX_CR_CLK_CTRL_USCS_AUTO                         (IMG_UINT64_C(0x0020000000000000))
+#define RGX_CR_CLK_CTRL_PBE_SHIFT                         (50U)
+#define RGX_CR_CLK_CTRL_PBE_CLRMSK                        (IMG_UINT64_C(0XFFF3FFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))
+#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_SHIFT                      (48U)
+#define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK                     (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))
+#define RGX_CR_CLK_CTRL_CDM_SHIFT                         (46U)
+#define RGX_CR_CLK_CTRL_CDM_CLRMSK                        (IMG_UINT64_C(0XFFFF3FFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_CDM_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_CDM_ON                            (IMG_UINT64_C(0x0000400000000000))
+#define RGX_CR_CLK_CTRL_CDM_AUTO                          (IMG_UINT64_C(0x0000800000000000))
+#define RGX_CR_CLK_CTRL_SIDEKICK_SHIFT                    (44U)
+#define RGX_CR_CLK_CTRL_SIDEKICK_CLRMSK                   (IMG_UINT64_C(0XFFFFCFFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_SIDEKICK_OFF                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_SIDEKICK_ON                       (IMG_UINT64_C(0x0000100000000000))
+#define RGX_CR_CLK_CTRL_SIDEKICK_AUTO                     (IMG_UINT64_C(0x0000200000000000))
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_SHIFT                (42U)
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_CLRMSK               (IMG_UINT64_C(0XFFFFF3FFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_OFF                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_ON                   (IMG_UINT64_C(0x0000040000000000))
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_AUTO                 (IMG_UINT64_C(0x0000080000000000))
+#define RGX_CR_CLK_CTRL_BIF_SHIFT                         (40U)
+#define RGX_CR_CLK_CTRL_BIF_CLRMSK                        (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
+#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))
+#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_SHIFT               (28U)
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF                 (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON                  (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO                (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_SHIFT                      (26U)
+#define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
+#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_CTRL_TPU_SHIFT                         (24U)
+#define RGX_CR_CLK_CTRL_TPU_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
+#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))
+#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_CTRL_USC_SHIFT                         (20U)
+#define RGX_CR_CLK_CTRL_USC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
+#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_CTRL_TLA_SHIFT                         (18U)
+#define RGX_CR_CLK_CTRL_TLA_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
+#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))
+#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))
+#define RGX_CR_CLK_CTRL_SLC_SHIFT                         (16U)
+#define RGX_CR_CLK_CTRL_SLC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
+#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))
+#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))
+#define RGX_CR_CLK_CTRL_UVS_SHIFT                         (14U)
+#define RGX_CR_CLK_CTRL_UVS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFF3FFF))
+#define RGX_CR_CLK_CTRL_UVS_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_UVS_ON                            (IMG_UINT64_C(0x0000000000004000))
+#define RGX_CR_CLK_CTRL_UVS_AUTO                          (IMG_UINT64_C(0x0000000000008000))
+#define RGX_CR_CLK_CTRL_PDS_SHIFT                         (12U)
+#define RGX_CR_CLK_CTRL_PDS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
+#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_CTRL_VDM_SHIFT                         (10U)
+#define RGX_CR_CLK_CTRL_VDM_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
+#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))
+#define RGX_CR_CLK_CTRL_PM_SHIFT                          (8U)
+#define RGX_CR_CLK_CTRL_PM_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_CTRL_GPP_SHIFT                         (6U)
+#define RGX_CR_CLK_CTRL_GPP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFF3F))
+#define RGX_CR_CLK_CTRL_GPP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_GPP_ON                            (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_CTRL_GPP_AUTO                          (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_CTRL_TE_SHIFT                          (4U)
+#define RGX_CR_CLK_CTRL_TE_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
+#define RGX_CR_CLK_CTRL_TE_OFF                            (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TE_ON                             (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_CTRL_TE_AUTO                           (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_CTRL_TSP_SHIFT                         (2U)
+#define RGX_CR_CLK_CTRL_TSP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
+#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_CTRL_ISP_SHIFT                         (0U)
+#define RGX_CR_CLK_CTRL_ISP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))
+#endif /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
+
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_CLK_STATUS
+*/
+#define RGX_CR_CLK_STATUS                                 (0x0008U)
+#define RGX_CR_CLK_STATUS_MASKFULL                        (IMG_UINT64_C(0x00000001FF907773))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT                  (32U)
+#define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT                 (31U)
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))
+#define RGX_CR_CLK_STATUS_IPP_SHIFT                       (30U)
+#define RGX_CR_CLK_STATUS_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
+#define RGX_CR_CLK_STATUS_IPP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_IPP_RUNNING                     (IMG_UINT64_C(0x0000000040000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_CLK_STATUS_FBC_SHIFT                       (29U)
+#define RGX_CR_CLK_STATUS_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
+#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_STATUS_FBDC_SHIFT                      (28U)
+#define RGX_CR_CLK_STATUS_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
+#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_SHIFT                (27U)
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING              (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_STATUS_USCS_SHIFT                      (26U)
+#define RGX_CR_CLK_STATUS_USCS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
+#define RGX_CR_CLK_STATUS_USCS_GATED                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_USCS_RUNNING                    (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_STATUS_PBE_SHIFT                       (25U)
+#define RGX_CR_CLK_STATUS_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
+#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_STATUS_MCU_L1_SHIFT                    (24U)
+#define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
+#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))
+#define RGX_CR_CLK_STATUS_CDM_SHIFT                       (23U)
+#define RGX_CR_CLK_STATUS_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
+#define RGX_CR_CLK_STATUS_CDM_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_CDM_RUNNING                     (IMG_UINT64_C(0x0000000000800000))
+#define RGX_CR_CLK_STATUS_BIF_SHIFT                       (20U)
+#define RGX_CR_CLK_STATUS_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
+#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_SHIFT             (14U)
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED             (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING           (IMG_UINT64_C(0x0000000000004000))
+#define RGX_CR_CLK_STATUS_MCU_L0_SHIFT                    (13U)
+#define RGX_CR_CLK_STATUS_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
+#define RGX_CR_CLK_STATUS_MCU_L0_GATED                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING                  (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_STATUS_TPU_SHIFT                       (12U)
+#define RGX_CR_CLK_STATUS_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
+#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_STATUS_USC_SHIFT                       (10U)
+#define RGX_CR_CLK_STATUS_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
+#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_STATUS_TLA_SHIFT                       (9U)
+#define RGX_CR_CLK_STATUS_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
+#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_STATUS_SLC_SHIFT                       (8U)
+#define RGX_CR_CLK_STATUS_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_STATUS_PDS_SHIFT                       (6U)
+#define RGX_CR_CLK_STATUS_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
+#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_STATUS_VDM_SHIFT                       (5U)
+#define RGX_CR_CLK_STATUS_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_STATUS_PM_SHIFT                        (4U)
+#define RGX_CR_CLK_STATUS_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_STATUS_TSP_SHIFT                       (1U)
+#define RGX_CR_CLK_STATUS_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_STATUS_ISP_SHIFT                       (0U)
+#define RGX_CR_CLK_STATUS_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))
+#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
+
+
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_CLK_STATUS
+*/
+#define RGX_CR_CLK_STATUS                                 (0x0008U)
+#define RGX_CR_CLK_STATUS_MASKFULL                        (IMG_UINT64_C(0x00000001FFF077FF))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT                  (32U)
+#define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT                 (31U)
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))
+#define RGX_CR_CLK_STATUS_IPP_SHIFT                       (30U)
+#define RGX_CR_CLK_STATUS_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
+#define RGX_CR_CLK_STATUS_IPP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_IPP_RUNNING                     (IMG_UINT64_C(0x0000000040000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_CLK_STATUS_FBC_SHIFT                       (29U)
+#define RGX_CR_CLK_STATUS_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
+#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_STATUS_FBDC_SHIFT                      (28U)
+#define RGX_CR_CLK_STATUS_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
+#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_SHIFT                (27U)
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING              (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_STATUS_USCS_SHIFT                      (26U)
+#define RGX_CR_CLK_STATUS_USCS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
+#define RGX_CR_CLK_STATUS_USCS_GATED                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_USCS_RUNNING                    (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_STATUS_PBE_SHIFT                       (25U)
+#define RGX_CR_CLK_STATUS_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
+#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_STATUS_MCU_L1_SHIFT                    (24U)
+#define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
+#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))
+#define RGX_CR_CLK_STATUS_CDM_SHIFT                       (23U)
+#define RGX_CR_CLK_STATUS_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
+#define RGX_CR_CLK_STATUS_CDM_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_CDM_RUNNING                     (IMG_UINT64_C(0x0000000000800000))
+#define RGX_CR_CLK_STATUS_SIDEKICK_SHIFT                  (22U)
+#define RGX_CR_CLK_STATUS_SIDEKICK_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
+#define RGX_CR_CLK_STATUS_SIDEKICK_GATED                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_SIDEKICK_RUNNING                (IMG_UINT64_C(0x0000000000400000))
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_SHIFT              (21U)
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_GATED              (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_RUNNING            (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_STATUS_BIF_SHIFT                       (20U)
+#define RGX_CR_CLK_STATUS_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
+#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_SHIFT             (14U)
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED             (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING           (IMG_UINT64_C(0x0000000000004000))
+#define RGX_CR_CLK_STATUS_MCU_L0_SHIFT                    (13U)
+#define RGX_CR_CLK_STATUS_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
+#define RGX_CR_CLK_STATUS_MCU_L0_GATED                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING                  (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_STATUS_TPU_SHIFT                       (12U)
+#define RGX_CR_CLK_STATUS_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
+#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_STATUS_USC_SHIFT                       (10U)
+#define RGX_CR_CLK_STATUS_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
+#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_STATUS_TLA_SHIFT                       (9U)
+#define RGX_CR_CLK_STATUS_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
+#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_STATUS_SLC_SHIFT                       (8U)
+#define RGX_CR_CLK_STATUS_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_STATUS_UVS_SHIFT                       (7U)
+#define RGX_CR_CLK_STATUS_UVS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
+#define RGX_CR_CLK_STATUS_UVS_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_UVS_RUNNING                     (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_STATUS_PDS_SHIFT                       (6U)
+#define RGX_CR_CLK_STATUS_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
+#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_STATUS_VDM_SHIFT                       (5U)
+#define RGX_CR_CLK_STATUS_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_STATUS_PM_SHIFT                        (4U)
+#define RGX_CR_CLK_STATUS_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_STATUS_GPP_SHIFT                       (3U)
+#define RGX_CR_CLK_STATUS_GPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_CLK_STATUS_GPP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_GPP_RUNNING                     (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_STATUS_TE_SHIFT                        (2U)
+#define RGX_CR_CLK_STATUS_TE_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_CLK_STATUS_TE_GATED                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TE_RUNNING                      (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_STATUS_TSP_SHIFT                       (1U)
+#define RGX_CR_CLK_STATUS_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_STATUS_ISP_SHIFT                       (0U)
+#define RGX_CR_CLK_STATUS_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))
+#endif /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
+
+
+/*
+    Register RGX_CR_CORE_ID
+*/
+#define RGX_CR_CORE_ID                                    (0x0018U)
+#define RGX_CR_CORE_ID_MASKFULL                           (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_CORE_ID_ID_SHIFT                           (16U)
+#define RGX_CR_CORE_ID_ID_CLRMSK                          (0X0000FFFFU)
+#define RGX_CR_CORE_ID_CONFIG_SHIFT                       (0U)
+#define RGX_CR_CORE_ID_CONFIG_CLRMSK                      (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_CORE_REVISION
+*/
+#define RGX_CR_CORE_REVISION                              (0x0020U)
+#define RGX_CR_CORE_REVISION_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_CORE_REVISION_DESIGNER_SHIFT               (24U)
+#define RGX_CR_CORE_REVISION_DESIGNER_CLRMSK              (0X00FFFFFFU)
+#define RGX_CR_CORE_REVISION_MAJOR_SHIFT                  (16U)
+#define RGX_CR_CORE_REVISION_MAJOR_CLRMSK                 (0XFF00FFFFU)
+#define RGX_CR_CORE_REVISION_MINOR_SHIFT                  (8U)
+#define RGX_CR_CORE_REVISION_MINOR_CLRMSK                 (0XFFFF00FFU)
+#define RGX_CR_CORE_REVISION_MAINTENANCE_SHIFT            (0U)
+#define RGX_CR_CORE_REVISION_MAINTENANCE_CLRMSK           (0XFFFFFF00U)
+
+
+/*
+    Register RGX_CR_DESIGNER_REV_FIELD1
+*/
+#define RGX_CR_DESIGNER_REV_FIELD1                        (0x0028U)
+#define RGX_CR_DESIGNER_REV_FIELD1_MASKFULL               (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT (0U)
+#define RGX_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_CLRMSK (00000000U)
+
+
+/*
+    Register RGX_CR_DESIGNER_REV_FIELD2
+*/
+#define RGX_CR_DESIGNER_REV_FIELD2                        (0x0030U)
+#define RGX_CR_DESIGNER_REV_FIELD2_MASKFULL               (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT (0U)
+#define RGX_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_CLRMSK (00000000U)
+
+
+/*
+    Register RGX_CR_CHANGESET_NUMBER
+*/
+#define RGX_CR_CHANGESET_NUMBER                           (0x0040U)
+#define RGX_CR_CHANGESET_NUMBER_MASKFULL                  (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_CHANGESET_NUMBER_CHANGESET_NUMBER_SHIFT    (0U)
+#define RGX_CR_CHANGESET_NUMBER_CHANGESET_NUMBER_CLRMSK   (IMG_UINT64_C(0000000000000000))
+
+
+/*
+    Register RGX_CR_CLK_XTPLUS_CTRL
+*/
+#define RGX_CR_CLK_XTPLUS_CTRL                            (0x0080U)
+#define RGX_CR_CLK_XTPLUS_CTRL_MASKFULL                   (IMG_UINT64_C(0x0000000FFFFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_SHIFT                 (34U)
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_CLRMSK                (IMG_UINT64_C(0XFFFFFFF3FFFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_OFF                   (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_ON                    (IMG_UINT64_C(0x0000000400000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_AUTO                  (IMG_UINT64_C(0x0000000800000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_SHIFT                  (32U)
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFCFFFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_ON                     (IMG_UINT64_C(0x0000000100000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_AUTO                   (IMG_UINT64_C(0x0000000200000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_SHIFT              (30U)
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_CLRMSK             (IMG_UINT64_C(0XFFFFFFFF3FFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_OFF                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_ON                 (IMG_UINT64_C(0x0000000040000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_AUTO               (IMG_UINT64_C(0x0000000080000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_SHIFT                (28U)
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_OFF                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_ON                   (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_AUTO                 (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_SHIFT               (26U)
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_OFF                 (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_ON                  (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_AUTO                (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_SHIFT                (24U)
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_OFF                  (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_ON                   (IMG_UINT64_C(0x0000000001000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_AUTO                 (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_SHIFT           (22U)
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFF3FFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_OFF             (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_ON              (IMG_UINT64_C(0x0000000000400000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_AUTO            (IMG_UINT64_C(0x0000000000800000))
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_SHIFT       (20U)
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_OFF         (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_ON          (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_AUTO        (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_SHIFT           (18U)
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_OFF             (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_ON              (IMG_UINT64_C(0x0000000000040000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_AUTO            (IMG_UINT64_C(0x0000000000080000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_SHIFT             (16U)
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_OFF               (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_ON                (IMG_UINT64_C(0x0000000000010000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_AUTO              (IMG_UINT64_C(0x0000000000020000))
+#define RGX_CR_CLK_XTPLUS_CTRL_RAST_SHIFT                 (14U)
+#define RGX_CR_CLK_XTPLUS_CTRL_RAST_CLRMSK                (IMG_UINT64_C(0XFFFFFFFFFFFF3FFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_RAST_OFF                   (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_RAST_ON                    (IMG_UINT64_C(0x0000000000004000))
+#define RGX_CR_CLK_XTPLUS_CTRL_RAST_AUTO                  (IMG_UINT64_C(0x0000000000008000))
+#define RGX_CR_CLK_XTPLUS_CTRL_UVB_SHIFT                  (12U)
+#define RGX_CR_CLK_XTPLUS_CTRL_UVB_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_UVB_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_UVB_ON                     (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_XTPLUS_CTRL_UVB_AUTO                   (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GPP_SHIFT                  (10U)
+#define RGX_CR_CLK_XTPLUS_CTRL_GPP_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
+#define RGX_CR_CLK_XTPLUS_CTRL_GPP_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GPP_ON                     (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_XTPLUS_CTRL_GPP_AUTO                   (IMG_UINT64_C(0x0000000000000800))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_PIPE_SHIFT             (8U)
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_PIPE_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_PIPE_OFF               (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_PIPE_ON                (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_PIPE_AUTO              (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_SHIFT                  (6U)
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFF3F))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_ON                     (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_XTPLUS_CTRL_VDM_AUTO                   (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_XTPLUS_CTRL_TE3_SHIFT                  (4U)
+#define RGX_CR_CLK_XTPLUS_CTRL_TE3_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
+#define RGX_CR_CLK_XTPLUS_CTRL_TE3_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_TE3_ON                     (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_XTPLUS_CTRL_TE3_AUTO                   (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_XTPLUS_CTRL_VCE_SHIFT                  (2U)
+#define RGX_CR_CLK_XTPLUS_CTRL_VCE_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
+#define RGX_CR_CLK_XTPLUS_CTRL_VCE_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VCE_ON                     (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_XTPLUS_CTRL_VCE_AUTO                   (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_XTPLUS_CTRL_VBS_SHIFT                  (0U)
+#define RGX_CR_CLK_XTPLUS_CTRL_VBS_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+#define RGX_CR_CLK_XTPLUS_CTRL_VBS_OFF                    (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VBS_ON                     (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_XTPLUS_CTRL_VBS_AUTO                   (IMG_UINT64_C(0x0000000000000002))
+
+
+/*
+    Register RGX_CR_CLK_XTPLUS_STATUS
+*/
+#define RGX_CR_CLK_XTPLUS_STATUS                          (0x0088U)
+#define RGX_CR_CLK_XTPLUS_STATUS_MASKFULL                 (IMG_UINT64_C(0x00000000000000FF))
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_SHIFT               (7U)
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_GATED               (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_RUNNING             (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_XTPLUS_STATUS_UVB_SHIFT                (6U)
+#define RGX_CR_CLK_XTPLUS_STATUS_UVB_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
+#define RGX_CR_CLK_XTPLUS_STATUS_UVB_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_UVB_RUNNING              (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_XTPLUS_STATUS_GPP_SHIFT                (5U)
+#define RGX_CR_CLK_XTPLUS_STATUS_GPP_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_CLK_XTPLUS_STATUS_GPP_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_GPP_RUNNING              (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_PIPE_SHIFT           (4U)
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_PIPE_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_PIPE_GATED           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_PIPE_RUNNING         (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_SHIFT                (3U)
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_VDM_RUNNING              (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_XTPLUS_STATUS_TE3_SHIFT                (2U)
+#define RGX_CR_CLK_XTPLUS_STATUS_TE3_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_CLK_XTPLUS_STATUS_TE3_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_TE3_RUNNING              (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_XTPLUS_STATUS_VCE_SHIFT                (1U)
+#define RGX_CR_CLK_XTPLUS_STATUS_VCE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_CLK_XTPLUS_STATUS_VCE_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_VCE_RUNNING              (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_XTPLUS_STATUS_VBS_SHIFT                (0U)
+#define RGX_CR_CLK_XTPLUS_STATUS_VBS_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_CLK_XTPLUS_STATUS_VBS_GATED                (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_XTPLUS_STATUS_VBS_RUNNING              (IMG_UINT64_C(0x0000000000000001))
+
+
+/*
+    Register RGX_CR_SOFT_RESET
+*/
+#define RGX_CR_SOFT_RESET                                 (0x0100U)
+#define RGX_CR_SOFT_RESET_MASKFULL                        (IMG_UINT64_C(0xFFE7FFFFFFFFFC1D))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_SHIFT             (63U)
+#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_CLRMSK            (IMG_UINT64_C(0X7FFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_EN                (IMG_UINT64_C(0X8000000000000000))
+#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_SHIFT             (62U)
+#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_CLRMSK            (IMG_UINT64_C(0XBFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_EN                (IMG_UINT64_C(0X4000000000000000))
+#define RGX_CR_SOFT_RESET_BERNADO2_CORE_SHIFT             (61U)
+#define RGX_CR_SOFT_RESET_BERNADO2_CORE_CLRMSK            (IMG_UINT64_C(0XDFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_BERNADO2_CORE_EN                (IMG_UINT64_C(0X2000000000000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_SOFT_RESET_JONES_CORE_SHIFT                (60U)
+#define RGX_CR_SOFT_RESET_JONES_CORE_CLRMSK               (IMG_UINT64_C(0XEFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_JONES_CORE_EN                   (IMG_UINT64_C(0X1000000000000000))
+#define RGX_CR_SOFT_RESET_TILING_CORE_SHIFT               (59U)
+#define RGX_CR_SOFT_RESET_TILING_CORE_CLRMSK              (IMG_UINT64_C(0XF7FFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_TILING_CORE_EN                  (IMG_UINT64_C(0X0800000000000000))
+#define RGX_CR_SOFT_RESET_TE3_SHIFT                       (58U)
+#define RGX_CR_SOFT_RESET_TE3_CLRMSK                      (IMG_UINT64_C(0XFBFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_TE3_EN                          (IMG_UINT64_C(0X0400000000000000))
+#define RGX_CR_SOFT_RESET_VCE_SHIFT                       (57U)
+#define RGX_CR_SOFT_RESET_VCE_CLRMSK                      (IMG_UINT64_C(0XFDFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_VCE_EN                          (IMG_UINT64_C(0X0200000000000000))
+#define RGX_CR_SOFT_RESET_VBS_SHIFT                       (56U)
+#define RGX_CR_SOFT_RESET_VBS_CLRMSK                      (IMG_UINT64_C(0XFEFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_VBS_EN                          (IMG_UINT64_C(0X0100000000000000))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_SOFT_RESET_DPX1_CORE_SHIFT                 (55U)
+#define RGX_CR_SOFT_RESET_DPX1_CORE_CLRMSK                (IMG_UINT64_C(0XFF7FFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DPX1_CORE_EN                    (IMG_UINT64_C(0X0080000000000000))
+#define RGX_CR_SOFT_RESET_DPX0_CORE_SHIFT                 (54U)
+#define RGX_CR_SOFT_RESET_DPX0_CORE_CLRMSK                (IMG_UINT64_C(0XFFBFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DPX0_CORE_EN                    (IMG_UINT64_C(0X0040000000000000))
+#define RGX_CR_SOFT_RESET_FBA_SHIFT                       (53U)
+#define RGX_CR_SOFT_RESET_FBA_CLRMSK                      (IMG_UINT64_C(0XFFDFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_FBA_EN                          (IMG_UINT64_C(0X0020000000000000))
+#define RGX_CR_SOFT_RESET_SH_SHIFT                        (50U)
+#define RGX_CR_SOFT_RESET_SH_CLRMSK                       (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_SH_EN                           (IMG_UINT64_C(0X0004000000000000))
+#define RGX_CR_SOFT_RESET_VRDM_SHIFT                      (49U)
+#define RGX_CR_SOFT_RESET_VRDM_CLRMSK                     (IMG_UINT64_C(0XFFFDFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_VRDM_EN                         (IMG_UINT64_C(0X0002000000000000))
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_SOFT_RESET_MCU_FBTC_SHIFT                  (48U)
+#define RGX_CR_SOFT_RESET_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFEFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_MCU_FBTC_EN                     (IMG_UINT64_C(0X0001000000000000))
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_SHIFT             (47U)
+#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_CLRMSK            (IMG_UINT64_C(0XFFFF7FFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_EN                (IMG_UINT64_C(0X0000800000000000))
+#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_SHIFT             (46U)
+#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFBFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_EN                (IMG_UINT64_C(0X0000400000000000))
+#define RGX_CR_SOFT_RESET_BERNADO1_CORE_SHIFT             (45U)
+#define RGX_CR_SOFT_RESET_BERNADO1_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFDFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_BERNADO1_CORE_EN                (IMG_UINT64_C(0X0000200000000000))
+#define RGX_CR_SOFT_RESET_BERNADO0_CORE_SHIFT             (44U)
+#define RGX_CR_SOFT_RESET_BERNADO0_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFEFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_BERNADO0_CORE_EN                (IMG_UINT64_C(0X0000100000000000))
+#define RGX_CR_SOFT_RESET_IPP_SHIFT                       (43U)
+#define RGX_CR_SOFT_RESET_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFF7FFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_IPP_EN                          (IMG_UINT64_C(0X0000080000000000))
+#define RGX_CR_SOFT_RESET_BIF_TEXAS_SHIFT                 (42U)
+#define RGX_CR_SOFT_RESET_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFBFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_BIF_TEXAS_EN                    (IMG_UINT64_C(0X0000040000000000))
+#define RGX_CR_SOFT_RESET_TORNADO_CORE_SHIFT              (41U)
+#define RGX_CR_SOFT_RESET_TORNADO_CORE_CLRMSK             (IMG_UINT64_C(0XFFFFFDFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_TORNADO_CORE_EN                 (IMG_UINT64_C(0X0000020000000000))
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_SOFT_RESET_DUST_H_CORE_SHIFT               (40U)
+#define RGX_CR_SOFT_RESET_DUST_H_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFEFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_H_CORE_EN                  (IMG_UINT64_C(0X0000010000000000))
+#define RGX_CR_SOFT_RESET_DUST_G_CORE_SHIFT               (39U)
+#define RGX_CR_SOFT_RESET_DUST_G_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFF7FFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_G_CORE_EN                  (IMG_UINT64_C(0X0000008000000000))
+#define RGX_CR_SOFT_RESET_DUST_F_CORE_SHIFT               (38U)
+#define RGX_CR_SOFT_RESET_DUST_F_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFBFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_F_CORE_EN                  (IMG_UINT64_C(0X0000004000000000))
+#define RGX_CR_SOFT_RESET_DUST_E_CORE_SHIFT               (37U)
+#define RGX_CR_SOFT_RESET_DUST_E_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFDFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_E_CORE_EN                  (IMG_UINT64_C(0X0000002000000000))
+#define RGX_CR_SOFT_RESET_DUST_D_CORE_SHIFT               (36U)
+#define RGX_CR_SOFT_RESET_DUST_D_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFEFFFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_D_CORE_EN                  (IMG_UINT64_C(0X0000001000000000))
+#define RGX_CR_SOFT_RESET_DUST_C_CORE_SHIFT               (35U)
+#define RGX_CR_SOFT_RESET_DUST_C_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFF7FFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_C_CORE_EN                  (IMG_UINT64_C(0X0000000800000000))
+#define RGX_CR_SOFT_RESET_MMU_SHIFT                       (34U)
+#define RGX_CR_SOFT_RESET_MMU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFBFFFFFFFF))
+#define RGX_CR_SOFT_RESET_MMU_EN                          (IMG_UINT64_C(0X0000000400000000))
+#define RGX_CR_SOFT_RESET_BIF1_SHIFT                      (33U)
+#define RGX_CR_SOFT_RESET_BIF1_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFDFFFFFFFF))
+#define RGX_CR_SOFT_RESET_BIF1_EN                         (IMG_UINT64_C(0X0000000200000000))
+#define RGX_CR_SOFT_RESET_GARTEN_SHIFT                    (32U)
+#define RGX_CR_SOFT_RESET_GARTEN_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_SOFT_RESET_GARTEN_EN                       (IMG_UINT64_C(0X0000000100000000))
+#define RGX_CR_SOFT_RESET_RASCAL_CORE_SHIFT               (31U)
+#define RGX_CR_SOFT_RESET_RASCAL_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
+#define RGX_CR_SOFT_RESET_RASCAL_CORE_EN                  (IMG_UINT64_C(0X0000000080000000))
+#define RGX_CR_SOFT_RESET_DUST_B_CORE_SHIFT               (30U)
+#define RGX_CR_SOFT_RESET_DUST_B_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_B_CORE_EN                  (IMG_UINT64_C(0X0000000040000000))
+#define RGX_CR_SOFT_RESET_DUST_A_CORE_SHIFT               (29U)
+#define RGX_CR_SOFT_RESET_DUST_A_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
+#define RGX_CR_SOFT_RESET_DUST_A_CORE_EN                  (IMG_UINT64_C(0X0000000020000000))
+#define RGX_CR_SOFT_RESET_FB_TLCACHE_SHIFT                (28U)
+#define RGX_CR_SOFT_RESET_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
+#define RGX_CR_SOFT_RESET_FB_TLCACHE_EN                   (IMG_UINT64_C(0X0000000010000000))
+#define RGX_CR_SOFT_RESET_SLC_SHIFT                       (27U)
+#define RGX_CR_SOFT_RESET_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
+#define RGX_CR_SOFT_RESET_SLC_EN                          (IMG_UINT64_C(0X0000000008000000))
+#define RGX_CR_SOFT_RESET_TLA_SHIFT                       (26U)
+#define RGX_CR_SOFT_RESET_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
+#define RGX_CR_SOFT_RESET_TLA_EN                          (IMG_UINT64_C(0X0000000004000000))
+#define RGX_CR_SOFT_RESET_UVS_SHIFT                       (25U)
+#define RGX_CR_SOFT_RESET_UVS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
+#define RGX_CR_SOFT_RESET_UVS_EN                          (IMG_UINT64_C(0X0000000002000000))
+#define RGX_CR_SOFT_RESET_TE_SHIFT                        (24U)
+#define RGX_CR_SOFT_RESET_TE_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
+#define RGX_CR_SOFT_RESET_TE_EN                           (IMG_UINT64_C(0X0000000001000000))
+#define RGX_CR_SOFT_RESET_GPP_SHIFT                       (23U)
+#define RGX_CR_SOFT_RESET_GPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
+#define RGX_CR_SOFT_RESET_GPP_EN                          (IMG_UINT64_C(0X0000000000800000))
+#define RGX_CR_SOFT_RESET_FBDC_SHIFT                      (22U)
+#define RGX_CR_SOFT_RESET_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
+#define RGX_CR_SOFT_RESET_FBDC_EN                         (IMG_UINT64_C(0X0000000000400000))
+#define RGX_CR_SOFT_RESET_FBC_SHIFT                       (21U)
+#define RGX_CR_SOFT_RESET_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
+#define RGX_CR_SOFT_RESET_FBC_EN                          (IMG_UINT64_C(0X0000000000200000))
+#define RGX_CR_SOFT_RESET_PM_SHIFT                        (20U)
+#define RGX_CR_SOFT_RESET_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
+#define RGX_CR_SOFT_RESET_PM_EN                           (IMG_UINT64_C(0X0000000000100000))
+#define RGX_CR_SOFT_RESET_PBE_SHIFT                       (19U)
+#define RGX_CR_SOFT_RESET_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFF7FFFF))
+#define RGX_CR_SOFT_RESET_PBE_EN                          (IMG_UINT64_C(0X0000000000080000))
+#define RGX_CR_SOFT_RESET_USC_SHARED_SHIFT                (18U)
+#define RGX_CR_SOFT_RESET_USC_SHARED_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFBFFFF))
+#define RGX_CR_SOFT_RESET_USC_SHARED_EN                   (IMG_UINT64_C(0X0000000000040000))
+#define RGX_CR_SOFT_RESET_MCU_L1_SHIFT                    (17U)
+#define RGX_CR_SOFT_RESET_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFDFFFF))
+#define RGX_CR_SOFT_RESET_MCU_L1_EN                       (IMG_UINT64_C(0X0000000000020000))
+#define RGX_CR_SOFT_RESET_BIF_SHIFT                       (16U)
+#define RGX_CR_SOFT_RESET_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFEFFFF))
+#define RGX_CR_SOFT_RESET_BIF_EN                          (IMG_UINT64_C(0X0000000000010000))
+#define RGX_CR_SOFT_RESET_CDM_SHIFT                       (15U)
+#define RGX_CR_SOFT_RESET_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFF7FFF))
+#define RGX_CR_SOFT_RESET_CDM_EN                          (IMG_UINT64_C(0X0000000000008000))
+#define RGX_CR_SOFT_RESET_VDM_SHIFT                       (14U)
+#define RGX_CR_SOFT_RESET_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
+#define RGX_CR_SOFT_RESET_VDM_EN                          (IMG_UINT64_C(0X0000000000004000))
+#if defined(RGX_FEATURE_TESSELLATION)
+#define RGX_CR_SOFT_RESET_TESS_SHIFT                      (13U)
+#define RGX_CR_SOFT_RESET_TESS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
+#define RGX_CR_SOFT_RESET_TESS_EN                         (IMG_UINT64_C(0X0000000000002000))
+#endif /* RGX_FEATURE_TESSELLATION */
+
+#define RGX_CR_SOFT_RESET_PDS_SHIFT                       (12U)
+#define RGX_CR_SOFT_RESET_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
+#define RGX_CR_SOFT_RESET_PDS_EN                          (IMG_UINT64_C(0X0000000000001000))
+#define RGX_CR_SOFT_RESET_ISP_SHIFT                       (11U)
+#define RGX_CR_SOFT_RESET_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFF7FF))
+#define RGX_CR_SOFT_RESET_ISP_EN                          (IMG_UINT64_C(0X0000000000000800))
+#define RGX_CR_SOFT_RESET_TSP_SHIFT                       (10U)
+#define RGX_CR_SOFT_RESET_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
+#define RGX_CR_SOFT_RESET_TSP_EN                          (IMG_UINT64_C(0X0000000000000400))
+#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_SHIFT             (4U)
+#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_EN                (IMG_UINT64_C(0X0000000000000010))
+#define RGX_CR_SOFT_RESET_MCU_L0_SHIFT                    (3U)
+#define RGX_CR_SOFT_RESET_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_SOFT_RESET_MCU_L0_EN                       (IMG_UINT64_C(0X0000000000000008))
+#define RGX_CR_SOFT_RESET_TPU_SHIFT                       (2U)
+#define RGX_CR_SOFT_RESET_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_SOFT_RESET_TPU_EN                          (IMG_UINT64_C(0X0000000000000004))
+#define RGX_CR_SOFT_RESET_USC_SHIFT                       (0U)
+#define RGX_CR_SOFT_RESET_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_SOFT_RESET_USC_EN                          (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_SOFT_RESET2
+*/
+#define RGX_CR_SOFT_RESET2                                (0x0108U)
+#define RGX_CR_SOFT_RESET2_MASKFULL                       (IMG_UINT64_C(0x00000000000007FF))
+#define RGX_CR_SOFT_RESET2_ASTC_SHIFT                     (10U)
+#define RGX_CR_SOFT_RESET2_ASTC_CLRMSK                    (0XFFFFFBFFU)
+#define RGX_CR_SOFT_RESET2_ASTC_EN                        (0X00000400U)
+#define RGX_CR_SOFT_RESET2_BLACKPEARL_SHIFT               (9U)
+#define RGX_CR_SOFT_RESET2_BLACKPEARL_CLRMSK              (0XFFFFFDFFU)
+#define RGX_CR_SOFT_RESET2_BLACKPEARL_EN                  (0X00000200U)
+#define RGX_CR_SOFT_RESET2_USCPS_SHIFT                    (8U)
+#define RGX_CR_SOFT_RESET2_USCPS_CLRMSK                   (0XFFFFFEFFU)
+#define RGX_CR_SOFT_RESET2_USCPS_EN                       (0X00000100U)
+#define RGX_CR_SOFT_RESET2_IPF_SHIFT                      (7U)
+#define RGX_CR_SOFT_RESET2_IPF_CLRMSK                     (0XFFFFFF7FU)
+#define RGX_CR_SOFT_RESET2_IPF_EN                         (0X00000080U)
+#define RGX_CR_SOFT_RESET2_GEOMETRY_SHIFT                 (6U)
+#define RGX_CR_SOFT_RESET2_GEOMETRY_CLRMSK                (0XFFFFFFBFU)
+#define RGX_CR_SOFT_RESET2_GEOMETRY_EN                    (0X00000040U)
+#define RGX_CR_SOFT_RESET2_USC_SHARED_SHIFT               (5U)
+#define RGX_CR_SOFT_RESET2_USC_SHARED_CLRMSK              (0XFFFFFFDFU)
+#define RGX_CR_SOFT_RESET2_USC_SHARED_EN                  (0X00000020U)
+#define RGX_CR_SOFT_RESET2_PDS_SHARED_SHIFT               (4U)
+#define RGX_CR_SOFT_RESET2_PDS_SHARED_CLRMSK              (0XFFFFFFEFU)
+#define RGX_CR_SOFT_RESET2_PDS_SHARED_EN                  (0X00000010U)
+#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_SHIFT           (3U)
+#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_CLRMSK          (0XFFFFFFF7U)
+#define RGX_CR_SOFT_RESET2_BIF_BLACKPEARL_EN              (0X00000008U)
+#define RGX_CR_SOFT_RESET2_PIXEL_SHIFT                    (2U)
+#define RGX_CR_SOFT_RESET2_PIXEL_CLRMSK                   (0XFFFFFFFBU)
+#define RGX_CR_SOFT_RESET2_PIXEL_EN                       (0X00000004U)
+#define RGX_CR_SOFT_RESET2_COMPUTE_SHIFT                  (1U)
+#define RGX_CR_SOFT_RESET2_COMPUTE_CLRMSK                 (0XFFFFFFFDU)
+#define RGX_CR_SOFT_RESET2_COMPUTE_EN                     (0X00000002U)
+#define RGX_CR_SOFT_RESET2_VERTEX_SHIFT                   (0U)
+#define RGX_CR_SOFT_RESET2_VERTEX_CLRMSK                  (0XFFFFFFFEU)
+#define RGX_CR_SOFT_RESET2_VERTEX_EN                      (0X00000001U)
+
+
+/*
+    Register RGX_CR_EVENT_STATUS
+*/
+#define RGX_CR_EVENT_STATUS                               (0x0130U)
+#define RGX_CR_EVENT_STATUS_MASKFULL                      (IMG_UINT64_C(0x000000001FFEFFFF))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_SHIFT       (28U)
+#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_CLRMSK      (0XEFFFFFFFU)
+#define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_EN          (0X10000000U)
+#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_SHIFT      (27U)
+#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_CLRMSK     (0XF7FFFFFFU)
+#define RGX_CR_EVENT_STATUS_DPX_MMU_PAGE_FAULT_EN         (0X08000000U)
+#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_SHIFT       (26U)
+#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_CLRMSK      (0XFBFFFFFFU)
+#define RGX_CR_EVENT_STATUS_RPM_OUT_OF_MEMORY_EN          (0X04000000U)
+#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_SHIFT        (25U)
+#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_CLRMSK       (0XFDFFFFFFU)
+#define RGX_CR_EVENT_STATUS_FBA_FC3_FINISHED_EN           (0X02000000U)
+#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_SHIFT        (24U)
+#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_CLRMSK       (0XFEFFFFFFU)
+#define RGX_CR_EVENT_STATUS_FBA_FC2_FINISHED_EN           (0X01000000U)
+#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_SHIFT        (23U)
+#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_CLRMSK       (0XFF7FFFFFU)
+#define RGX_CR_EVENT_STATUS_FBA_FC1_FINISHED_EN           (0X00800000U)
+#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_SHIFT        (22U)
+#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_CLRMSK       (0XFFBFFFFFU)
+#define RGX_CR_EVENT_STATUS_FBA_FC0_FINISHED_EN           (0X00400000U)
+#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_SHIFT        (21U)
+#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_CLRMSK       (0XFFDFFFFFU)
+#define RGX_CR_EVENT_STATUS_RDM_FC3_FINISHED_EN           (0X00200000U)
+#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_SHIFT        (20U)
+#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_CLRMSK       (0XFFEFFFFFU)
+#define RGX_CR_EVENT_STATUS_RDM_FC2_FINISHED_EN           (0X00100000U)
+#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_SHIFT        (19U)
+#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_CLRMSK       (0XFFF7FFFFU)
+#define RGX_CR_EVENT_STATUS_RDM_FC1_FINISHED_EN           (0X00080000U)
+#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_SHIFT        (18U)
+#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_CLRMSK       (0XFFFBFFFFU)
+#define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_EN           (0X00040000U)
+#define RGX_CR_EVENT_STATUS_SHG_FINISHED_SHIFT            (17U)
+#define RGX_CR_EVENT_STATUS_SHG_FINISHED_CLRMSK           (0XFFFDFFFFU)
+#define RGX_CR_EVENT_STATUS_SHG_FINISHED_EN               (0X00020000U)
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_EVENT_STATUS_USC_TRIGGER_SHIFT             (15U)
+#define RGX_CR_EVENT_STATUS_USC_TRIGGER_CLRMSK            (0XFFFF7FFFU)
+#define RGX_CR_EVENT_STATUS_USC_TRIGGER_EN                (0X00008000U)
+#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_SHIFT            (14U)
+#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_CLRMSK           (0XFFFFBFFFU)
+#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_EN               (0X00004000U)
+#define RGX_CR_EVENT_STATUS_GPIO_ACK_SHIFT                (13U)
+#define RGX_CR_EVENT_STATUS_GPIO_ACK_CLRMSK               (0XFFFFDFFFU)
+#define RGX_CR_EVENT_STATUS_GPIO_ACK_EN                   (0X00002000U)
+#define RGX_CR_EVENT_STATUS_GPIO_REQ_SHIFT                (12U)
+#define RGX_CR_EVENT_STATUS_GPIO_REQ_CLRMSK               (0XFFFFEFFFU)
+#define RGX_CR_EVENT_STATUS_GPIO_REQ_EN                   (0X00001000U)
+#define RGX_CR_EVENT_STATUS_POWER_ABORT_SHIFT             (11U)
+#define RGX_CR_EVENT_STATUS_POWER_ABORT_CLRMSK            (0XFFFFF7FFU)
+#define RGX_CR_EVENT_STATUS_POWER_ABORT_EN                (0X00000800U)
+#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_SHIFT          (10U)
+#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_CLRMSK         (0XFFFFFBFFU)
+#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_EN             (0X00000400U)
+#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_SHIFT          (9U)
+#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_CLRMSK         (0XFFFFFDFFU)
+#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_EN             (0X00000200U)
+#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_SHIFT          (8U)
+#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_CLRMSK         (0XFFFFFEFFU)
+#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_EN             (0X00000100U)
+#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_SHIFT        (7U)
+#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_CLRMSK       (0XFFFFFF7FU)
+#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_EN           (0X00000080U)
+#define RGX_CR_EVENT_STATUS_TA_TERMINATE_SHIFT            (6U)
+#define RGX_CR_EVENT_STATUS_TA_TERMINATE_CLRMSK           (0XFFFFFFBFU)
+#define RGX_CR_EVENT_STATUS_TA_TERMINATE_EN               (0X00000040U)
+#define RGX_CR_EVENT_STATUS_TA_FINISHED_SHIFT             (5U)
+#define RGX_CR_EVENT_STATUS_TA_FINISHED_CLRMSK            (0XFFFFFFDFU)
+#define RGX_CR_EVENT_STATUS_TA_FINISHED_EN                (0X00000020U)
+#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_SHIFT       (4U)
+#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_CLRMSK      (0XFFFFFFEFU)
+#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_EN          (0X00000010U)
+#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT      (3U)
+#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_CLRMSK     (0XFFFFFFF7U)
+#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_EN         (0X00000008U)
+#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_SHIFT        (2U)
+#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_CLRMSK       (0XFFFFFFFBU)
+#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_EN           (0X00000004U)
+#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_SHIFT         (1U)
+#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_CLRMSK        (0XFFFFFFFDU)
+#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_EN            (0X00000002U)
+#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_SHIFT            (0U)
+#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_CLRMSK           (0XFFFFFFFEU)
+#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_EN               (0X00000001U)
+
+
+/*
+    Register RGX_CR_TIMER
+*/
+#define RGX_CR_TIMER                                      (0x0160U)
+#define RGX_CR_TIMER_MASKFULL                             (IMG_UINT64_C(0x8000FFFFFFFFFFFF))
+#define RGX_CR_TIMER_BIT31_SHIFT                          (63U)
+#define RGX_CR_TIMER_BIT31_CLRMSK                         (IMG_UINT64_C(0X7FFFFFFFFFFFFFFF))
+#define RGX_CR_TIMER_BIT31_EN                             (IMG_UINT64_C(0X8000000000000000))
+#define RGX_CR_TIMER_VALUE_SHIFT                          (0U)
+#define RGX_CR_TIMER_VALUE_CLRMSK                         (IMG_UINT64_C(0XFFFF000000000000))
+
+
+/*
+    Register RGX_CR_TLA_STATUS
+*/
+#define RGX_CR_TLA_STATUS                                 (0x0178U)
+#define RGX_CR_TLA_STATUS_MASKFULL                        (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_TLA_STATUS_BLIT_COUNT_SHIFT                (39U)
+#define RGX_CR_TLA_STATUS_BLIT_COUNT_CLRMSK               (IMG_UINT64_C(0X0000007FFFFFFFFF))
+#define RGX_CR_TLA_STATUS_REQUEST_SHIFT                   (7U)
+#define RGX_CR_TLA_STATUS_REQUEST_CLRMSK                  (IMG_UINT64_C(0XFFFFFF800000007F))
+#define RGX_CR_TLA_STATUS_FIFO_FULLNESS_SHIFT             (1U)
+#define RGX_CR_TLA_STATUS_FIFO_FULLNESS_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFF81))
+#define RGX_CR_TLA_STATUS_BUSY_SHIFT                      (0U)
+#define RGX_CR_TLA_STATUS_BUSY_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_TLA_STATUS_BUSY_EN                         (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_PM_PARTIAL_RENDER_ENABLE
+*/
+#define RGX_CR_PM_PARTIAL_RENDER_ENABLE                   (0x0338U)
+#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_MASKFULL          (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_SHIFT          (0U)
+#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_CLRMSK         (0XFFFFFFFEU)
+#define RGX_CR_PM_PARTIAL_RENDER_ENABLE_OP_EN             (0X00000001U)
+
+
+/*
+    Register RGX_CR_SIDEKICK_IDLE
+*/
+#define RGX_CR_SIDEKICK_IDLE                              (0x03C8U)
+#define RGX_CR_SIDEKICK_IDLE_MASKFULL                     (IMG_UINT64_C(0x000000000000007F))
+#define RGX_CR_SIDEKICK_IDLE_FB_CDC_SHIFT                 (6U)
+#define RGX_CR_SIDEKICK_IDLE_FB_CDC_CLRMSK                (0XFFFFFFBFU)
+#define RGX_CR_SIDEKICK_IDLE_FB_CDC_EN                    (0X00000040U)
+#define RGX_CR_SIDEKICK_IDLE_MMU_SHIFT                    (5U)
+#define RGX_CR_SIDEKICK_IDLE_MMU_CLRMSK                   (0XFFFFFFDFU)
+#define RGX_CR_SIDEKICK_IDLE_MMU_EN                       (0X00000020U)
+#define RGX_CR_SIDEKICK_IDLE_BIF128_SHIFT                 (4U)
+#define RGX_CR_SIDEKICK_IDLE_BIF128_CLRMSK                (0XFFFFFFEFU)
+#define RGX_CR_SIDEKICK_IDLE_BIF128_EN                    (0X00000010U)
+#define RGX_CR_SIDEKICK_IDLE_TLA_SHIFT                    (3U)
+#define RGX_CR_SIDEKICK_IDLE_TLA_CLRMSK                   (0XFFFFFFF7U)
+#define RGX_CR_SIDEKICK_IDLE_TLA_EN                       (0X00000008U)
+#define RGX_CR_SIDEKICK_IDLE_GARTEN_SHIFT                 (2U)
+#define RGX_CR_SIDEKICK_IDLE_GARTEN_CLRMSK                (0XFFFFFFFBU)
+#define RGX_CR_SIDEKICK_IDLE_GARTEN_EN                    (0X00000004U)
+#define RGX_CR_SIDEKICK_IDLE_HOSTIF_SHIFT                 (1U)
+#define RGX_CR_SIDEKICK_IDLE_HOSTIF_CLRMSK                (0XFFFFFFFDU)
+#define RGX_CR_SIDEKICK_IDLE_HOSTIF_EN                    (0X00000002U)
+#define RGX_CR_SIDEKICK_IDLE_SOCIF_SHIFT                  (0U)
+#define RGX_CR_SIDEKICK_IDLE_SOCIF_CLRMSK                 (0XFFFFFFFEU)
+#define RGX_CR_SIDEKICK_IDLE_SOCIF_EN                     (0X00000001U)
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_STORE_STATUS
+*/
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS                   (0x0430U)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_MASKFULL          (IMG_UINT64_C(0x00000000000000F3))
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_LAST_PIPE_SHIFT   (4U)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_LAST_PIPE_CLRMSK  (0XFFFFFF0FU)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_SHIFT (1U)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_CLRMSK (0XFFFFFFFDU)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_NEED_RESUME_EN    (0X00000002U)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_SHIFT    (0U)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_CLRMSK   (0XFFFFFFFEU)
+#define RGX_CR_VDM_CONTEXT_STORE_STATUS_COMPLETE_EN       (0X00000001U)
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_STORE_TASK0
+*/
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0                    (0x0438U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0_MASKFULL           (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE1_SHIFT   (32U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE1_CLRMSK  (IMG_UINT64_C(0X00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE0_SHIFT   (0U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK0_PDS_STATE0_CLRMSK  (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_STORE_TASK1
+*/
+#define RGX_CR_VDM_CONTEXT_STORE_TASK1                    (0x0440U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK1_MASKFULL           (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_STORE_TASK1_PDS_STATE2_SHIFT   (0U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK1_PDS_STATE2_CLRMSK  (00000000U)
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_STORE_TASK2
+*/
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2                    (0x0448U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2_MASKFULL           (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT2_SHIFT  (32U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT2_CLRMSK (IMG_UINT64_C(0X00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT1_SHIFT  (0U)
+#define RGX_CR_VDM_CONTEXT_STORE_TASK2_STREAM_OUT1_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_RESUME_TASK0
+*/
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0                   (0x0450U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_MASKFULL          (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE1_SHIFT  (32U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE1_CLRMSK (IMG_UINT64_C(0X00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE0_SHIFT  (0U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK0_PDS_STATE0_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_RESUME_TASK1
+*/
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK1                   (0x0458U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_MASKFULL          (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_PDS_STATE2_SHIFT  (0U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK1_PDS_STATE2_CLRMSK (00000000U)
+
+
+/*
+    Register RGX_CR_VDM_CONTEXT_RESUME_TASK2
+*/
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2                   (0x0460U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_MASKFULL          (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT2_SHIFT (32U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT2_CLRMSK (IMG_UINT64_C(0X00000000FFFFFFFF))
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT1_SHIFT (0U)
+#define RGX_CR_VDM_CONTEXT_RESUME_TASK2_STREAM_OUT1_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
+    Register RGX_CR_CDM_CONTEXT_STORE_STATUS
+*/
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS                   (0x04A0U)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_MASKFULL          (IMG_UINT64_C(0x0000000000000003))
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_SHIFT (1U)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_CLRMSK (0XFFFFFFFDU)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_NEED_RESUME_EN    (0X00000002U)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_SHIFT    (0U)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_CLRMSK   (0XFFFFFFFEU)
+#define RGX_CR_CDM_CONTEXT_STORE_STATUS_COMPLETE_EN       (0X00000001U)
+
+
+/*
+    Register RGX_CR_CDM_CONTEXT_PDS0
+*/
+#define RGX_CR_CDM_CONTEXT_PDS0                           (0x04A8U)
+#define RGX_CR_CDM_CONTEXT_PDS0_MASKFULL                  (IMG_UINT64_C(0xFFFFFFF0FFFFFFF0))
+#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_SHIFT           (36U)
+#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_CLRMSK          (IMG_UINT64_C(0X0000000FFFFFFFFF))
+#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_ALIGNSHIFT      (4U)
+#define RGX_CR_CDM_CONTEXT_PDS0_DATA_ADDR_ALIGNSIZE       (16U)
+#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_SHIFT           (4U)
+#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_CLRMSK          (IMG_UINT64_C(0XFFFFFFFF0000000F))
+#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_ALIGNSHIFT      (4U)
+#define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_ALIGNSIZE       (16U)
+
+
+#if defined(RGX_FEATURE_PDS_TEMPSIZE8)
+/*
+    Register RGX_CR_CDM_CONTEXT_PDS1
+*/
+#define RGX_CR_CDM_CONTEXT_PDS1                           (0x04B0U)
+#define RGX_CR_CDM_CONTEXT_PDS1_MASKFULL                  (IMG_UINT64_C(0x000000007FFFFFFF))
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_SHIFT         (30U)
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_CLRMSK        (0XBFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_EN            (0X40000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_SHIFT         (29U)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_CLRMSK        (0XDFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_EN            (0X20000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_SHIFT              (28U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_CLRMSK             (0XEFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_EN                 (0X10000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_SHIFT        (22U)
+#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_CLRMSK       (0XF03FFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_SHIFT       (21U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_CLRMSK      (0XFFDFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_EN          (0X00200000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_SHIFT         (12U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_CLRMSK        (0XFFE00FFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_SHIFT           (7U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_CLRMSK          (0XFFFFF07FU)
+#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_SHIFT           (1U)
+#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_CLRMSK          (0XFFFFFF81U)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_SHIFT               (0U)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_CLRMSK              (0XFFFFFFFEU)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_EN                  (0X00000001U)
+#endif /* RGX_FEATURE_PDS_TEMPSIZE8 */ 
+
+
+#if !defined(RGX_FEATURE_PDS_TEMPSIZE8)
+/*
+    Register RGX_CR_CDM_CONTEXT_PDS1
+*/
+#define RGX_CR_CDM_CONTEXT_PDS1                           (0x04B0U)
+#define RGX_CR_CDM_CONTEXT_PDS1_MASKFULL                  (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_SHIFT         (29U)
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_CLRMSK        (0XDFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_EN            (0X20000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_SHIFT         (28U)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_CLRMSK        (0XEFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_EN            (0X10000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_SHIFT              (27U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_CLRMSK             (0XF7FFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_EN                 (0X08000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_SHIFT        (21U)
+#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_CLRMSK       (0XF81FFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_SHIFT       (20U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_CLRMSK      (0XFFEFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_EN          (0X00100000U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_SHIFT         (11U)
+#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_CLRMSK        (0XFFF007FFU)
+#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_SHIFT           (7U)
+#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_CLRMSK          (0XFFFFF87FU)
+#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_SHIFT           (1U)
+#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_CLRMSK          (0XFFFFFF81U)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_SHIFT               (0U)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_CLRMSK              (0XFFFFFFFEU)
+#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_EN                  (0X00000001U)
+#endif /* !defined(RGX_FEATURE_PDS_TEMPSIZE8) */
+
+
+/*
+    Register RGX_CR_CDM_TERMINATE_PDS
+*/
+#define RGX_CR_CDM_TERMINATE_PDS                          (0x04B8U)
+#define RGX_CR_CDM_TERMINATE_PDS_MASKFULL                 (IMG_UINT64_C(0xFFFFFFF0FFFFFFF0))
+#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_SHIFT          (36U)
+#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_CLRMSK         (IMG_UINT64_C(0X0000000FFFFFFFFF))
+#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_ALIGNSHIFT     (4U)
+#define RGX_CR_CDM_TERMINATE_PDS_DATA_ADDR_ALIGNSIZE      (16U)
+#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_SHIFT          (4U)
+#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_CLRMSK         (IMG_UINT64_C(0XFFFFFFFF0000000F))
+#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_ALIGNSHIFT     (4U)
+#define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_ALIGNSIZE      (16U)
+
+
+#if defined(RGX_FEATURE_PDS_TEMPSIZE8)
+/*
+    Register RGX_CR_CDM_TERMINATE_PDS1
+*/
+#define RGX_CR_CDM_TERMINATE_PDS1                         (0x04C0U)
+#define RGX_CR_CDM_TERMINATE_PDS1_MASKFULL                (IMG_UINT64_C(0x000000007FFFFFFF))
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_SHIFT       (30U)
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_CLRMSK      (0XBFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_EN          (0X40000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_SHIFT       (29U)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_CLRMSK      (0XDFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_EN          (0X20000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_SHIFT            (28U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_CLRMSK           (0XEFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_EN               (0X10000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_SHIFT      (22U)
+#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_CLRMSK     (0XF03FFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_SHIFT     (21U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_CLRMSK    (0XFFDFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_EN        (0X00200000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_SHIFT       (12U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_CLRMSK      (0XFFE00FFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_SHIFT         (7U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_CLRMSK        (0XFFFFF07FU)
+#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_SHIFT         (1U)
+#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_CLRMSK        (0XFFFFFF81U)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_SHIFT             (0U)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_CLRMSK            (0XFFFFFFFEU)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_EN                (0X00000001U)
+#endif /* RGX_FEATURE_PDS_TEMPSIZE8 */ 
+
+
+#if !defined(RGX_FEATURE_PDS_TEMPSIZE8)
+/*
+    Register RGX_CR_CDM_TERMINATE_PDS1
+*/
+#define RGX_CR_CDM_TERMINATE_PDS1                         (0x04C0U)
+#define RGX_CR_CDM_TERMINATE_PDS1_MASKFULL                (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_SHIFT       (29U)
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_CLRMSK      (0XDFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_EN          (0X20000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_SHIFT       (28U)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_CLRMSK      (0XEFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_EN          (0X10000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_SHIFT            (27U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_CLRMSK           (0XF7FFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_EN               (0X08000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_SHIFT      (21U)
+#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_CLRMSK     (0XF81FFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_SHIFT     (20U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_CLRMSK    (0XFFEFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_EN        (0X00100000U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_SHIFT       (11U)
+#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_CLRMSK      (0XFFF007FFU)
+#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_SHIFT         (7U)
+#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_CLRMSK        (0XFFFFF87FU)
+#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_SHIFT         (1U)
+#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_CLRMSK        (0XFFFFFF81U)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_SHIFT             (0U)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_CLRMSK            (0XFFFFFFFEU)
+#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_EN                (0X00000001U)
+#endif /* !defined(RGX_FEATURE_PDS_TEMPSIZE8) */
+
+
+/*
+    Register RGX_CR_META_SP_MSLVDATAX
+*/
+#define RGX_CR_META_SP_MSLVDATAX                          (0x0A00U)
+#define RGX_CR_META_SP_MSLVDATAX_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_META_SP_MSLVDATAX_MSLVDATAX_SHIFT          (0U)
+#define RGX_CR_META_SP_MSLVDATAX_MSLVDATAX_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVDATAT
+*/
+#define RGX_CR_META_SP_MSLVDATAT                          (0x0A08U)
+#define RGX_CR_META_SP_MSLVDATAT_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_META_SP_MSLVDATAT_MSLVDATAT_SHIFT          (0U)
+#define RGX_CR_META_SP_MSLVDATAT_MSLVDATAT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVCTRL0
+*/
+#define RGX_CR_META_SP_MSLVCTRL0                          (0x0A10U)
+#define RGX_CR_META_SP_MSLVCTRL0_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_META_SP_MSLVCTRL0_ADDR_SHIFT               (2U)
+#define RGX_CR_META_SP_MSLVCTRL0_ADDR_CLRMSK              (0X00000003U)
+#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_SHIFT           (1U)
+#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_CLRMSK          (0XFFFFFFFDU)
+#define RGX_CR_META_SP_MSLVCTRL0_AUTOINCR_EN              (0X00000002U)
+#define RGX_CR_META_SP_MSLVCTRL0_RD_SHIFT                 (0U)
+#define RGX_CR_META_SP_MSLVCTRL0_RD_CLRMSK                (0XFFFFFFFEU)
+#define RGX_CR_META_SP_MSLVCTRL0_RD_EN                    (0X00000001U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVCTRL1
+*/
+#define RGX_CR_META_SP_MSLVCTRL1                          (0x0A18U)
+#define RGX_CR_META_SP_MSLVCTRL1_MASKFULL                 (IMG_UINT64_C(0x00000000F7F4003F))
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERRTHREAD_SHIFT       (30U)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERRTHREAD_CLRMSK      (0X3FFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_SHIFT    (29U)
+#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_CLRMSK   (0XDFFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_LOCK2_INTERLOCK_EN       (0X20000000U)
+#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_SHIFT   (28U)
+#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_CLRMSK  (0XEFFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_ATOMIC_INTERLOCK_EN      (0X10000000U)
+#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_SHIFT       (26U)
+#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_CLRMSK      (0XFBFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN          (0X04000000U)
+#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_SHIFT       (25U)
+#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_CLRMSK      (0XFDFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_COREMEM_IDLE_EN          (0X02000000U)
+#define RGX_CR_META_SP_MSLVCTRL1_READY_SHIFT              (24U)
+#define RGX_CR_META_SP_MSLVCTRL1_READY_CLRMSK             (0XFEFFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_READY_EN                 (0X01000000U)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERRID_SHIFT           (21U)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERRID_CLRMSK          (0XFF1FFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_SHIFT             (20U)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_CLRMSK            (0XFFEFFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_DEFERR_EN                (0X00100000U)
+#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_SHIFT          (18U)
+#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_CLRMSK         (0XFFFBFFFFU)
+#define RGX_CR_META_SP_MSLVCTRL1_WR_ACTIVE_EN             (0X00040000U)
+#define RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT             (4U)
+#define RGX_CR_META_SP_MSLVCTRL1_THREAD_CLRMSK            (0XFFFFFFCFU)
+#define RGX_CR_META_SP_MSLVCTRL1_TRANS_SIZE_SHIFT         (2U)
+#define RGX_CR_META_SP_MSLVCTRL1_TRANS_SIZE_CLRMSK        (0XFFFFFFF3U)
+#define RGX_CR_META_SP_MSLVCTRL1_BYTE_ROUND_SHIFT         (0U)
+#define RGX_CR_META_SP_MSLVCTRL1_BYTE_ROUND_CLRMSK        (0XFFFFFFFCU)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVHANDSHKE
+*/
+#define RGX_CR_META_SP_MSLVHANDSHKE                       (0x0A50U)
+#define RGX_CR_META_SP_MSLVHANDSHKE_MASKFULL              (IMG_UINT64_C(0x000000000000000F))
+#define RGX_CR_META_SP_MSLVHANDSHKE_INPUT_SHIFT           (2U)
+#define RGX_CR_META_SP_MSLVHANDSHKE_INPUT_CLRMSK          (0XFFFFFFF3U)
+#define RGX_CR_META_SP_MSLVHANDSHKE_OUTPUT_SHIFT          (0U)
+#define RGX_CR_META_SP_MSLVHANDSHKE_OUTPUT_CLRMSK         (0XFFFFFFFCU)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT0KICK
+*/
+#define RGX_CR_META_SP_MSLVT0KICK                         (0x0A80U)
+#define RGX_CR_META_SP_MSLVT0KICK_MASKFULL                (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT0KICK_MSLVT0KICK_SHIFT        (0U)
+#define RGX_CR_META_SP_MSLVT0KICK_MSLVT0KICK_CLRMSK       (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT0KICKI
+*/
+#define RGX_CR_META_SP_MSLVT0KICKI                        (0x0A88U)
+#define RGX_CR_META_SP_MSLVT0KICKI_MASKFULL               (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT0KICKI_MSLVT0KICKI_SHIFT      (0U)
+#define RGX_CR_META_SP_MSLVT0KICKI_MSLVT0KICKI_CLRMSK     (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT1KICK
+*/
+#define RGX_CR_META_SP_MSLVT1KICK                         (0x0A90U)
+#define RGX_CR_META_SP_MSLVT1KICK_MASKFULL                (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT1KICK_MSLVT1KICK_SHIFT        (0U)
+#define RGX_CR_META_SP_MSLVT1KICK_MSLVT1KICK_CLRMSK       (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT1KICKI
+*/
+#define RGX_CR_META_SP_MSLVT1KICKI                        (0x0A98U)
+#define RGX_CR_META_SP_MSLVT1KICKI_MASKFULL               (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT1KICKI_MSLVT1KICKI_SHIFT      (0U)
+#define RGX_CR_META_SP_MSLVT1KICKI_MSLVT1KICKI_CLRMSK     (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT2KICK
+*/
+#define RGX_CR_META_SP_MSLVT2KICK                         (0x0AA0U)
+#define RGX_CR_META_SP_MSLVT2KICK_MASKFULL                (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT2KICK_MSLVT2KICK_SHIFT        (0U)
+#define RGX_CR_META_SP_MSLVT2KICK_MSLVT2KICK_CLRMSK       (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT2KICKI
+*/
+#define RGX_CR_META_SP_MSLVT2KICKI                        (0x0AA8U)
+#define RGX_CR_META_SP_MSLVT2KICKI_MASKFULL               (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT2KICKI_MSLVT2KICKI_SHIFT      (0U)
+#define RGX_CR_META_SP_MSLVT2KICKI_MSLVT2KICKI_CLRMSK     (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT3KICK
+*/
+#define RGX_CR_META_SP_MSLVT3KICK                         (0x0AB0U)
+#define RGX_CR_META_SP_MSLVT3KICK_MASKFULL                (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT3KICK_MSLVT3KICK_SHIFT        (0U)
+#define RGX_CR_META_SP_MSLVT3KICK_MSLVT3KICK_CLRMSK       (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVT3KICKI
+*/
+#define RGX_CR_META_SP_MSLVT3KICKI                        (0x0AB8U)
+#define RGX_CR_META_SP_MSLVT3KICKI_MASKFULL               (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_META_SP_MSLVT3KICKI_MSLVT3KICKI_SHIFT      (0U)
+#define RGX_CR_META_SP_MSLVT3KICKI_MSLVT3KICKI_CLRMSK     (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVRST
+*/
+#define RGX_CR_META_SP_MSLVRST                            (0x0AC0U)
+#define RGX_CR_META_SP_MSLVRST_MASKFULL                   (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_META_SP_MSLVRST_SOFTRESET_SHIFT            (0U)
+#define RGX_CR_META_SP_MSLVRST_SOFTRESET_CLRMSK           (0XFFFFFFFEU)
+#define RGX_CR_META_SP_MSLVRST_SOFTRESET_EN               (0X00000001U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVIRQSTATUS
+*/
+#define RGX_CR_META_SP_MSLVIRQSTATUS                      (0x0AC8U)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_MASKFULL             (IMG_UINT64_C(0x000000000000000C))
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_SHIFT      (3U)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_CLRMSK     (0XFFFFFFF7U)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT3_EN         (0X00000008U)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_SHIFT      (2U)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK     (0XFFFFFFFBU)
+#define RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN         (0X00000004U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVIRQENABLE
+*/
+#define RGX_CR_META_SP_MSLVIRQENABLE                      (0x0AD0U)
+#define RGX_CR_META_SP_MSLVIRQENABLE_MASKFULL             (IMG_UINT64_C(0x000000000000000C))
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_SHIFT         (3U)
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_CLRMSK        (0XFFFFFFF7U)
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT1_EN            (0X00000008U)
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_SHIFT         (2U)
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_CLRMSK        (0XFFFFFFFBU)
+#define RGX_CR_META_SP_MSLVIRQENABLE_EVENT0_EN            (0X00000004U)
+
+
+/*
+    Register RGX_CR_META_SP_MSLVIRQLEVEL
+*/
+#define RGX_CR_META_SP_MSLVIRQLEVEL                       (0x0AD8U)
+#define RGX_CR_META_SP_MSLVIRQLEVEL_MASKFULL              (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_SHIFT            (0U)
+#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_CLRMSK           (0XFFFFFFFEU)
+#define RGX_CR_META_SP_MSLVIRQLEVEL_MODE_EN               (0X00000001U)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE
+*/
+#define RGX_CR_MTS_SCHEDULE                               (0x0B00U)
+#define RGX_CR_MTS_SCHEDULE_MASKFULL                      (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE_HOST_SHIFT                    (8U)
+#define RGX_CR_MTS_SCHEDULE_HOST_CLRMSK                   (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE_HOST_BG_TIMER                 (00000000U)
+#define RGX_CR_MTS_SCHEDULE_HOST_HOST                     (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_SHIFT                (6U)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_CLRMSK               (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT0                 (00000000U)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT1                 (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT2                 (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE_PRIORITY_PRT3                 (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE_CONTEXT_SHIFT                 (5U)
+#define RGX_CR_MTS_SCHEDULE_CONTEXT_CLRMSK                (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE_CONTEXT_BGCTX                 (00000000U)
+#define RGX_CR_MTS_SCHEDULE_CONTEXT_INTCTX                (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE_TASK_SHIFT                    (4U)
+#define RGX_CR_MTS_SCHEDULE_TASK_CLRMSK                   (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED              (00000000U)
+#define RGX_CR_MTS_SCHEDULE_TASK_COUNTED                  (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE_DM_SHIFT                      (0U)
+#define RGX_CR_MTS_SCHEDULE_DM_CLRMSK                     (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM0                        (00000000U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM1                        (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM2                        (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM3                        (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM4                        (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM5                        (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM6                        (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM7                        (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE_DM_DM_ALL                     (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE1
+*/
+#define RGX_CR_MTS_SCHEDULE1                              (0x10B00U)
+#define RGX_CR_MTS_SCHEDULE1_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE1_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE1_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE1_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE1_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE1_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE1_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE1_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE1_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE1_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE1_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE1_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE1_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE1_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE1_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE1_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE1_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE2
+*/
+#define RGX_CR_MTS_SCHEDULE2                              (0x20B00U)
+#define RGX_CR_MTS_SCHEDULE2_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE2_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE2_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE2_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE2_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE2_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE2_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE2_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE2_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE2_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE2_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE2_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE2_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE2_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE2_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE2_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE2_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE3
+*/
+#define RGX_CR_MTS_SCHEDULE3                              (0x30B00U)
+#define RGX_CR_MTS_SCHEDULE3_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE3_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE3_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE3_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE3_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE3_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE3_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE3_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE3_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE3_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE3_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE3_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE3_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE3_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE3_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE3_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE3_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE4
+*/
+#define RGX_CR_MTS_SCHEDULE4                              (0x40B00U)
+#define RGX_CR_MTS_SCHEDULE4_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE4_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE4_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE4_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE4_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE4_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE4_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE4_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE4_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE4_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE4_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE4_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE4_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE4_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE4_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE4_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE4_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE5
+*/
+#define RGX_CR_MTS_SCHEDULE5                              (0x50B00U)
+#define RGX_CR_MTS_SCHEDULE5_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE5_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE5_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE5_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE5_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE5_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE5_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE5_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE5_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE5_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE5_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE5_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE5_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE5_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE5_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE5_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE5_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE6
+*/
+#define RGX_CR_MTS_SCHEDULE6                              (0x60B00U)
+#define RGX_CR_MTS_SCHEDULE6_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE6_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE6_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE6_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE6_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE6_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE6_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE6_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE6_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE6_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE6_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE6_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE6_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE6_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE6_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE6_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE6_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_SCHEDULE7
+*/
+#define RGX_CR_MTS_SCHEDULE7                              (0x70B00U)
+#define RGX_CR_MTS_SCHEDULE7_MASKFULL                     (IMG_UINT64_C(0x00000000000001FF))
+#define RGX_CR_MTS_SCHEDULE7_HOST_SHIFT                   (8U)
+#define RGX_CR_MTS_SCHEDULE7_HOST_CLRMSK                  (0XFFFFFEFFU)
+#define RGX_CR_MTS_SCHEDULE7_HOST_BG_TIMER                (00000000U)
+#define RGX_CR_MTS_SCHEDULE7_HOST_HOST                    (0X00000100U)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_SHIFT               (6U)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_CLRMSK              (0XFFFFFF3FU)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT0                (00000000U)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT1                (0X00000040U)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT2                (0X00000080U)
+#define RGX_CR_MTS_SCHEDULE7_PRIORITY_PRT3                (0X000000C0U)
+#define RGX_CR_MTS_SCHEDULE7_CONTEXT_SHIFT                (5U)
+#define RGX_CR_MTS_SCHEDULE7_CONTEXT_CLRMSK               (0XFFFFFFDFU)
+#define RGX_CR_MTS_SCHEDULE7_CONTEXT_BGCTX                (00000000U)
+#define RGX_CR_MTS_SCHEDULE7_CONTEXT_INTCTX               (0X00000020U)
+#define RGX_CR_MTS_SCHEDULE7_TASK_SHIFT                   (4U)
+#define RGX_CR_MTS_SCHEDULE7_TASK_CLRMSK                  (0XFFFFFFEFU)
+#define RGX_CR_MTS_SCHEDULE7_TASK_NON_COUNTED             (00000000U)
+#define RGX_CR_MTS_SCHEDULE7_TASK_COUNTED                 (0X00000010U)
+#define RGX_CR_MTS_SCHEDULE7_DM_SHIFT                     (0U)
+#define RGX_CR_MTS_SCHEDULE7_DM_CLRMSK                    (0XFFFFFFF0U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM0                       (00000000U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM1                       (0X00000001U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM2                       (0X00000002U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM3                       (0X00000003U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM4                       (0X00000004U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM5                       (0X00000005U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM6                       (0X00000006U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM7                       (0X00000007U)
+#define RGX_CR_MTS_SCHEDULE7_DM_DM_ALL                    (0X0000000FU)
+
+
+/*
+    Register RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC
+*/
+#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC                 (0x0B30U)
+#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL        (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_SHIFT  (0U)
+#define RGX_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC
+*/
+#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC                 (0x0B38U)
+#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL        (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_SHIFT  (0U)
+#define RGX_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC
+*/
+#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC                (0x0B40U)
+#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL       (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_SHIFT (0U)
+#define RGX_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC
+*/
+#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC                (0x0B48U)
+#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL       (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_SHIFT (0U)
+#define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK (0XFFFF0000U)
+
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_MTS_GARTEN_WRAPPER_CONFIG
+*/
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG                  (0x0B50U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_MASKFULL         (IMG_UINT64_C(0x000FF0FFFFFFF701))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT (44U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0XFFF00FFFFFFFFFFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_SHIFT (12U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_SHIFT (9U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFF9FF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_SHIFT (8U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_EN (IMG_UINT64_C(0X0000000000000100))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_SHIFT  (0U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META   (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS    (IMG_UINT64_C(0x0000000000000001))
+#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
+
+
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*
+    Register RGX_CR_MTS_GARTEN_WRAPPER_CONFIG
+*/
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG                  (0x0B50U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_MASKFULL         (IMG_UINT64_C(0x0000FFFFFFFFF001))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT (44U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0XFFFF0FFFFFFFFFFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT   (40U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_CLRMSK  (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_SHIFT (12U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_SHIFT  (0U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META   (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS    (IMG_UINT64_C(0x0000000000000001))
+#endif /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
+
+
+/*
+    Register RGX_CR_MTS_INTCTX
+*/
+#define RGX_CR_MTS_INTCTX                                 (0x0B98U)
+#define RGX_CR_MTS_INTCTX_MASKFULL                        (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_MTS_INTCTX_DM_HOST_SCHEDULE_SHIFT          (22U)
+#define RGX_CR_MTS_INTCTX_DM_HOST_SCHEDULE_CLRMSK         (0XC03FFFFFU)
+#define RGX_CR_MTS_INTCTX_DM_PTR_SHIFT                    (18U)
+#define RGX_CR_MTS_INTCTX_DM_PTR_CLRMSK                   (0XFFC3FFFFU)
+#define RGX_CR_MTS_INTCTX_THREAD_ACTIVE_SHIFT             (16U)
+#define RGX_CR_MTS_INTCTX_THREAD_ACTIVE_CLRMSK            (0XFFFCFFFFU)
+#define RGX_CR_MTS_INTCTX_DM_TIMER_SCHEDULE_SHIFT         (8U)
+#define RGX_CR_MTS_INTCTX_DM_TIMER_SCHEDULE_CLRMSK        (0XFFFF00FFU)
+#define RGX_CR_MTS_INTCTX_DM_INTERRUPT_SCHEDULE_SHIFT     (0U)
+#define RGX_CR_MTS_INTCTX_DM_INTERRUPT_SCHEDULE_CLRMSK    (0XFFFFFF00U)
+
+
+/*
+    Register RGX_CR_MTS_BGCTX
+*/
+#define RGX_CR_MTS_BGCTX                                  (0x0BA0U)
+#define RGX_CR_MTS_BGCTX_MASKFULL                         (IMG_UINT64_C(0x0000000000003FFF))
+#define RGX_CR_MTS_BGCTX_DM_PTR_SHIFT                     (10U)
+#define RGX_CR_MTS_BGCTX_DM_PTR_CLRMSK                    (0XFFFFC3FFU)
+#define RGX_CR_MTS_BGCTX_THREAD_ACTIVE_SHIFT              (8U)
+#define RGX_CR_MTS_BGCTX_THREAD_ACTIVE_CLRMSK             (0XFFFFFCFFU)
+#define RGX_CR_MTS_BGCTX_DM_NONCOUNTED_SCHEDULE_SHIFT     (0U)
+#define RGX_CR_MTS_BGCTX_DM_NONCOUNTED_SCHEDULE_CLRMSK    (0XFFFFFF00U)
+
+
+/*
+    Register RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE
+*/
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE                 (0x0BA8U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_MASKFULL        (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_SHIFT       (56U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_CLRMSK      (IMG_UINT64_C(0X00FFFFFFFFFFFFFF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_SHIFT       (48U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_CLRMSK      (IMG_UINT64_C(0XFF00FFFFFFFFFFFF))
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_SHIFT       (40U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_CLRMSK      (IMG_UINT64_C(0XFFFF00FFFFFFFFFF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM4_SHIFT       (32U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM4_CLRMSK      (IMG_UINT64_C(0XFFFFFF00FFFFFFFF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM3_SHIFT       (24U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM3_CLRMSK      (IMG_UINT64_C(0XFFFFFFFF00FFFFFF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM2_SHIFT       (16U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM2_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFF00FFFF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM1_SHIFT       (8U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM1_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFF00FF))
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM0_SHIFT       (0U)
+#define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM0_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFF00))
+
+
+/*
+    Register RGX_CR_MTS_GPU_INT_STATUS
+*/
+#define RGX_CR_MTS_GPU_INT_STATUS                         (0x0BB0U)
+#define RGX_CR_MTS_GPU_INT_STATUS_MASKFULL                (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_MTS_GPU_INT_STATUS_STATUS_SHIFT            (0U)
+#define RGX_CR_MTS_GPU_INT_STATUS_STATUS_CLRMSK           (00000000U)
+
+
+/*
+    Register RGX_CR_META_BOOT
+*/
+#define RGX_CR_META_BOOT                                  (0x0BF8U)
+#define RGX_CR_META_BOOT_MASKFULL                         (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_META_BOOT_MODE_SHIFT                       (0U)
+#define RGX_CR_META_BOOT_MODE_CLRMSK                      (0XFFFFFFFEU)
+#define RGX_CR_META_BOOT_MODE_EN                          (0X00000001U)
+
+
+/*
+    Register RGX_CR_GARTEN_SLC
+*/
+#define RGX_CR_GARTEN_SLC                                 (0x0BB8U)
+#define RGX_CR_GARTEN_SLC_MASKFULL                        (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_SHIFT           (0U)
+#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_CLRMSK          (0XFFFFFFFEU)
+#define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_EN              (0X00000001U)
+
+
+#define RGX_CR_ISP_RENDER_DIR_TYPE_MASK                   (0x00000003U)
+/*
+ Top-left to bottom-right */
+#define RGX_CR_ISP_RENDER_DIR_TYPE_TL2BR                  (0x00000000U)
+/*
+ Top-right to bottom-left */
+#define RGX_CR_ISP_RENDER_DIR_TYPE_TR2BL                  (0x00000001U)
+/*
+ Bottom-left to top-right */
+#define RGX_CR_ISP_RENDER_DIR_TYPE_BL2TR                  (0x00000002U)
+/*
+ Bottom-right to top-left */
+#define RGX_CR_ISP_RENDER_DIR_TYPE_BR2TL                  (0x00000003U)
+
+
+#define RGX_CR_ISP_RENDER_MODE_TYPE_MASK                  (0x00000003U)
+/*
+ Normal render     */
+#define RGX_CR_ISP_RENDER_MODE_TYPE_NORM                  (0x00000000U)
+/*
+ Fast 2D render    */
+#define RGX_CR_ISP_RENDER_MODE_TYPE_FAST_2D               (0x00000002U)
+/*
+ Fast scale render */
+#define RGX_CR_ISP_RENDER_MODE_TYPE_FAST_SCALE            (0x00000003U)
+
+
+/*
+    Register RGX_CR_ISP_RENDER
+*/
+#define RGX_CR_ISP_RENDER                                 (0x0F08U)
+#define RGX_CR_ISP_RENDER_MASKFULL                        (IMG_UINT64_C(0x000000000000001F))
+#define RGX_CR_ISP_RENDER_RESUME_SHIFT                    (4U)
+#define RGX_CR_ISP_RENDER_RESUME_CLRMSK                   (0XFFFFFFEFU)
+#define RGX_CR_ISP_RENDER_RESUME_EN                       (0X00000010U)
+#define RGX_CR_ISP_RENDER_DIR_SHIFT                       (2U)
+#define RGX_CR_ISP_RENDER_DIR_CLRMSK                      (0XFFFFFFF3U)
+#define RGX_CR_ISP_RENDER_DIR_TL2BR                       (00000000U)
+#define RGX_CR_ISP_RENDER_DIR_TR2BL                       (0X00000004U)
+#define RGX_CR_ISP_RENDER_DIR_BL2TR                       (0X00000008U)
+#define RGX_CR_ISP_RENDER_DIR_BR2TL                       (0X0000000CU)
+#define RGX_CR_ISP_RENDER_MODE_SHIFT                      (0U)
+#define RGX_CR_ISP_RENDER_MODE_CLRMSK                     (0XFFFFFFFCU)
+#define RGX_CR_ISP_RENDER_MODE_NORM                       (00000000U)
+#define RGX_CR_ISP_RENDER_MODE_FAST_2D                    (0X00000002U)
+#define RGX_CR_ISP_RENDER_MODE_FAST_SCALE                 (0X00000003U)
+
+
+/*
+    Register RGX_CR_ISP_CTL
+*/
+#define RGX_CR_ISP_CTL                                    (0x0F38U)
+#define RGX_CR_ISP_CTL_MASKFULL                           (IMG_UINT64_C(0x0000000001FFF3FF))
+#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_SHIFT          (23U)
+#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_CLRMSK         (0XFE7FFFFFU)
+#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_DX9            (00000000U)
+#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_DX10           (0X00800000U)
+#define RGX_CR_ISP_CTL_ISP_SAMPLE_POS_MODE_OGL            (0X01000000U)
+#define RGX_CR_ISP_CTL_NUM_TILES_PER_USC_SHIFT            (21U)
+#define RGX_CR_ISP_CTL_NUM_TILES_PER_USC_CLRMSK           (0XFF9FFFFFU)
+#define RGX_CR_ISP_CTL_DBIAS_IS_INT_SHIFT                 (20U)
+#define RGX_CR_ISP_CTL_DBIAS_IS_INT_CLRMSK                (0XFFEFFFFFU)
+#define RGX_CR_ISP_CTL_DBIAS_IS_INT_EN                    (0X00100000U)
+#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_SHIFT           (19U)
+#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_CLRMSK          (0XFFF7FFFFU)
+#define RGX_CR_ISP_CTL_OVERLAP_CHECK_MODE_EN              (0X00080000U)
+#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_SHIFT     (18U)
+#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_CLRMSK    (0XFFFBFFFFU)
+#define RGX_CR_ISP_CTL_PT_UPFRONT_DEPTH_DISABLE_EN        (0X00040000U)
+#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_SHIFT          (17U)
+#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_CLRMSK         (0XFFFDFFFFU)
+#define RGX_CR_ISP_CTL_PROCESS_EMPTY_TILES_EN             (0X00020000U)
+#define RGX_CR_ISP_CTL_SAMPLE_POS_SHIFT                   (16U)
+#define RGX_CR_ISP_CTL_SAMPLE_POS_CLRMSK                  (0XFFFEFFFFU)
+#define RGX_CR_ISP_CTL_SAMPLE_POS_EN                      (0X00010000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_SHIFT                  (12U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_CLRMSK                 (0XFFFF0FFFU)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_ONE               (00000000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TWO               (0X00001000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_THREE             (0X00002000U)
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FOUR              (0X00003000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FIVE              (0X00004000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SIX               (0X00005000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SEVEN             (0X00006000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_EIGHT             (0X00007000U)
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+
+#define RGX_CR_ISP_CTL_VALID_ID_SHIFT                     (4U)
+#define RGX_CR_ISP_CTL_VALID_ID_CLRMSK                    (0XFFFFFC0FU)
+#define RGX_CR_ISP_CTL_UPASS_START_SHIFT                  (0U)
+#define RGX_CR_ISP_CTL_UPASS_START_CLRMSK                 (0XFFFFFFF0U)
+
+
+/*
+    Register RGX_CR_ISP_STORE0
+*/
+#define RGX_CR_ISP_STORE0                                 (0x1008U)
+#define RGX_CR_ISP_STORE0_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
+#define RGX_CR_ISP_STORE0_ACTIVE_SHIFT                    (30U)
+#define RGX_CR_ISP_STORE0_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
+#define RGX_CR_ISP_STORE0_ACTIVE_EN                       (0X40000000U)
+#define RGX_CR_ISP_STORE0_EOR_SHIFT                       (29U)
+#define RGX_CR_ISP_STORE0_EOR_CLRMSK                      (0XDFFFFFFFU)
+#define RGX_CR_ISP_STORE0_EOR_EN                          (0X20000000U)
+#define RGX_CR_ISP_STORE0_TILE_LAST_SHIFT                 (28U)
+#define RGX_CR_ISP_STORE0_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
+#define RGX_CR_ISP_STORE0_TILE_LAST_EN                    (0X10000000U)
+#define RGX_CR_ISP_STORE0_MT_SHIFT                        (24U)
+#define RGX_CR_ISP_STORE0_MT_CLRMSK                       (0XF0FFFFFFU)
+#define RGX_CR_ISP_STORE0_TILE_X_SHIFT                    (12U)
+#define RGX_CR_ISP_STORE0_TILE_X_CLRMSK                   (0XFFC00FFFU)
+#define RGX_CR_ISP_STORE0_TILE_Y_SHIFT                    (0U)
+#define RGX_CR_ISP_STORE0_TILE_Y_CLRMSK                   (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_STORE1
+*/
+#define RGX_CR_ISP_STORE1                                 (0x1010U)
+#define RGX_CR_ISP_STORE1_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
+#define RGX_CR_ISP_STORE1_ACTIVE_SHIFT                    (30U)
+#define RGX_CR_ISP_STORE1_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
+#define RGX_CR_ISP_STORE1_ACTIVE_EN                       (0X40000000U)
+#define RGX_CR_ISP_STORE1_EOR_SHIFT                       (29U)
+#define RGX_CR_ISP_STORE1_EOR_CLRMSK                      (0XDFFFFFFFU)
+#define RGX_CR_ISP_STORE1_EOR_EN                          (0X20000000U)
+#define RGX_CR_ISP_STORE1_TILE_LAST_SHIFT                 (28U)
+#define RGX_CR_ISP_STORE1_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
+#define RGX_CR_ISP_STORE1_TILE_LAST_EN                    (0X10000000U)
+#define RGX_CR_ISP_STORE1_MT_SHIFT                        (24U)
+#define RGX_CR_ISP_STORE1_MT_CLRMSK                       (0XF0FFFFFFU)
+#define RGX_CR_ISP_STORE1_TILE_X_SHIFT                    (12U)
+#define RGX_CR_ISP_STORE1_TILE_X_CLRMSK                   (0XFFC00FFFU)
+#define RGX_CR_ISP_STORE1_TILE_Y_SHIFT                    (0U)
+#define RGX_CR_ISP_STORE1_TILE_Y_CLRMSK                   (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_STORE2
+*/
+#define RGX_CR_ISP_STORE2                                 (0x1018U)
+#define RGX_CR_ISP_STORE2_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
+#define RGX_CR_ISP_STORE2_ACTIVE_SHIFT                    (30U)
+#define RGX_CR_ISP_STORE2_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
+#define RGX_CR_ISP_STORE2_ACTIVE_EN                       (0X40000000U)
+#define RGX_CR_ISP_STORE2_EOR_SHIFT                       (29U)
+#define RGX_CR_ISP_STORE2_EOR_CLRMSK                      (0XDFFFFFFFU)
+#define RGX_CR_ISP_STORE2_EOR_EN                          (0X20000000U)
+#define RGX_CR_ISP_STORE2_TILE_LAST_SHIFT                 (28U)
+#define RGX_CR_ISP_STORE2_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
+#define RGX_CR_ISP_STORE2_TILE_LAST_EN                    (0X10000000U)
+#define RGX_CR_ISP_STORE2_MT_SHIFT                        (24U)
+#define RGX_CR_ISP_STORE2_MT_CLRMSK                       (0XF0FFFFFFU)
+#define RGX_CR_ISP_STORE2_TILE_X_SHIFT                    (12U)
+#define RGX_CR_ISP_STORE2_TILE_X_CLRMSK                   (0XFFC00FFFU)
+#define RGX_CR_ISP_STORE2_TILE_Y_SHIFT                    (0U)
+#define RGX_CR_ISP_STORE2_TILE_Y_CLRMSK                   (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_RESUME0
+*/
+#define RGX_CR_ISP_RESUME0                                (0x1020U)
+#define RGX_CR_ISP_RESUME0_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
+#define RGX_CR_ISP_RESUME0_TILE_X_SHIFT                   (12U)
+#define RGX_CR_ISP_RESUME0_TILE_X_CLRMSK                  (0XFFC00FFFU)
+#define RGX_CR_ISP_RESUME0_TILE_Y_SHIFT                   (0U)
+#define RGX_CR_ISP_RESUME0_TILE_Y_CLRMSK                  (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_RESUME1
+*/
+#define RGX_CR_ISP_RESUME1                                (0x1028U)
+#define RGX_CR_ISP_RESUME1_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
+#define RGX_CR_ISP_RESUME1_TILE_X_SHIFT                   (12U)
+#define RGX_CR_ISP_RESUME1_TILE_X_CLRMSK                  (0XFFC00FFFU)
+#define RGX_CR_ISP_RESUME1_TILE_Y_SHIFT                   (0U)
+#define RGX_CR_ISP_RESUME1_TILE_Y_CLRMSK                  (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_RESUME2
+*/
+#define RGX_CR_ISP_RESUME2                                (0x1030U)
+#define RGX_CR_ISP_RESUME2_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
+#define RGX_CR_ISP_RESUME2_TILE_X_SHIFT                   (12U)
+#define RGX_CR_ISP_RESUME2_TILE_X_CLRMSK                  (0XFFC00FFFU)
+#define RGX_CR_ISP_RESUME2_TILE_Y_SHIFT                   (0U)
+#define RGX_CR_ISP_RESUME2_TILE_Y_CLRMSK                  (0XFFFFFC00U)
+
+
+/*
+    Register RGX_CR_ISP_STATUS
+*/
+#define RGX_CR_ISP_STATUS                                 (0x1038U)
+#define RGX_CR_ISP_STATUS_MASKFULL                        (IMG_UINT64_C(0x0000000000000007))
+#define RGX_CR_ISP_STATUS_SPLIT_MAX_SHIFT                 (2U)
+#define RGX_CR_ISP_STATUS_SPLIT_MAX_CLRMSK                (0XFFFFFFFBU)
+#define RGX_CR_ISP_STATUS_SPLIT_MAX_EN                    (0X00000004U)
+#define RGX_CR_ISP_STATUS_ACTIVE_SHIFT                    (1U)
+#define RGX_CR_ISP_STATUS_ACTIVE_CLRMSK                   (0XFFFFFFFDU)
+#define RGX_CR_ISP_STATUS_ACTIVE_EN                       (0X00000002U)
+#define RGX_CR_ISP_STATUS_EOR_SHIFT                       (0U)
+#define RGX_CR_ISP_STATUS_EOR_CLRMSK                      (0XFFFFFFFEU)
+#define RGX_CR_ISP_STATUS_EOR_EN                          (0X00000001U)
+
+
+/*
+    Register group: RGX_CR_BIF_CAT_BASE, with 8 repeats
+*/
+#define RGX_CR_BIF_CAT_BASE_REPEATCOUNT                   (8)
+/*
+    Register RGX_CR_BIF_CAT_BASE0
+*/
+#define RGX_CR_BIF_CAT_BASE0                              (0x1200U)
+#define RGX_CR_BIF_CAT_BASE0_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE0_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE0_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE0_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE1
+*/
+#define RGX_CR_BIF_CAT_BASE1                              (0x1208U)
+#define RGX_CR_BIF_CAT_BASE1_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE1_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE1_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE1_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE1_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE2
+*/
+#define RGX_CR_BIF_CAT_BASE2                              (0x1210U)
+#define RGX_CR_BIF_CAT_BASE2_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE2_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE2_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE2_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE2_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE3
+*/
+#define RGX_CR_BIF_CAT_BASE3                              (0x1218U)
+#define RGX_CR_BIF_CAT_BASE3_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE3_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE3_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE3_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE3_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE4
+*/
+#define RGX_CR_BIF_CAT_BASE4                              (0x1220U)
+#define RGX_CR_BIF_CAT_BASE4_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE4_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE4_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE4_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE4_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE5
+*/
+#define RGX_CR_BIF_CAT_BASE5                              (0x1228U)
+#define RGX_CR_BIF_CAT_BASE5_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE5_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE5_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE5_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE5_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE6
+*/
+#define RGX_CR_BIF_CAT_BASE6                              (0x1230U)
+#define RGX_CR_BIF_CAT_BASE6_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE6_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE6_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE6_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE6_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE7
+*/
+#define RGX_CR_BIF_CAT_BASE7                              (0x1238U)
+#define RGX_CR_BIF_CAT_BASE7_MASKFULL                     (IMG_UINT64_C(0x000000FFFFFFF000))
+#define RGX_CR_BIF_CAT_BASE7_ADDR_SHIFT                   (12U)
+#define RGX_CR_BIF_CAT_BASE7_ADDR_CLRMSK                  (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_CAT_BASE7_ADDR_ALIGNSHIFT              (12U)
+#define RGX_CR_BIF_CAT_BASE7_ADDR_ALIGNSIZE               (4096U)
+
+
+/*
+    Register RGX_CR_BIF_CAT_BASE_INDEX
+*/
+#define RGX_CR_BIF_CAT_BASE_INDEX                         (0x1240U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_MASKFULL                (IMG_UINT64_C(0x0007070707070707))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_SHIFT              (48U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_CLRMSK             (IMG_UINT64_C(0XFFF8FFFFFFFFFFFF))
+#define RGX_CR_BIF_CAT_BASE_INDEX_RAY_SHIFT               (40U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_RAY_CLRMSK              (IMG_UINT64_C(0XFFFFF8FFFFFFFFFF))
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_BIF_CAT_BASE_INDEX_HOST_SHIFT              (32U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_HOST_CLRMSK             (IMG_UINT64_C(0XFFFFFFF8FFFFFFFF))
+#define RGX_CR_BIF_CAT_BASE_INDEX_TLA_SHIFT               (24U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_TLA_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFF8FFFFFF))
+#define RGX_CR_BIF_CAT_BASE_INDEX_CDM_SHIFT               (16U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_CDM_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFF8FFFF))
+#define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_SHIFT             (8U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFF8FF))
+#define RGX_CR_BIF_CAT_BASE_INDEX_TA_SHIFT                (0U)
+#define RGX_CR_BIF_CAT_BASE_INDEX_TA_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFF8))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_VCE0
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0                       (0x1248U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_MASKFULL              (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_INIT_PAGE_SHIFT       (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_INIT_PAGE_CLRMSK      (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_ADDR_SHIFT            (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_ADDR_CLRMSK           (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_SHIFT            (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_WRAP_EN               (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_SHIFT           (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE0_VALID_EN              (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_TE0
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_TE0                        (0x1250U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_MASKFULL               (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_INIT_PAGE_SHIFT        (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_INIT_PAGE_CLRMSK       (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_ADDR_SHIFT             (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_ADDR_CLRMSK            (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_SHIFT             (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_WRAP_EN                (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_SHIFT            (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_TE0_VALID_EN               (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_ALIST0
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0                     (0x1260U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_MASKFULL            (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_INIT_PAGE_SHIFT     (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_INIT_PAGE_CLRMSK    (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_ADDR_SHIFT          (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_ADDR_CLRMSK         (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_SHIFT          (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_CLRMSK         (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_WRAP_EN             (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_SHIFT         (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST0_VALID_EN            (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_VCE1
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1                       (0x1268U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_MASKFULL              (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_INIT_PAGE_SHIFT       (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_INIT_PAGE_CLRMSK      (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_ADDR_SHIFT            (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_ADDR_CLRMSK           (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_SHIFT            (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_WRAP_EN               (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_SHIFT           (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_VCE1_VALID_EN              (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_TE1
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_TE1                        (0x1270U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_MASKFULL               (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_INIT_PAGE_SHIFT        (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_INIT_PAGE_CLRMSK       (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_ADDR_SHIFT             (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_ADDR_CLRMSK            (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_SHIFT             (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_WRAP_EN                (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_SHIFT            (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_TE1_VALID_EN               (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_PM_CAT_BASE_ALIST1
+*/
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1                     (0x1280U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_MASKFULL            (IMG_UINT64_C(0x0FFFFFFFFFFFF003))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_INIT_PAGE_SHIFT     (40U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_INIT_PAGE_CLRMSK    (IMG_UINT64_C(0XF00000FFFFFFFFFF))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_ADDR_SHIFT          (12U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_ADDR_CLRMSK         (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_SHIFT          (1U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_CLRMSK         (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_WRAP_EN             (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_SHIFT         (0U)
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_BIF_PM_CAT_BASE_ALIST1_VALID_EN            (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_BIF_MMU_ENTRY_STATUS
+*/
+#define RGX_CR_BIF_MMU_ENTRY_STATUS                       (0x1288U)
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_MASKFULL              (IMG_UINT64_C(0x000000FFFFFFF0F3))
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_SHIFT         (12U)
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_CLRMSK        (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_SHIFT        (4U)
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_CLRMSK       (IMG_UINT64_C(0XFFFFFFFFFFFFFF0F))
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_SHIFT       (0U)
+#define RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+
+
+/*
+    Register RGX_CR_BIF_MMU_ENTRY
+*/
+#define RGX_CR_BIF_MMU_ENTRY                              (0x1290U)
+#define RGX_CR_BIF_MMU_ENTRY_MASKFULL                     (IMG_UINT64_C(0x0000000000000003))
+#define RGX_CR_BIF_MMU_ENTRY_ENABLE_SHIFT                 (1U)
+#define RGX_CR_BIF_MMU_ENTRY_ENABLE_CLRMSK                (0XFFFFFFFDU)
+#define RGX_CR_BIF_MMU_ENTRY_ENABLE_EN                    (0X00000002U)
+#define RGX_CR_BIF_MMU_ENTRY_PENDING_SHIFT                (0U)
+#define RGX_CR_BIF_MMU_ENTRY_PENDING_CLRMSK               (0XFFFFFFFEU)
+#define RGX_CR_BIF_MMU_ENTRY_PENDING_EN                   (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_CTRL_INVAL
+*/
+#define RGX_CR_BIF_CTRL_INVAL                             (0x12A0U)
+#define RGX_CR_BIF_CTRL_INVAL_MASKFULL                    (IMG_UINT64_C(0x000000000000000F))
+#define RGX_CR_BIF_CTRL_INVAL_TLB1_SHIFT                  (3U)
+#define RGX_CR_BIF_CTRL_INVAL_TLB1_CLRMSK                 (0XFFFFFFF7U)
+#define RGX_CR_BIF_CTRL_INVAL_TLB1_EN                     (0X00000008U)
+#define RGX_CR_BIF_CTRL_INVAL_PC_SHIFT                    (2U)
+#define RGX_CR_BIF_CTRL_INVAL_PC_CLRMSK                   (0XFFFFFFFBU)
+#define RGX_CR_BIF_CTRL_INVAL_PC_EN                       (0X00000004U)
+#define RGX_CR_BIF_CTRL_INVAL_PD_SHIFT                    (1U)
+#define RGX_CR_BIF_CTRL_INVAL_PD_CLRMSK                   (0XFFFFFFFDU)
+#define RGX_CR_BIF_CTRL_INVAL_PD_EN                       (0X00000002U)
+#define RGX_CR_BIF_CTRL_INVAL_PT_SHIFT                    (0U)
+#define RGX_CR_BIF_CTRL_INVAL_PT_CLRMSK                   (0XFFFFFFFEU)
+#define RGX_CR_BIF_CTRL_INVAL_PT_EN                       (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_CTRL
+*/
+#define RGX_CR_BIF_CTRL                                   (0x12A8U)
+#define RGX_CR_BIF_CTRL_MASKFULL                          (IMG_UINT64_C(0x00000000000000FF))
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_SHIFT     (7U)
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_CLRMSK    (0XFFFFFF7FU)
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_QUEUE_BYPASS_EN        (0X00000080U)
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_SHIFT    (6U)
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_CLRMSK   (0XFFFFFFBFU)
+#define RGX_CR_BIF_CTRL_ENABLE_MMU_AUTO_PREFETCH_EN       (0X00000040U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_SHIFT              (5U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_CLRMSK             (0XFFFFFFDFU)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF3_EN                 (0X00000020U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_SHIFT              (4U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_CLRMSK             (0XFFFFFFEFU)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF2_EN                 (0X00000010U)
+#define RGX_CR_BIF_CTRL_PAUSE_BIF1_SHIFT                  (3U)
+#define RGX_CR_BIF_CTRL_PAUSE_BIF1_CLRMSK                 (0XFFFFFFF7U)
+#define RGX_CR_BIF_CTRL_PAUSE_BIF1_EN                     (0X00000008U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_SHIFT                (2U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_CLRMSK               (0XFFFFFFFBU)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_PM_EN                   (0X00000004U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_SHIFT              (1U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_CLRMSK             (0XFFFFFFFDU)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF1_EN                 (0X00000002U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_SHIFT              (0U)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_CLRMSK             (0XFFFFFFFEU)
+#define RGX_CR_BIF_CTRL_PAUSE_MMU_BIF0_EN                 (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_FAULT_BANK0_MMU_STATUS
+*/
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS                 (0x12B0U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_MASKFULL        (IMG_UINT64_C(0x000000000000F775))
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT  (12U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK (0XFFFF0FFFU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT (8U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK (0XFFFFF8FFU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT (5U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK (0XFFFFFF9FU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_SHIFT  (4U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_CLRMSK (0XFFFFFFEFU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN     (0X00000010U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0XFFFFFFFBU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN (0X00000004U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_SHIFT     (0U)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_CLRMSK    (0XFFFFFFFEU)
+#define RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_EN        (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_FAULT_BANK0_REQ_STATUS
+*/
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS                 (0x12B8U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_MASKFULL        (IMG_UINT64_C(0x0007FFFFFFFFFFF0))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_SHIFT       (50U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_CLRMSK      (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN          (IMG_UINT64_C(0X0004000000000000))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT    (44U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK   (IMG_UINT64_C(0XFFFC0FFFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT    (40U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK   (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT   (4U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK  (IMG_UINT64_C(0XFFFFFF000000000F))
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U)
+#define RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSIZE (16U)
+
+
+/*
+    Register RGX_CR_BIF_FAULT_BANK1_MMU_STATUS
+*/
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS                 (0x12C0U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_MASKFULL        (IMG_UINT64_C(0x000000000000F775))
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_CAT_BASE_SHIFT  (12U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_CAT_BASE_CLRMSK (0XFFFF0FFFU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_PAGE_SIZE_SHIFT (8U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_PAGE_SIZE_CLRMSK (0XFFFFF8FFU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_DATA_TYPE_SHIFT (5U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_DATA_TYPE_CLRMSK (0XFFFFFF9FU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_SHIFT  (4U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_CLRMSK (0XFFFFFFEFU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_RO_EN     (0X00000010U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0XFFFFFFFBU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_PM_META_RO_EN (0X00000004U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_SHIFT     (0U)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_CLRMSK    (0XFFFFFFFEU)
+#define RGX_CR_BIF_FAULT_BANK1_MMU_STATUS_FAULT_EN        (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_FAULT_BANK1_REQ_STATUS
+*/
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS                 (0x12C8U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_MASKFULL        (IMG_UINT64_C(0x0007FFFFFFFFFFF0))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_SHIFT       (50U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_CLRMSK      (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_RNW_EN          (IMG_UINT64_C(0X0004000000000000))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_SB_SHIFT    (44U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_SB_CLRMSK   (IMG_UINT64_C(0XFFFC0FFFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_ID_SHIFT    (40U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_TAG_ID_CLRMSK   (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_SHIFT   (4U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_CLRMSK  (IMG_UINT64_C(0XFFFFFF000000000F))
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U)
+#define RGX_CR_BIF_FAULT_BANK1_REQ_STATUS_ADDRESS_ALIGNSIZE (16U)
+
+
+/*
+    Register RGX_CR_BIF_MMU_STATUS
+*/
+#define RGX_CR_BIF_MMU_STATUS                             (0x12D0U)
+#define RGX_CR_BIF_MMU_STATUS_MASKFULL                    (IMG_UINT64_C(0x000000001FFFFFF7))
+#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_SHIFT              (28U)
+#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_CLRMSK             (0XEFFFFFFFU)
+#define RGX_CR_BIF_MMU_STATUS_PM_FAULT_EN                 (0X10000000U)
+#define RGX_CR_BIF_MMU_STATUS_PC_DATA_SHIFT               (20U)
+#define RGX_CR_BIF_MMU_STATUS_PC_DATA_CLRMSK              (0XF00FFFFFU)
+#define RGX_CR_BIF_MMU_STATUS_PD_DATA_SHIFT               (12U)
+#define RGX_CR_BIF_MMU_STATUS_PD_DATA_CLRMSK              (0XFFF00FFFU)
+#define RGX_CR_BIF_MMU_STATUS_PT_DATA_SHIFT               (4U)
+#define RGX_CR_BIF_MMU_STATUS_PT_DATA_CLRMSK              (0XFFFFF00FU)
+#define RGX_CR_BIF_MMU_STATUS_STALLED_SHIFT               (2U)
+#define RGX_CR_BIF_MMU_STATUS_STALLED_CLRMSK              (0XFFFFFFFBU)
+#define RGX_CR_BIF_MMU_STATUS_STALLED_EN                  (0X00000004U)
+#define RGX_CR_BIF_MMU_STATUS_PAUSED_SHIFT                (1U)
+#define RGX_CR_BIF_MMU_STATUS_PAUSED_CLRMSK               (0XFFFFFFFDU)
+#define RGX_CR_BIF_MMU_STATUS_PAUSED_EN                   (0X00000002U)
+#define RGX_CR_BIF_MMU_STATUS_BUSY_SHIFT                  (0U)
+#define RGX_CR_BIF_MMU_STATUS_BUSY_CLRMSK                 (0XFFFFFFFEU)
+#define RGX_CR_BIF_MMU_STATUS_BUSY_EN                     (0X00000001U)
+
+
+/*
+    Register RGX_CR_BIF_READS_EXT_STATUS
+*/
+#define RGX_CR_BIF_READS_EXT_STATUS                       (0x1320U)
+#define RGX_CR_BIF_READS_EXT_STATUS_MASKFULL              (IMG_UINT64_C(0x00000000007FFFFF))
+#define RGX_CR_BIF_READS_EXT_STATUS_MMU_SHIFT             (16U)
+#define RGX_CR_BIF_READS_EXT_STATUS_MMU_CLRMSK            (0XFF80FFFFU)
+#define RGX_CR_BIF_READS_EXT_STATUS_BANK1_SHIFT           (0U)
+#define RGX_CR_BIF_READS_EXT_STATUS_BANK1_CLRMSK          (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_BIF_READS_INT_STATUS
+*/
+#define RGX_CR_BIF_READS_INT_STATUS                       (0x1328U)
+#define RGX_CR_BIF_READS_INT_STATUS_MASKFULL              (IMG_UINT64_C(0x00000000007FFFFF))
+#define RGX_CR_BIF_READS_INT_STATUS_MMU_SHIFT             (16U)
+#define RGX_CR_BIF_READS_INT_STATUS_MMU_CLRMSK            (0XFF80FFFFU)
+#define RGX_CR_BIF_READS_INT_STATUS_BANK1_SHIFT           (0U)
+#define RGX_CR_BIF_READS_INT_STATUS_BANK1_CLRMSK          (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_BIFPM_READS_INT_STATUS
+*/
+#define RGX_CR_BIFPM_READS_INT_STATUS                     (0x1330U)
+#define RGX_CR_BIFPM_READS_INT_STATUS_MASKFULL            (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_BIFPM_READS_INT_STATUS_BANK0_SHIFT         (0U)
+#define RGX_CR_BIFPM_READS_INT_STATUS_BANK0_CLRMSK        (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_BIFPM_READS_EXT_STATUS
+*/
+#define RGX_CR_BIFPM_READS_EXT_STATUS                     (0x1338U)
+#define RGX_CR_BIFPM_READS_EXT_STATUS_MASKFULL            (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_BIFPM_READS_EXT_STATUS_BANK0_SHIFT         (0U)
+#define RGX_CR_BIFPM_READS_EXT_STATUS_BANK0_CLRMSK        (0XFFFF0000U)
+
+
+/*
+    Register RGX_CR_BIFPM_STATUS_MMU
+*/
+#define RGX_CR_BIFPM_STATUS_MMU                           (0x1350U)
+#define RGX_CR_BIFPM_STATUS_MMU_MASKFULL                  (IMG_UINT64_C(0x00000000000000FF))
+#define RGX_CR_BIFPM_STATUS_MMU_REQUESTS_SHIFT            (0U)
+#define RGX_CR_BIFPM_STATUS_MMU_REQUESTS_CLRMSK           (0XFFFFFF00U)
+
+
+/*
+    Register RGX_CR_BIF_STATUS_MMU
+*/
+#define RGX_CR_BIF_STATUS_MMU                             (0x1358U)
+#define RGX_CR_BIF_STATUS_MMU_MASKFULL                    (IMG_UINT64_C(0x00000000000000FF))
+#define RGX_CR_BIF_STATUS_MMU_REQUESTS_SHIFT              (0U)
+#define RGX_CR_BIF_STATUS_MMU_REQUESTS_CLRMSK             (0XFFFFFF00U)
+
+
+/*
+    Register RGX_CR_BIF_FAULT_READ
+*/
+#define RGX_CR_BIF_FAULT_READ                             (0x13E0U)
+#define RGX_CR_BIF_FAULT_READ_MASKFULL                    (IMG_UINT64_C(0x000000FFFFFFFFF0))
+#define RGX_CR_BIF_FAULT_READ_ADDRESS_SHIFT               (4U)
+#define RGX_CR_BIF_FAULT_READ_ADDRESS_CLRMSK              (IMG_UINT64_C(0XFFFFFF000000000F))
+#define RGX_CR_BIF_FAULT_READ_ADDRESS_ALIGNSHIFT          (4U)
+#define RGX_CR_BIF_FAULT_READ_ADDRESS_ALIGNSIZE           (16U)
+
+
+/*
+    Register RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS
+*/
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS           (0x1430U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_MASKFULL  (IMG_UINT64_C(0x000000000000F775))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT (12U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK (0XFFFF0FFFU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT (8U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK (0XFFFFF8FFU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT (5U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK (0XFFFFFF9FU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_SHIFT (4U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_CLRMSK (0XFFFFFFEFU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN (0X00000010U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0XFFFFFFFBU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN (0X00000004U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_SHIFT (0U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS_FAULT_EN  (0X00000001U)
+
+
+/*
+    Register RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS
+*/
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS           (0x1438U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_MASKFULL  (IMG_UINT64_C(0x0007FFFFFFFFFFF0))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_SHIFT (50U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_CLRMSK (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN    (IMG_UINT64_C(0X0004000000000000))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT (44U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK (IMG_UINT64_C(0XFFFC0FFFFFFFFFFF))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT (40U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT (4U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK (IMG_UINT64_C(0XFFFFFF000000000F))
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U)
+#define RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSIZE (16U)
+
+
+/*
+    Register RGX_CR_MCU_FENCE
+*/
+#define RGX_CR_MCU_FENCE                                  (0x1740U)
+#define RGX_CR_MCU_FENCE_MASKFULL                         (IMG_UINT64_C(0x000007FFFFFFFFE0))
+#define RGX_CR_MCU_FENCE_DM_SHIFT                         (40U)
+#define RGX_CR_MCU_FENCE_DM_CLRMSK                        (IMG_UINT64_C(0XFFFFF8FFFFFFFFFF))
+#define RGX_CR_MCU_FENCE_DM_VERTEX                        (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_MCU_FENCE_DM_PIXEL                         (IMG_UINT64_C(0x0000010000000000))
+#define RGX_CR_MCU_FENCE_DM_COMPUTE                       (IMG_UINT64_C(0x0000020000000000))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_MCU_FENCE_DM_RAY_VERTEX                    (IMG_UINT64_C(0x0000030000000000))
+#define RGX_CR_MCU_FENCE_DM_RAY                           (IMG_UINT64_C(0x0000040000000000))
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_MCU_FENCE_ADDR_SHIFT                       (5U)
+#define RGX_CR_MCU_FENCE_ADDR_CLRMSK                      (IMG_UINT64_C(0XFFFFFF000000001F))
+#define RGX_CR_MCU_FENCE_ADDR_ALIGNSHIFT                  (5U)
+#define RGX_CR_MCU_FENCE_ADDR_ALIGNSIZE                   (32U)
+
+
+/*
+    Register RGX_CR_SLC_CTRL_MISC
+*/
+#define RGX_CR_SLC_CTRL_MISC                              (0x3800U)
+#define RGX_CR_SLC_CTRL_MISC_MASKFULL                     (IMG_UINT64_C(0xFFFFFFFF00FF0105))
+#define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_SHIFT          (32U)
+#define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_CLRMSK         (IMG_UINT64_C(0X00000000FFFFFFFF))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SHIFT       (16U)
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFF00FFFF))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_64_BYTE (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_128_BYTE (IMG_UINT64_C(0x0000000000010000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH1 (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH2 (IMG_UINT64_C(0x0000000000110000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1   (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH2_SCRAMBLE (IMG_UINT64_C(0x0000000000210000))
+#define RGX_CR_SLC_CTRL_MISC_PAUSE_SHIFT                  (8U)
+#define RGX_CR_SLC_CTRL_MISC_PAUSE_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_SLC_CTRL_MISC_PAUSE_EN                     (IMG_UINT64_C(0X0000000000000100))
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_SHIFT  (2U)
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_EN     (IMG_UINT64_C(0X0000000000000004))
+#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_SHIFT  (0U)
+#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN     (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_SLC_CTRL_FLUSH_INVAL
+*/
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL                       (0x3818U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_MASKFULL              (IMG_UINT64_C(0x00000000800007FF))
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_SHIFT            (31U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_CLRMSK           (0X7FFFFFFFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_EN               (0X80000000U)
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_SHIFT   (10U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_CLRMSK  (0XFFFFFBFFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_EN      (0X00000400U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_SHIFT          (9U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_CLRMSK         (0XFFFFFDFFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_EN             (0X00000200U)
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_SHIFT          (8U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_CLRMSK         (0XFFFFFEFFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_EN             (0X00000100U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_SHIFT          (7U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_CLRMSK         (0XFFFFFF7FU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXE_EN             (0X00000080U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_SHIFT          (6U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_CLRMSK         (0XFFFFFFBFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_VXD_EN             (0X00000040U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_SHIFT    (5U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_CLRMSK   (0XFFFFFFDFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_HOST_META_EN       (0X00000020U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_SHIFT          (4U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_CLRMSK         (0XFFFFFFEFU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_EN             (0X00000010U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_SHIFT      (3U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_CLRMSK     (0XFFFFFFF7U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_EN         (0X00000008U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_SHIFT        (2U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_CLRMSK       (0XFFFFFFFBU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_EN           (0X00000004U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_SHIFT           (1U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_CLRMSK          (0XFFFFFFFDU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_TA_EN              (0X00000002U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_SHIFT             (0U)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_CLRMSK            (0XFFFFFFFEU)
+#define RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN                (0X00000001U)
+
+
+/*
+    Register RGX_CR_SLC_STATUS0
+*/
+#define RGX_CR_SLC_STATUS0                                (0x3820U)
+#define RGX_CR_SLC_STATUS0_MASKFULL                       (IMG_UINT64_C(0x0000000000000007))
+#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_SHIFT      (2U)
+#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_CLRMSK     (0XFFFFFFFBU)
+#define RGX_CR_SLC_STATUS0_FLUSH_INVAL_PENDING_EN         (0X00000004U)
+#define RGX_CR_SLC_STATUS0_INVAL_PENDING_SHIFT            (1U)
+#define RGX_CR_SLC_STATUS0_INVAL_PENDING_CLRMSK           (0XFFFFFFFDU)
+#define RGX_CR_SLC_STATUS0_INVAL_PENDING_EN               (0X00000002U)
+#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_SHIFT            (0U)
+#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_CLRMSK           (0XFFFFFFFEU)
+#define RGX_CR_SLC_STATUS0_FLUSH_PENDING_EN               (0X00000001U)
+
+
+/*
+    Register RGX_CR_SLC_CTRL_BYPASS
+*/
+#define RGX_CR_SLC_CTRL_BYPASS                            (0x3828U)
+#define RGX_CR_SLC_CTRL_BYPASS_MASKFULL                   (IMG_UINT64_C(0x000000000FFFFFFF))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_SHIFT        (27U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_CLRMSK       (0XF7FFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_EN           (0X08000000U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_SHIFT               (26U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_CLRMSK              (0XFBFFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_EN                  (0X04000000U)
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_SHIFT          (25U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_CLRMSK         (0XFDFFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_EN             (0X02000000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_SHIFT              (24U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_CLRMSK             (0XFEFFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_EN                 (0X01000000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_SHIFT             (23U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_CLRMSK            (0XFF7FFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_FBDC_EN                (0X00800000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_SHIFT              (22U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_CLRMSK             (0XFFBFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TLA_EN                 (0X00400000U)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_SHIFT             (21U)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_CLRMSK            (0XFFDFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_N_EN                (0X00200000U)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_SHIFT               (20U)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_CLRMSK              (0XFFEFFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_BYP_CC_EN                  (0X00100000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_SHIFT              (19U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_CLRMSK             (0XFFF7FFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MCU_EN                 (0X00080000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_SHIFT              (18U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_CLRMSK             (0XFFFBFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_PDS_EN                 (0X00040000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_SHIFT              (17U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_CLRMSK             (0XFFFDFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TPF_EN                 (0X00020000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_SHIFT           (16U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_CLRMSK          (0XFFFEFFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_TA_TPC_EN              (0X00010000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SHIFT          (15U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_CLRMSK         (0XFFFF7FFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_OBJ_EN             (0X00008000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_SHIFT              (14U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_CLRMSK             (0XFFFFBFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_USC_EN                 (0X00004000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_SHIFT             (13U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_CLRMSK            (0XFFFFDFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_META_EN                (0X00002000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_SHIFT             (12U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_CLRMSK            (0XFFFFEFFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_HOST_EN                (0X00001000U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_SHIFT           (11U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_CLRMSK          (0XFFFFF7FFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PT_EN              (0X00000800U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_SHIFT           (10U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_CLRMSK          (0XFFFFFBFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PD_EN              (0X00000400U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_SHIFT           (9U)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_CLRMSK          (0XFFFFFDFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_REQ_MMU_PC_EN              (0X00000200U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_SHIFT               (8U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_CLRMSK              (0XFFFFFEFFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_FRC_EN                  (0X00000100U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_SHIFT               (7U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_CLRMSK              (0XFFFFFF7FU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXE_EN                  (0X00000080U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_SHIFT               (6U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_CLRMSK              (0XFFFFFFBFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_VXD_EN                  (0X00000040U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_SHIFT         (5U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_CLRMSK        (0XFFFFFFDFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_HOST_META_EN            (0X00000020U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_SHIFT               (4U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_CLRMSK              (0XFFFFFFEFU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_EN                  (0X00000010U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_SHIFT           (3U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_CLRMSK          (0XFFFFFFF7U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_EN              (0X00000008U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT             (2U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_CLRMSK            (0XFFFFFFFBU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_EN                (0X00000004U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_SHIFT                (1U)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_CLRMSK               (0XFFFFFFFDU)
+#define RGX_CR_SLC_CTRL_BYPASS_DM_TA_EN                   (0X00000002U)
+#define RGX_CR_SLC_CTRL_BYPASS_ALL_SHIFT                  (0U)
+#define RGX_CR_SLC_CTRL_BYPASS_ALL_CLRMSK                 (0XFFFFFFFEU)
+#define RGX_CR_SLC_CTRL_BYPASS_ALL_EN                     (0X00000001U)
+
+
+/*
+    Register RGX_CR_SLC_STATUS1
+*/
+#define RGX_CR_SLC_STATUS1                                (0x3870U)
+#define RGX_CR_SLC_STATUS1_MASKFULL                       (IMG_UINT64_C(0x800003FF03FFFFFF))
+#define RGX_CR_SLC_STATUS1_PAUSED_SHIFT                   (63U)
+#define RGX_CR_SLC_STATUS1_PAUSED_CLRMSK                  (IMG_UINT64_C(0X7FFFFFFFFFFFFFFF))
+#define RGX_CR_SLC_STATUS1_PAUSED_EN                      (IMG_UINT64_C(0X8000000000000000))
+#define RGX_CR_SLC_STATUS1_READS1_SHIFT                   (32U)
+#define RGX_CR_SLC_STATUS1_READS1_CLRMSK                  (IMG_UINT64_C(0XFFFFFC00FFFFFFFF))
+#define RGX_CR_SLC_STATUS1_READS0_SHIFT                   (16U)
+#define RGX_CR_SLC_STATUS1_READS0_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFC00FFFF))
+#define RGX_CR_SLC_STATUS1_READS1_EXT_SHIFT               (8U)
+#define RGX_CR_SLC_STATUS1_READS1_EXT_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFF00FF))
+#define RGX_CR_SLC_STATUS1_READS0_EXT_SHIFT               (0U)
+#define RGX_CR_SLC_STATUS1_READS0_EXT_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFF00))
+
+
+/*
+    Register RGX_CR_SLC_IDLE
+*/
+#define RGX_CR_SLC_IDLE                                   (0x3898U)
+#define RGX_CR_SLC_IDLE_MASKFULL                          (IMG_UINT64_C(0x00000000000000FF))
+#define RGX_CR_SLC_IDLE_IMGBV4_SHIFT                      (7U)
+#define RGX_CR_SLC_IDLE_IMGBV4_CLRMSK                     (0XFFFFFF7FU)
+#define RGX_CR_SLC_IDLE_IMGBV4_EN                         (0X00000080U)
+#define RGX_CR_SLC_IDLE_CACHE_BANKS_SHIFT                 (6U)
+#define RGX_CR_SLC_IDLE_CACHE_BANKS_CLRMSK                (0XFFFFFFBFU)
+#define RGX_CR_SLC_IDLE_CACHE_BANKS_EN                    (0X00000040U)
+#define RGX_CR_SLC_IDLE_RBOFIFO_SHIFT                     (5U)
+#define RGX_CR_SLC_IDLE_RBOFIFO_CLRMSK                    (0XFFFFFFDFU)
+#define RGX_CR_SLC_IDLE_RBOFIFO_EN                        (0X00000020U)
+#define RGX_CR_SLC_IDLE_FRC_CONV_SHIFT                    (4U)
+#define RGX_CR_SLC_IDLE_FRC_CONV_CLRMSK                   (0XFFFFFFEFU)
+#define RGX_CR_SLC_IDLE_FRC_CONV_EN                       (0X00000010U)
+#define RGX_CR_SLC_IDLE_VXE_CONV_SHIFT                    (3U)
+#define RGX_CR_SLC_IDLE_VXE_CONV_CLRMSK                   (0XFFFFFFF7U)
+#define RGX_CR_SLC_IDLE_VXE_CONV_EN                       (0X00000008U)
+#define RGX_CR_SLC_IDLE_VXD_CONV_SHIFT                    (2U)
+#define RGX_CR_SLC_IDLE_VXD_CONV_CLRMSK                   (0XFFFFFFFBU)
+#define RGX_CR_SLC_IDLE_VXD_CONV_EN                       (0X00000004U)
+#define RGX_CR_SLC_IDLE_BIF1_CONV_SHIFT                   (1U)
+#define RGX_CR_SLC_IDLE_BIF1_CONV_CLRMSK                  (0XFFFFFFFDU)
+#define RGX_CR_SLC_IDLE_BIF1_CONV_EN                      (0X00000002U)
+#define RGX_CR_SLC_IDLE_CBAR_SHIFT                        (0U)
+#define RGX_CR_SLC_IDLE_CBAR_CLRMSK                       (0XFFFFFFFEU)
+#define RGX_CR_SLC_IDLE_CBAR_EN                           (0X00000001U)
+
+
+/*
+    Register RGX_CR_SLC_STATUS2
+*/
+#define RGX_CR_SLC_STATUS2                                (0x3908U)
+#define RGX_CR_SLC_STATUS2_MASKFULL                       (IMG_UINT64_C(0x000003FF03FFFFFF))
+#define RGX_CR_SLC_STATUS2_READS3_SHIFT                   (32U)
+#define RGX_CR_SLC_STATUS2_READS3_CLRMSK                  (IMG_UINT64_C(0XFFFFFC00FFFFFFFF))
+#define RGX_CR_SLC_STATUS2_READS2_SHIFT                   (16U)
+#define RGX_CR_SLC_STATUS2_READS2_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFC00FFFF))
+#define RGX_CR_SLC_STATUS2_READS3_EXT_SHIFT               (8U)
+#define RGX_CR_SLC_STATUS2_READS3_EXT_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFF00FF))
+#define RGX_CR_SLC_STATUS2_READS2_EXT_SHIFT               (0U)
+#define RGX_CR_SLC_STATUS2_READS2_EXT_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFF00))
+
+
+/*
+    Register RGX_CR_SLC_CTRL_MISC2
+*/
+#define RGX_CR_SLC_CTRL_MISC2                             (0x3930U)
+#define RGX_CR_SLC_CTRL_MISC2_MASKFULL                    (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SLC_CTRL_MISC2_SCRAMBLE_BITS_SHIFT         (0U)
+#define RGX_CR_SLC_CTRL_MISC2_SCRAMBLE_BITS_CLRMSK        (00000000U)
+
+
+/*
+    Register RGX_CR_SLC_CROSSBAR_LOAD_BALANCE
+*/
+#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE                  (0x3938U)
+#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_MASKFULL         (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_SHIFT     (0U)
+#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_CLRMSK    (0XFFFFFFFEU)
+#define RGX_CR_SLC_CROSSBAR_LOAD_BALANCE_BYPASS_EN        (0X00000001U)
+
+
+/*
+    Register RGX_CR_PERF_TA_PHASE
+*/
+#define RGX_CR_PERF_TA_PHASE                              (0x6008U)
+#define RGX_CR_PERF_TA_PHASE_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_TA_PHASE_COUNT_SHIFT                  (0U)
+#define RGX_CR_PERF_TA_PHASE_COUNT_CLRMSK                 (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_3D_PHASE
+*/
+#define RGX_CR_PERF_3D_PHASE                              (0x6010U)
+#define RGX_CR_PERF_3D_PHASE_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_3D_PHASE_COUNT_SHIFT                  (0U)
+#define RGX_CR_PERF_3D_PHASE_COUNT_CLRMSK                 (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_COMPUTE_PHASE
+*/
+#define RGX_CR_PERF_COMPUTE_PHASE                         (0x6018U)
+#define RGX_CR_PERF_COMPUTE_PHASE_MASKFULL                (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_COMPUTE_PHASE_COUNT_SHIFT             (0U)
+#define RGX_CR_PERF_COMPUTE_PHASE_COUNT_CLRMSK            (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_TA_CYCLE
+*/
+#define RGX_CR_PERF_TA_CYCLE                              (0x6020U)
+#define RGX_CR_PERF_TA_CYCLE_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_TA_CYCLE_COUNT_SHIFT                  (0U)
+#define RGX_CR_PERF_TA_CYCLE_COUNT_CLRMSK                 (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_3D_CYCLE
+*/
+#define RGX_CR_PERF_3D_CYCLE                              (0x6028U)
+#define RGX_CR_PERF_3D_CYCLE_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_3D_CYCLE_COUNT_SHIFT                  (0U)
+#define RGX_CR_PERF_3D_CYCLE_COUNT_CLRMSK                 (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_COMPUTE_CYCLE
+*/
+#define RGX_CR_PERF_COMPUTE_CYCLE                         (0x6030U)
+#define RGX_CR_PERF_COMPUTE_CYCLE_MASKFULL                (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_COMPUTE_CYCLE_COUNT_SHIFT             (0U)
+#define RGX_CR_PERF_COMPUTE_CYCLE_COUNT_CLRMSK            (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_TA_OR_3D_CYCLE
+*/
+#define RGX_CR_PERF_TA_OR_3D_CYCLE                        (0x6038U)
+#define RGX_CR_PERF_TA_OR_3D_CYCLE_MASKFULL               (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_TA_OR_3D_CYCLE_COUNT_SHIFT            (0U)
+#define RGX_CR_PERF_TA_OR_3D_CYCLE_COUNT_CLRMSK           (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_INITIAL_TA_CYCLE
+*/
+#define RGX_CR_PERF_INITIAL_TA_CYCLE                      (0x6040U)
+#define RGX_CR_PERF_INITIAL_TA_CYCLE_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_INITIAL_TA_CYCLE_COUNT_SHIFT          (0U)
+#define RGX_CR_PERF_INITIAL_TA_CYCLE_COUNT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC0_READ_STALL
+*/
+#define RGX_CR_PERF_SLC0_READ_STALL                       (0x60B8U)
+#define RGX_CR_PERF_SLC0_READ_STALL_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC0_READ_STALL_COUNT_SHIFT           (0U)
+#define RGX_CR_PERF_SLC0_READ_STALL_COUNT_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC0_WRITE_STALL
+*/
+#define RGX_CR_PERF_SLC0_WRITE_STALL                      (0x60C0U)
+#define RGX_CR_PERF_SLC0_WRITE_STALL_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC0_WRITE_STALL_COUNT_SHIFT          (0U)
+#define RGX_CR_PERF_SLC0_WRITE_STALL_COUNT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC1_READ_STALL
+*/
+#define RGX_CR_PERF_SLC1_READ_STALL                       (0x60E0U)
+#define RGX_CR_PERF_SLC1_READ_STALL_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC1_READ_STALL_COUNT_SHIFT           (0U)
+#define RGX_CR_PERF_SLC1_READ_STALL_COUNT_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC1_WRITE_STALL
+*/
+#define RGX_CR_PERF_SLC1_WRITE_STALL                      (0x60E8U)
+#define RGX_CR_PERF_SLC1_WRITE_STALL_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC1_WRITE_STALL_COUNT_SHIFT          (0U)
+#define RGX_CR_PERF_SLC1_WRITE_STALL_COUNT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC2_READ_STALL
+*/
+#define RGX_CR_PERF_SLC2_READ_STALL                       (0x6158U)
+#define RGX_CR_PERF_SLC2_READ_STALL_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC2_READ_STALL_COUNT_SHIFT           (0U)
+#define RGX_CR_PERF_SLC2_READ_STALL_COUNT_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC2_WRITE_STALL
+*/
+#define RGX_CR_PERF_SLC2_WRITE_STALL                      (0x6160U)
+#define RGX_CR_PERF_SLC2_WRITE_STALL_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC2_WRITE_STALL_COUNT_SHIFT          (0U)
+#define RGX_CR_PERF_SLC2_WRITE_STALL_COUNT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC3_READ_STALL
+*/
+#define RGX_CR_PERF_SLC3_READ_STALL                       (0x6180U)
+#define RGX_CR_PERF_SLC3_READ_STALL_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC3_READ_STALL_COUNT_SHIFT           (0U)
+#define RGX_CR_PERF_SLC3_READ_STALL_COUNT_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_SLC3_WRITE_STALL
+*/
+#define RGX_CR_PERF_SLC3_WRITE_STALL                      (0x6188U)
+#define RGX_CR_PERF_SLC3_WRITE_STALL_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_SLC3_WRITE_STALL_COUNT_SHIFT          (0U)
+#define RGX_CR_PERF_SLC3_WRITE_STALL_COUNT_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_PERF_3D_SPINUP
+*/
+#define RGX_CR_PERF_3D_SPINUP                             (0x6220U)
+#define RGX_CR_PERF_3D_SPINUP_MASKFULL                    (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PERF_3D_SPINUP_CYCLES_SHIFT                (0U)
+#define RGX_CR_PERF_3D_SPINUP_CYCLES_CLRMSK               (00000000U)
+
+
+/*
+    Register RGX_CR_AXI_ACE_LITE_CONFIGURATION
+*/
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION                 (0x38C0U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_MASKFULL        (IMG_UINT64_C(0x0000001FFFFFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_SHIFT (36U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_CLRMSK (IMG_UINT64_C(0XFFFFFFEFFFFFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_EN (IMG_UINT64_C(0X0000001000000000))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_SHIFT (35U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_CLRMSK (IMG_UINT64_C(0XFFFFFFF7FFFFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITE_EN (IMG_UINT64_C(0X0000000800000000))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_SHIFT (34U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_CLRMSK (IMG_UINT64_C(0XFFFFFFFBFFFFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_READ_EN (IMG_UINT64_C(0X0000000400000000))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT (30U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_CLRMSK (IMG_UINT64_C(0XFFFFFFFC3FFFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT (26U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFC3FFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT (22U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFC3FFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_BARRIER_SHIFT (20U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_BARRIER_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_BARRIER_SHIFT (18U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_BARRIER_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT (16U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT (14U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFF3FFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT (12U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT (10U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT (8U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_NON_SNOOPING_SHIFT (4U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFF0F))
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_NON_SNOOPING_SHIFT (0U)
+#define RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_NON_SNOOPING_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFF0))
+
+
+/*
+    Register RGX_CR_POWER_ESTIMATE_RESULT
+*/
+#define RGX_CR_POWER_ESTIMATE_RESULT                      (0x6328U)
+#define RGX_CR_POWER_ESTIMATE_RESULT_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_POWER_ESTIMATE_RESULT_VALUE_SHIFT          (0U)
+#define RGX_CR_POWER_ESTIMATE_RESULT_VALUE_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_OCP_REVINFO
+*/
+#define RGX_CR_OCP_REVINFO                                (0x9000U)
+#define RGX_CR_OCP_REVINFO_MASKFULL                       (IMG_UINT64_C(0x00000007FFFFFFFF))
+#define RGX_CR_OCP_REVINFO_HWINFO_SYSBUS_SHIFT            (33U)
+#define RGX_CR_OCP_REVINFO_HWINFO_SYSBUS_CLRMSK           (IMG_UINT64_C(0XFFFFFFF9FFFFFFFF))
+#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_SHIFT            (32U)
+#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_CLRMSK           (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_OCP_REVINFO_HWINFO_MEMBUS_EN               (IMG_UINT64_C(0X0000000100000000))
+#define RGX_CR_OCP_REVINFO_REVISION_SHIFT                 (0U)
+#define RGX_CR_OCP_REVINFO_REVISION_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
+    Register RGX_CR_OCP_SYSCONFIG
+*/
+#define RGX_CR_OCP_SYSCONFIG                              (0x9010U)
+#define RGX_CR_OCP_SYSCONFIG_MASKFULL                     (IMG_UINT64_C(0x0000000000000FFF))
+#define RGX_CR_OCP_SYSCONFIG_DUST2_STANDBY_MODE_SHIFT     (10U)
+#define RGX_CR_OCP_SYSCONFIG_DUST2_STANDBY_MODE_CLRMSK    (0XFFFFF3FFU)
+#define RGX_CR_OCP_SYSCONFIG_DUST1_STANDBY_MODE_SHIFT     (8U)
+#define RGX_CR_OCP_SYSCONFIG_DUST1_STANDBY_MODE_CLRMSK    (0XFFFFFCFFU)
+#define RGX_CR_OCP_SYSCONFIG_DUST0_STANDBY_MODE_SHIFT     (6U)
+#define RGX_CR_OCP_SYSCONFIG_DUST0_STANDBY_MODE_CLRMSK    (0XFFFFFF3FU)
+#define RGX_CR_OCP_SYSCONFIG_RASCAL_STANDBYMODE_SHIFT     (4U)
+#define RGX_CR_OCP_SYSCONFIG_RASCAL_STANDBYMODE_CLRMSK    (0XFFFFFFCFU)
+#define RGX_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT           (2U)
+#define RGX_CR_OCP_SYSCONFIG_STANDBY_MODE_CLRMSK          (0XFFFFFFF3U)
+#define RGX_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT              (0U)
+#define RGX_CR_OCP_SYSCONFIG_IDLE_MODE_CLRMSK             (0XFFFFFFFCU)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_RAW_0
+*/
+#define RGX_CR_OCP_IRQSTATUS_RAW_0                        (0x9020U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_0_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_SHIFT (0U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_RAW_0_INIT_MINTERRUPT_RAW_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_RAW_1
+*/
+#define RGX_CR_OCP_IRQSTATUS_RAW_1                        (0x9028U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_1_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_SHIFT (0U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_RAW_1_TARGET_SINTERRUPT_RAW_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_RAW_2
+*/
+#define RGX_CR_OCP_IRQSTATUS_RAW_2                        (0x9030U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_2_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_SHIFT      (0U)
+#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_CLRMSK     (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_RAW_2_RGX_IRQ_RAW_EN         (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_0
+*/
+#define RGX_CR_OCP_IRQSTATUS_0                            (0x9038U)
+#define RGX_CR_OCP_IRQSTATUS_0_MASKFULL                   (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_SHIFT (0U)
+#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_0_INIT_MINTERRUPT_STATUS_EN  (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_1
+*/
+#define RGX_CR_OCP_IRQSTATUS_1                            (0x9040U)
+#define RGX_CR_OCP_IRQSTATUS_1_MASKFULL                   (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_SHIFT (0U)
+#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_1_TARGET_SINTERRUPT_STATUS_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQSTATUS_2
+*/
+#define RGX_CR_OCP_IRQSTATUS_2                            (0x9048U)
+#define RGX_CR_OCP_IRQSTATUS_2_MASKFULL                   (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_SHIFT       (0U)
+#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_CLRMSK      (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_EN          (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_SET_0
+*/
+#define RGX_CR_OCP_IRQENABLE_SET_0                        (0x9050U)
+#define RGX_CR_OCP_IRQENABLE_SET_0_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_SHIFT (0U)
+#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_SET_0_INIT_MINTERRUPT_ENABLE_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_SET_1
+*/
+#define RGX_CR_OCP_IRQENABLE_SET_1                        (0x9058U)
+#define RGX_CR_OCP_IRQENABLE_SET_1_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_SHIFT (0U)
+#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_SET_1_TARGET_SINTERRUPT_ENABLE_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_SET_2
+*/
+#define RGX_CR_OCP_IRQENABLE_SET_2                        (0x9060U)
+#define RGX_CR_OCP_IRQENABLE_SET_2_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_SHIFT   (0U)
+#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_CLRMSK  (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_SET_2_RGX_IRQ_ENABLE_EN      (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_CLR_0
+*/
+#define RGX_CR_OCP_IRQENABLE_CLR_0                        (0x9068U)
+#define RGX_CR_OCP_IRQENABLE_CLR_0_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_SHIFT (0U)
+#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_CLR_0_INIT_MINTERRUPT_DISABLE_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_CLR_1
+*/
+#define RGX_CR_OCP_IRQENABLE_CLR_1                        (0x9070U)
+#define RGX_CR_OCP_IRQENABLE_CLR_1_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_SHIFT (0U)
+#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_CLR_1_TARGET_SINTERRUPT_DISABLE_EN (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQENABLE_CLR_2
+*/
+#define RGX_CR_OCP_IRQENABLE_CLR_2                        (0x9078U)
+#define RGX_CR_OCP_IRQENABLE_CLR_2_MASKFULL               (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_SHIFT  (0U)
+#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_CLRMSK (0XFFFFFFFEU)
+#define RGX_CR_OCP_IRQENABLE_CLR_2_RGX_IRQ_DISABLE_EN     (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_IRQ_EVENT
+*/
+#define RGX_CR_OCP_IRQ_EVENT                              (0x9080U)
+#define RGX_CR_OCP_IRQ_EVENT_MASKFULL                     (IMG_UINT64_C(0x00000000000FFFFF))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_SHIFT (19U)
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFF7FFFF))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNEXPECTED_RDATA_EN (IMG_UINT64_C(0X0000000000080000))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_SHIFT (18U)
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFBFFFF))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETH_RCVD_UNSUPPORTED_MCMD_EN (IMG_UINT64_C(0X0000000000040000))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_SHIFT (17U)
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFDFFFF))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNEXPECTED_RDATA_EN (IMG_UINT64_C(0X0000000000020000))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_SHIFT (16U)
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFEFFFF))
+#define RGX_CR_OCP_IRQ_EVENT_TARGETS_RCVD_UNSUPPORTED_MCMD_EN (IMG_UINT64_C(0X0000000000010000))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_SHIFT (15U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFF7FFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0X0000000000008000))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_SHIFT (14U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_RESP_ERR_FAIL_EN  (IMG_UINT64_C(0X0000000000004000))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_SHIFT (13U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RCVD_UNUSED_TAGID_EN   (IMG_UINT64_C(0X0000000000002000))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_SHIFT (12U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT3_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0X0000000000001000))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_SHIFT (11U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFF7FF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0X0000000000000800))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_SHIFT (10U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_RESP_ERR_FAIL_EN  (IMG_UINT64_C(0X0000000000000400))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_SHIFT (9U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RCVD_UNUSED_TAGID_EN   (IMG_UINT64_C(0X0000000000000200))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_SHIFT (8U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT2_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0X0000000000000100))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_SHIFT (7U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0X0000000000000080))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_SHIFT (6U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_RESP_ERR_FAIL_EN  (IMG_UINT64_C(0X0000000000000040))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_SHIFT (5U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RCVD_UNUSED_TAGID_EN   (IMG_UINT64_C(0X0000000000000020))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_SHIFT (4U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_OCP_IRQ_EVENT_INIT1_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0X0000000000000010))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_SHIFT (3U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_IMG_PAGE_BOUNDARY_CROSS_EN (IMG_UINT64_C(0X0000000000000008))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_SHIFT (2U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_RESP_ERR_FAIL_EN  (IMG_UINT64_C(0X0000000000000004))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_SHIFT (1U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RCVD_UNUSED_TAGID_EN   (IMG_UINT64_C(0X0000000000000002))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_SHIFT (0U)
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_OCP_IRQ_EVENT_INIT0_RDATA_FIFO_OVERFILL_EN (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_OCP_DEBUG_CONFIG
+*/
+#define RGX_CR_OCP_DEBUG_CONFIG                           (0x9088U)
+#define RGX_CR_OCP_DEBUG_CONFIG_MASKFULL                  (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_OCP_DEBUG_CONFIG_REG_SHIFT                 (0U)
+#define RGX_CR_OCP_DEBUG_CONFIG_REG_CLRMSK                (0XFFFFFFFEU)
+#define RGX_CR_OCP_DEBUG_CONFIG_REG_EN                    (0X00000001U)
+
+
+/*
+    Register RGX_CR_OCP_DEBUG_STATUS
+*/
+#define RGX_CR_OCP_DEBUG_STATUS                           (0x9090U)
+#define RGX_CR_OCP_DEBUG_STATUS_MASKFULL                  (IMG_UINT64_C(0x001F1F77FFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SDISCACK_SHIFT    (51U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SDISCACK_CLRMSK   (IMG_UINT64_C(0XFFE7FFFFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_SHIFT    (50U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_CLRMSK   (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SCONNECT_EN       (IMG_UINT64_C(0X0004000000000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_MCONNECT_SHIFT    (48U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_MCONNECT_CLRMSK   (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SDISCACK_SHIFT    (43U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SDISCACK_CLRMSK   (IMG_UINT64_C(0XFFFFE7FFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_SHIFT    (42U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_CLRMSK   (IMG_UINT64_C(0XFFFFFBFFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SCONNECT_EN       (IMG_UINT64_C(0X0000040000000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_MCONNECT_SHIFT    (40U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_MCONNECT_CLRMSK   (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_SHIFT        (38U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_CLRMSK       (IMG_UINT64_C(0XFFFFFFBFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_BUSY_EN           (IMG_UINT64_C(0X0000004000000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_SHIFT (37U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_CLRMSK (IMG_UINT64_C(0XFFFFFFDFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_CMD_FIFO_FULL_EN  (IMG_UINT64_C(0X0000002000000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_SHIFT (36U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_CLRMSK (IMG_UINT64_C(0XFFFFFFEFFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETH_SRESP_ERROR_EN    (IMG_UINT64_C(0X0000001000000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_SHIFT        (34U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_CLRMSK       (IMG_UINT64_C(0XFFFFFFFBFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_BUSY_EN           (IMG_UINT64_C(0X0000000400000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_SHIFT (33U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_CLRMSK (IMG_UINT64_C(0XFFFFFFFDFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_CMD_FIFO_FULL_EN  (IMG_UINT64_C(0X0000000200000000))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_SHIFT (32U)
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_CLRMSK (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_TARGETS_SRESP_ERROR_EN    (IMG_UINT64_C(0X0000000100000000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_SHIFT      (31U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_CLRMSK     (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_RESERVED_EN         (IMG_UINT64_C(0X0000000080000000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_SHIFT         (30U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SWAIT_EN            (IMG_UINT64_C(0X0000000040000000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_SHIFT      (29U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCREQ_EN         (IMG_UINT64_C(0X0000000020000000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCACK_SHIFT      (27U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MDISCACK_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFE7FFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_SHIFT      (26U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_SCONNECT_EN         (IMG_UINT64_C(0X0000000004000000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MCONNECT_SHIFT      (24U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT3_MCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_SHIFT      (23U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_RESERVED_EN         (IMG_UINT64_C(0X0000000000800000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_SHIFT         (22U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SWAIT_EN            (IMG_UINT64_C(0X0000000000400000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_SHIFT      (21U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCREQ_EN         (IMG_UINT64_C(0X0000000000200000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCACK_SHIFT      (19U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MDISCACK_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFE7FFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_SHIFT      (18U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFBFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_SCONNECT_EN         (IMG_UINT64_C(0X0000000000040000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MCONNECT_SHIFT      (16U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT2_MCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_SHIFT      (15U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFF7FFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_RESERVED_EN         (IMG_UINT64_C(0X0000000000008000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_SHIFT         (14U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SWAIT_EN            (IMG_UINT64_C(0X0000000000004000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_SHIFT      (13U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCREQ_EN         (IMG_UINT64_C(0X0000000000002000))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCACK_SHIFT      (11U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MDISCACK_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFE7FF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_SHIFT      (10U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_SCONNECT_EN         (IMG_UINT64_C(0X0000000000000400))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MCONNECT_SHIFT      (8U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT1_MCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_SHIFT      (7U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_RESERVED_EN         (IMG_UINT64_C(0X0000000000000080))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_SHIFT         (6U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SWAIT_EN            (IMG_UINT64_C(0X0000000000000040))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_SHIFT      (5U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCREQ_EN         (IMG_UINT64_C(0X0000000000000020))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCACK_SHIFT      (3U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MDISCACK_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFFE7))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_SHIFT      (2U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_SCONNECT_EN         (IMG_UINT64_C(0X0000000000000004))
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MCONNECT_SHIFT      (0U)
+#define RGX_CR_OCP_DEBUG_STATUS_INIT0_MCONNECT_CLRMSK     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+
+
+#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_SHIFT           (6U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_CLRMSK          (0XFFFFFFBFU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PM_ALIST_EN              (0X00000040U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_SHIFT               (5U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_CLRMSK              (0XFFFFFFDFU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_HOST_EN                  (0X00000020U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_META_SHIFT               (4U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_META_CLRMSK              (0XFFFFFFEFU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_META_EN                  (0X00000010U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_SHIFT             (3U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_CLRMSK            (0XFFFFFFF7U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_ZLS_EN                (0X00000008U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_SHIFT              (2U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_CLRMSK             (0XFFFFFFFBU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_TE_EN                 (0X00000004U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_SHIFT             (1U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_CLRMSK            (0XFFFFFFFDU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_PB_VCE_EN                (0X00000002U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_SHIFT                (0U)
+#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_CLRMSK               (0XFFFFFFFEU)
+#define RGX_CR_BIF_TRUST_DM_TYPE_TLA_EN                   (0X00000001U)
+
+
+#define RGX_CR_BIF_TRUST_DM_MASK                          (0x0000007FU)
+
+
+/*
+    Register RGX_CR_BIF_TRUST
+*/
+#define RGX_CR_BIF_TRUST                                  (0xA000U)
+#define RGX_CR_BIF_TRUST_MASKFULL                         (IMG_UINT64_C(0x00000000001FFFFF))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_SHIFT (20U)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_CLRMSK (0XFFEFFFFFU)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_EN   (0X00100000U)
+#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_SHIFT  (19U)
+#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_CLRMSK (0XFFF7FFFFU)
+#define RGX_CR_BIF_TRUST_MCU_RAY_VERTEX_DM_TRUSTED_EN     (0X00080000U)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_SHIFT       (18U)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_CLRMSK      (0XFFFBFFFFU)
+#define RGX_CR_BIF_TRUST_OTHER_RAY_DM_TRUSTED_EN          (0X00040000U)
+#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_SHIFT         (17U)
+#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_CLRMSK        (0XFFFDFFFFU)
+#define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_EN            (0X00020000U)
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+#define RGX_CR_BIF_TRUST_ENABLE_SHIFT                     (16U)
+#define RGX_CR_BIF_TRUST_ENABLE_CLRMSK                    (0XFFFEFFFFU)
+#define RGX_CR_BIF_TRUST_ENABLE_EN                        (0X00010000U)
+#define RGX_CR_BIF_TRUST_DM_TRUSTED_SHIFT                 (9U)
+#define RGX_CR_BIF_TRUST_DM_TRUSTED_CLRMSK                (0XFFFF01FFU)
+#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_SHIFT   (8U)
+#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_CLRMSK  (0XFFFFFEFFU)
+#define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_EN      (0X00000100U)
+#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_SHIFT     (7U)
+#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_CLRMSK    (0XFFFFFF7FU)
+#define RGX_CR_BIF_TRUST_MCU_COMPUTE_DM_TRUSTED_EN        (0X00000080U)
+#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_SHIFT     (6U)
+#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_CLRMSK    (0XFFFFFFBFU)
+#define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_EN        (0X00000040U)
+#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_SHIFT     (5U)
+#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_CLRMSK    (0XFFFFFFDFU)
+#define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_EN        (0X00000020U)
+#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_SHIFT       (4U)
+#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_CLRMSK      (0XFFFFFFEFU)
+#define RGX_CR_BIF_TRUST_MCU_PIXEL_DM_TRUSTED_EN          (0X00000010U)
+#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_SHIFT       (3U)
+#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_CLRMSK      (0XFFFFFFF7U)
+#define RGX_CR_BIF_TRUST_PBE_PIXEL_DM_TRUSTED_EN          (0X00000008U)
+#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_SHIFT    (2U)
+#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_CLRMSK   (0XFFFFFFFBU)
+#define RGX_CR_BIF_TRUST_OTHER_VERTEX_DM_TRUSTED_EN       (0X00000004U)
+#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_SHIFT      (1U)
+#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_CLRMSK     (0XFFFFFFFDU)
+#define RGX_CR_BIF_TRUST_MCU_VERTEX_DM_TRUSTED_EN         (0X00000002U)
+#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_SHIFT      (0U)
+#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_CLRMSK     (0XFFFFFFFEU)
+#define RGX_CR_BIF_TRUST_PBE_VERTEX_DM_TRUSTED_EN         (0X00000001U)
+
+
+/*
+    Register RGX_CR_SYS_BUS_SECURE
+*/
+#define RGX_CR_SYS_BUS_SECURE                             (0xA100U)
+#define RGX_CR_SYS_BUS_SECURE_MASKFULL                    (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_SYS_BUS_SECURE_ENABLE_SHIFT                (0U)
+#define RGX_CR_SYS_BUS_SECURE_ENABLE_CLRMSK               (0XFFFFFFFEU)
+#define RGX_CR_SYS_BUS_SECURE_ENABLE_EN                   (0X00000001U)
+
+
+/*
+    Register RGX_CR_CLK_CTRL2
+*/
+#define RGX_CR_CLK_CTRL2                                  (0xD200U)
+#define RGX_CR_CLK_CTRL2_MASKFULL                         (IMG_UINT64_C(0x0000000000000F33))
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_SHIFT                   (10U)
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_OFF                     (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_ON                      (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_AUTO                    (IMG_UINT64_C(0x0000000000000800))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_CLK_CTRL2_VRDM_SHIFT                       (8U)
+#define RGX_CR_CLK_CTRL2_VRDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
+#define RGX_CR_CLK_CTRL2_VRDM_OFF                         (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL2_VRDM_ON                          (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_CTRL2_VRDM_AUTO                        (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_CTRL2_SH_SHIFT                         (4U)
+#define RGX_CR_CLK_CTRL2_SH_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
+#define RGX_CR_CLK_CTRL2_SH_OFF                           (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL2_SH_ON                            (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_CTRL2_SH_AUTO                          (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_CTRL2_FBA_SHIFT                        (0U)
+#define RGX_CR_CLK_CTRL2_FBA_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
+#define RGX_CR_CLK_CTRL2_FBA_OFF                          (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_CTRL2_FBA_ON                           (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_CTRL2_FBA_AUTO                         (IMG_UINT64_C(0x0000000000000002))
+
+
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+/*
+    Register RGX_CR_CLK_STATUS2
+*/
+#define RGX_CR_CLK_STATUS2                                (0xD208U)
+#define RGX_CR_CLK_STATUS2_MASKFULL                       (IMG_UINT64_C(0x0000000000000015))
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_CLK_STATUS2_VRDM_SHIFT                     (4U)
+#define RGX_CR_CLK_STATUS2_VRDM_CLRMSK                    (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_CR_CLK_STATUS2_VRDM_GATED                     (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS2_VRDM_RUNNING                   (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_STATUS2_SH_SHIFT                       (2U)
+#define RGX_CR_CLK_STATUS2_SH_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_CR_CLK_STATUS2_SH_GATED                       (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS2_SH_RUNNING                     (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_STATUS2_FBA_SHIFT                      (0U)
+#define RGX_CR_CLK_STATUS2_FBA_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_CLK_STATUS2_FBA_GATED                      (IMG_UINT64_C(0000000000000000))
+#define RGX_CR_CLK_STATUS2_FBA_RUNNING                    (IMG_UINT64_C(0x0000000000000001))
+
+
+/*
+    Register DPX_CR_BIF_FAULT_BANK_MMU_STATUS
+*/
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS                  (0xC5C8U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_MASKFULL         (IMG_UINT64_C(0x000000000000F775))
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_CAT_BASE_SHIFT   (12U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_CAT_BASE_CLRMSK  (0XFFFF0FFFU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_PAGE_SIZE_SHIFT  (8U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_PAGE_SIZE_CLRMSK (0XFFFFF8FFU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_DATA_TYPE_SHIFT  (5U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_DATA_TYPE_CLRMSK (0XFFFFFF9FU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_SHIFT   (4U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_CLRMSK  (0XFFFFFFEFU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_RO_EN      (0X00000010U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_SHIFT (2U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_CLRMSK (0XFFFFFFFBU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_PM_META_RO_EN (0X00000004U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_SHIFT      (0U)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_CLRMSK     (0XFFFFFFFEU)
+#define DPX_CR_BIF_FAULT_BANK_MMU_STATUS_FAULT_EN         (0X00000001U)
+
+
+/*
+    Register DPX_CR_BIF_FAULT_BANK_REQ_STATUS
+*/
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS                  (0xC5D0U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_MASKFULL         (IMG_UINT64_C(0x03FFFFFFFFFFFFF0))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_SHIFT        (57U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_CLRMSK       (IMG_UINT64_C(0XFDFFFFFFFFFFFFFF))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_EN           (IMG_UINT64_C(0X0200000000000000))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_SB_SHIFT     (44U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_SB_CLRMSK    (IMG_UINT64_C(0XFE000FFFFFFFFFFF))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_ID_SHIFT     (40U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_TAG_ID_CLRMSK    (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_SHIFT    (4U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_CLRMSK   (IMG_UINT64_C(0XFFFFFF000000000F))
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_ALIGNSHIFT (4U)
+#define DPX_CR_BIF_FAULT_BANK_REQ_STATUS_ADDRESS_ALIGNSIZE (16U)
+
+
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+/*
+    Register RGX_CR_MMU_FAULT_STATUS
+*/
+#define RGX_CR_MMU_FAULT_STATUS                           (0xE150U)
+#define RGX_CR_MMU_FAULT_STATUS_MASKFULL                  (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT             (28U)
+#define RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK            (IMG_UINT64_C(0X000000000FFFFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT             (20U)
+#define RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFF00FFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT              (12U)
+#define RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFF00FFF))
+#define RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT              (6U)
+#define RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFFFF03F))
+#define RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT               (4U)
+#define RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
+#define RGX_CR_MMU_FAULT_STATUS_RNW_SHIFT                 (3U)
+#define RGX_CR_MMU_FAULT_STATUS_RNW_CLRMSK                (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_MMU_FAULT_STATUS_RNW_EN                    (IMG_UINT64_C(0X0000000000000008))
+#define RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT                (1U)
+#define RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFFF9))
+#define RGX_CR_MMU_FAULT_STATUS_FAULT_SHIFT               (0U)
+#define RGX_CR_MMU_FAULT_STATUS_FAULT_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MMU_FAULT_STATUS_FAULT_EN                  (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_MMU_FAULT_STATUS_META
+*/
+#define RGX_CR_MMU_FAULT_STATUS_META                      (0xE158U)
+#define RGX_CR_MMU_FAULT_STATUS_META_MASKFULL             (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_SHIFT        (28U)
+#define RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_CLRMSK       (IMG_UINT64_C(0X000000000FFFFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_SHIFT        (20U)
+#define RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_CLRMSK       (IMG_UINT64_C(0XFFFFFFFFF00FFFFF))
+#define RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_SHIFT         (12U)
+#define RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFF00FFF))
+#define RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_SHIFT         (6U)
+#define RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFF03F))
+#define RGX_CR_MMU_FAULT_STATUS_META_LEVEL_SHIFT          (4U)
+#define RGX_CR_MMU_FAULT_STATUS_META_LEVEL_CLRMSK         (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
+#define RGX_CR_MMU_FAULT_STATUS_META_RNW_SHIFT            (3U)
+#define RGX_CR_MMU_FAULT_STATUS_META_RNW_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_CR_MMU_FAULT_STATUS_META_RNW_EN               (IMG_UINT64_C(0X0000000000000008))
+#define RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT           (1U)
+#define RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFF9))
+#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_SHIFT          (0U)
+#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_CLRMSK         (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MMU_FAULT_STATUS_META_FAULT_EN             (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_SLC3_CTRL_MISC
+*/
+#define RGX_CR_SLC3_CTRL_MISC                             (0xE200U)
+#define RGX_CR_SLC3_CTRL_MISC_MASKFULL                    (IMG_UINT64_C(0x0000000000000007))
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SHIFT      (0U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_CLRMSK     (0XFFFFFFF8U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_LINEAR     (00000000U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_IN_PAGE_HASH (0X00000001U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_FIXED_PVR_HASH (0X00000002U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SCRAMBLE_PVR_HASH (0X00000003U)
+#define RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_WEAVED_HASH (0X00000004U)
+
+
+/*
+    Register RGX_CR_SLC3_SCRAMBLE
+*/
+#define RGX_CR_SLC3_SCRAMBLE                              (0xE208U)
+#define RGX_CR_SLC3_SCRAMBLE_MASKFULL                     (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_SLC3_SCRAMBLE_BITS_SHIFT                   (0U)
+#define RGX_CR_SLC3_SCRAMBLE_BITS_CLRMSK                  (IMG_UINT64_C(0000000000000000))
+
+
+/*
+    Register RGX_CR_SLC3_SCRAMBLE2
+*/
+#define RGX_CR_SLC3_SCRAMBLE2                             (0xE210U)
+#define RGX_CR_SLC3_SCRAMBLE2_MASKFULL                    (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_SLC3_SCRAMBLE2_BITS_SHIFT                  (0U)
+#define RGX_CR_SLC3_SCRAMBLE2_BITS_CLRMSK                 (IMG_UINT64_C(0000000000000000))
+
+
+/*
+    Register RGX_CR_SLC3_SCRAMBLE3
+*/
+#define RGX_CR_SLC3_SCRAMBLE3                             (0xE218U)
+#define RGX_CR_SLC3_SCRAMBLE3_MASKFULL                    (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_SLC3_SCRAMBLE3_BITS_SHIFT                  (0U)
+#define RGX_CR_SLC3_SCRAMBLE3_BITS_CLRMSK                 (IMG_UINT64_C(0000000000000000))
+
+
+/*
+    Register RGX_CR_SLC3_SCRAMBLE4
+*/
+#define RGX_CR_SLC3_SCRAMBLE4                             (0xE260U)
+#define RGX_CR_SLC3_SCRAMBLE4_MASKFULL                    (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_SLC3_SCRAMBLE4_BITS_SHIFT                  (0U)
+#define RGX_CR_SLC3_SCRAMBLE4_BITS_CLRMSK                 (IMG_UINT64_C(0000000000000000))
+
+
+#endif /* _RGX_CR_DEFS_KM_H_ */
+
+/*****************************************************************************
+ End of file (rgx_cr_defs_km.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/hwdefs/km/rgxdefs_km.h b/drivers/gpu/rogue_m/hwdefs/km/rgxdefs_km.h
new file mode 100644 (file)
index 0000000..83151cf
--- /dev/null
@@ -0,0 +1,175 @@
+/*************************************************************************/ /*!
+@Title          Rogue hw definitions (kernel mode)
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGXDEFS_KM_H_
+#define _RGXDEFS_KM_H_
+
+#include RGX_BVNC_CORE_KM_HEADER
+#include RGX_BNC_CONFIG_KM_HEADER
+
+#define __IMG_EXPLICIT_INCLUDE_HWDEFS
+#include "rgx_cr_defs_km.h"
+#undef __IMG_EXPLICIT_INCLUDE_HWDEFS
+
+/******************************************************************************
+ * Check for valid B.X.N.C
+ *****************************************************************************/
+#if !defined(RGX_BVNC_KM_B) || !defined(RGX_BVNC_KM_V) || !defined(RGX_BVNC_KM_N) || !defined(RGX_BVNC_KM_C)
+#error "Need to specify BVNC (RGX_BVNC_KM_B, RGX_BVNC_KM_V, RGX_BVNC_KM_N and RGX_BVNC_C)"
+#endif
+
+/* Check core/config compatibility */
+#if (RGX_BVNC_KM_B != RGX_BNC_KM_B) || (RGX_BVNC_KM_N != RGX_BNC_KM_N) || (RGX_BVNC_KM_C != RGX_BNC_KM_C) 
+#error "BVNC headers are mismatching (KM core/config)"
+#endif
+
+/******************************************************************************
+ * RGX Version name
+ *****************************************************************************/
+#define _RGX_BVNC_ST2(S)       #S
+#define _RGX_BVNC_ST(S)                _RGX_BVNC_ST2(S)
+#define RGX_BVNC_KM                    _RGX_BVNC_ST(RGX_BVNC_KM_B) "." _RGX_BVNC_ST(RGX_BVNC_KM_V) "." _RGX_BVNC_ST(RGX_BVNC_KM_N) "." _RGX_BVNC_ST(RGX_BVNC_KM_C)
+#define RGX_BVNC_KM_V_ST       _RGX_BVNC_ST(RGX_BVNC_KM_V)
+
+/******************************************************************************
+ * RGX Defines
+ *****************************************************************************/
+
+/* META cores (required for the RGX_FEATURE_META) */
+#define MTP218   (1)
+#define MTP219   (2)
+#define LTP218   (3)
+#define LTP217   (4)
+
+/* META Core memory feature depending on META variants */
+#define RGX_META_COREMEM_32K      (32*1024)
+#define RGX_META_COREMEM_48K      (48*1024)
+#define RGX_META_COREMEM_64K      (64*1024)
+
+#define RGX_META_COREMEM_SIZE     (RGX_FEATURE_META_COREMEM_SIZE*1024)
+
+#if (RGX_FEATURE_META_COREMEM_SIZE != 0)
+#define RGX_META_COREMEM          (1)
+#define RGX_META_COREMEM_CODE     (1)
+#if !defined(FIX_HW_BRN_50767)
+#define RGX_META_COREMEM_DATA     (1)
+#endif
+#endif
+
+/* ISP requires valid state on all three pipes regardless of the number of
+ * active pipes/tiles in flight.
+ */
+#define RGX_MAX_NUM_PIPES      3
+
+#define ROGUE_CACHE_LINE_SIZE                          ((RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS)/8)
+
+#define MAX_HW_TA3DCONTEXTS    2
+
+
+/* useful extra defines for clock ctrl*/
+#define RGX_CR_CLK_CTRL_ALL_ON   (IMG_UINT64_C(0x5555555555555555)&RGX_CR_CLK_CTRL_MASKFULL)
+#define RGX_CR_CLK_CTRL_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&RGX_CR_CLK_CTRL_MASKFULL)
+
+#define RGX_CR_SOFT_RESET_DUST_n_CORE_EN       (RGX_CR_SOFT_RESET_DUST_A_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_B_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_C_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_D_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_E_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_F_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_G_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_H_CORE_EN)
+
+/* SOFT_RESET Rascal and DUSTs bits */
+#define RGX_CR_SOFT_RESET_RASCALDUSTS_EN       (RGX_CR_SOFT_RESET_RASCAL_CORE_EN | \
+                                                                                        RGX_CR_SOFT_RESET_DUST_n_CORE_EN)
+
+
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/* SOFT_RESET steps as defined in the TRM */
+#define RGX_S7_SOFT_RESET_DUSTS (RGX_CR_SOFT_RESET_DUST_n_CORE_EN)
+
+#define RGX_S7_SOFT_RESET_JONES (RGX_CR_SOFT_RESET_PM_EN  | \
+                                 RGX_CR_SOFT_RESET_VDM_EN | \
+                                                                RGX_CR_SOFT_RESET_ISP_EN)
+
+#define RGX_S7_SOFT_RESET_JONES_ALL (RGX_S7_SOFT_RESET_JONES  | \
+                                                                        RGX_CR_SOFT_RESET_BIF_EN | \
+                                     RGX_CR_SOFT_RESET_SLC_EN | \
+                                                                    RGX_CR_SOFT_RESET_GARTEN_EN)
+
+#define RGX_S7_SOFT_RESET2 (RGX_CR_SOFT_RESET2_BLACKPEARL_EN | \
+                            RGX_CR_SOFT_RESET2_PIXEL_EN | \
+                                                       RGX_CR_SOFT_RESET2_COMPUTE_EN | \
+                                                       RGX_CR_SOFT_RESET2_VERTEX_EN)
+#endif
+
+
+#define RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT            (12)
+#define RGX_BIF_PM_PHYSICAL_PAGE_SIZE                  (1 << RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT)
+
+#define RGX_BIF_PM_VIRTUAL_PAGE_ALIGNSHIFT             (14)
+#define RGX_BIF_PM_VIRTUAL_PAGE_SIZE                   (1 << RGX_BIF_PM_VIRTUAL_PAGE_ALIGNSHIFT)
+
+/******************************************************************************
+ * WA HWBRNs
+ *****************************************************************************/
+#if defined(FIX_HW_BRN_36492)
+
+#undef RGX_CR_SOFT_RESET_SLC_EN
+#undef RGX_CR_SOFT_RESET_SLC_CLRMSK
+#undef RGX_CR_SOFT_RESET_SLC_SHIFT
+
+/* Remove the SOFT_RESET_SLC_EN bit from SOFT_RESET_MASKFULL */
+#undef RGX_CR_SOFT_RESET_MASKFULL 
+#define RGX_CR_SOFT_RESET_MASKFULL IMG_UINT64_C(0x000001FFF7FFFC1D)
+
+#endif /* FIX_HW_BRN_36492 */
+
+#define DPX_MAX_RAY_CONTEXTS 4 /* FIXME should this be in dpx file? */
+#define DPX_MAX_FBA_AP 16
+#define DPX_MAX_FBA_FILTER_WIDTH 24
+
+#if !defined(RGX_FEATURE_SLC_SIZE_IN_BYTES)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (RGX_FEATURE_SLC_SIZE_IN_KILOBYTES * 1024)
+#endif
+
+#endif /* _RGXDEFS_KM_H_ */
diff --git a/drivers/gpu/rogue_m/hwdefs/km/rgxmmudefs_km.h b/drivers/gpu/rogue_m/hwdefs/km/rgxmmudefs_km.h
new file mode 100644 (file)
index 0000000..7419db5
--- /dev/null
@@ -0,0 +1,395 @@
+/*************************************************************************/ /*!
+@Title          Hardware definition file rgxmmudefs_km.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/*               ****   Autogenerated C -- do not edit    ****               */
+
+/*
+ * Generated by regconv version MAIN@2782796
+ *   from files:
+ *      rogue_bif.def 
+ *      rogue_bif.def 
+ */
+
+
+#ifndef _RGXMMUDEFS_KM_H_
+#define _RGXMMUDEFS_KM_H_
+
+#include "img_types.h"
+
+/*
+
+               Encoding of DM (note value 0x6 not used)
+       
+*/
+#define RGX_BIF_DM_ENCODING_VERTEX                        (0x00000000U)
+#define RGX_BIF_DM_ENCODING_PIXEL                         (0x00000001U)
+#define RGX_BIF_DM_ENCODING_COMPUTE                       (0x00000002U)
+#define RGX_BIF_DM_ENCODING_TLA                           (0x00000003U)
+#define RGX_BIF_DM_ENCODING_PB_VCE                        (0x00000004U)
+#define RGX_BIF_DM_ENCODING_PB_TE                         (0x00000005U)
+#define RGX_BIF_DM_ENCODING_META                          (0x00000007U)
+#define RGX_BIF_DM_ENCODING_HOST                          (0x00000008U)
+#define RGX_BIF_DM_ENCODING_PM_ALIST                      (0x00000009U)
+
+
+/*
+
+               Labelling of fields within virtual address
+       
+*/
+/*
+Page Catalogue entry #
+*/
+#define RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT                  (30U)
+#define RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK                 (IMG_UINT64_C(0XFFFFFF003FFFFFFF))
+/*
+Page Directory entry #
+*/
+#define RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT                  (21U)
+#define RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFC01FFFFF))
+/*
+Page Table entry #
+*/
+#define RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT                  (12U)
+#define RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFE00FFF))
+
+
+/*
+
+               Number of entries in a PC
+       
+*/
+#define RGX_MMUCTRL_ENTRIES_PC_VALUE                      (0x00000400U)
+
+
+/*
+
+               Number of entries in a PD
+       
+*/
+#define RGX_MMUCTRL_ENTRIES_PD_VALUE                      (0x00000200U)
+
+
+/*
+
+               Number of entries in a PT
+       
+*/
+#define RGX_MMUCTRL_ENTRIES_PT_VALUE                      (0x00000200U)
+
+
+/*
+
+               Size in bits of the PC entries in memory
+       
+*/
+#define RGX_MMUCTRL_ENTRY_SIZE_PC_VALUE                   (0x00000020U)
+
+
+/*
+
+               Size in bits of the PD entries in memory
+       
+*/
+#define RGX_MMUCTRL_ENTRY_SIZE_PD_VALUE                   (0x00000040U)
+
+
+/*
+
+               Size in bits of the PT entries in memory
+       
+*/
+#define RGX_MMUCTRL_ENTRY_SIZE_PT_VALUE                   (0x00000040U)
+
+
+/*
+
+               Encoding of page size field
+       
+*/
+#define RGX_MMUCTRL_PAGE_SIZE_MASK                        (0x00000007U)
+#define RGX_MMUCTRL_PAGE_SIZE_4KB                         (0x00000000U)
+#define RGX_MMUCTRL_PAGE_SIZE_16KB                        (0x00000001U)
+#define RGX_MMUCTRL_PAGE_SIZE_64KB                        (0x00000002U)
+#define RGX_MMUCTRL_PAGE_SIZE_256KB                       (0x00000003U)
+#define RGX_MMUCTRL_PAGE_SIZE_1MB                         (0x00000004U)
+#define RGX_MMUCTRL_PAGE_SIZE_2MB                         (0x00000005U)
+
+
+/*
+
+               Range of bits used for 4KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_4KB_RANGE_SHIFT                  (12U)
+#define RGX_MMUCTRL_PAGE_4KB_RANGE_CLRMSK                 (IMG_UINT64_C(0XFFFFFF0000000FFF))
+
+
+/*
+
+               Range of bits used for 16KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_16KB_RANGE_SHIFT                 (14U)
+#define RGX_MMUCTRL_PAGE_16KB_RANGE_CLRMSK                (IMG_UINT64_C(0XFFFFFF0000003FFF))
+
+
+/*
+
+               Range of bits used for 64KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_64KB_RANGE_SHIFT                 (16U)
+#define RGX_MMUCTRL_PAGE_64KB_RANGE_CLRMSK                (IMG_UINT64_C(0XFFFFFF000000FFFF))
+
+
+/*
+
+               Range of bits used for 256KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_256KB_RANGE_SHIFT                (18U)
+#define RGX_MMUCTRL_PAGE_256KB_RANGE_CLRMSK               (IMG_UINT64_C(0XFFFFFF000003FFFF))
+
+
+/*
+
+               Range of bits used for 1MB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_1MB_RANGE_SHIFT                  (20U)
+#define RGX_MMUCTRL_PAGE_1MB_RANGE_CLRMSK                 (IMG_UINT64_C(0XFFFFFF00000FFFFF))
+
+
+/*
+
+               Range of bits used for 2MB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PAGE_2MB_RANGE_SHIFT                  (21U)
+#define RGX_MMUCTRL_PAGE_2MB_RANGE_CLRMSK                 (IMG_UINT64_C(0XFFFFFF00001FFFFF))
+
+
+/*
+
+               Range of bits used for PT Base Address for 4KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_4KB_RANGE_SHIFT               (12U)
+#define RGX_MMUCTRL_PT_BASE_4KB_RANGE_CLRMSK              (IMG_UINT64_C(0XFFFFFF0000000FFF))
+
+
+/*
+
+               Range of bits used for PT Base Address for 16KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_16KB_RANGE_SHIFT              (10U)
+#define RGX_MMUCTRL_PT_BASE_16KB_RANGE_CLRMSK             (IMG_UINT64_C(0XFFFFFF00000003FF))
+
+
+/*
+
+               Range of bits used for PT Base Address for 64KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_64KB_RANGE_SHIFT              (8U)
+#define RGX_MMUCTRL_PT_BASE_64KB_RANGE_CLRMSK             (IMG_UINT64_C(0XFFFFFF00000000FF))
+
+
+/*
+
+               Range of bits used for PT Base Address for 256KB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_256KB_RANGE_SHIFT             (6U)
+#define RGX_MMUCTRL_PT_BASE_256KB_RANGE_CLRMSK            (IMG_UINT64_C(0XFFFFFF000000003F))
+
+
+/*
+
+               Range of bits used for PT Base Address for 1MB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_1MB_RANGE_SHIFT               (5U)
+#define RGX_MMUCTRL_PT_BASE_1MB_RANGE_CLRMSK              (IMG_UINT64_C(0XFFFFFF000000001F))
+
+
+/*
+
+               Range of bits used for PT Base Address for 2MB Physical Page
+       
+*/
+#define RGX_MMUCTRL_PT_BASE_2MB_RANGE_SHIFT               (5U)
+#define RGX_MMUCTRL_PT_BASE_2MB_RANGE_CLRMSK              (IMG_UINT64_C(0XFFFFFF000000001F))
+
+
+/*
+
+               Format of Page Table data
+       
+*/
+/*
+PM/Meta protect bit
+*/
+#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_SHIFT         (62U)
+#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_CLRMSK        (IMG_UINT64_C(0XBFFFFFFFFFFFFFFF))
+#define RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN            (IMG_UINT64_C(0X4000000000000000))
+/*
+Upper part of vp page field
+*/
+#define RGX_MMUCTRL_PT_DATA_VP_PAGE_HI_SHIFT              (40U)
+#define RGX_MMUCTRL_PT_DATA_VP_PAGE_HI_CLRMSK             (IMG_UINT64_C(0XC00000FFFFFFFFFF))
+/*
+Physical page address
+*/
+#define RGX_MMUCTRL_PT_DATA_PAGE_SHIFT                    (12U)
+#define RGX_MMUCTRL_PT_DATA_PAGE_CLRMSK                   (IMG_UINT64_C(0XFFFFFF0000000FFF))
+/*
+Lower part of vp page field
+*/
+#define RGX_MMUCTRL_PT_DATA_VP_PAGE_LO_SHIFT              (6U)
+#define RGX_MMUCTRL_PT_DATA_VP_PAGE_LO_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFFFF03F))
+/*
+Entry pending
+*/
+#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_SHIFT           (5U)
+#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN              (IMG_UINT64_C(0X0000000000000020))
+/*
+PM Src
+*/
+#define RGX_MMUCTRL_PT_DATA_PM_SRC_SHIFT                  (4U)
+#define RGX_MMUCTRL_PT_DATA_PM_SRC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
+#define RGX_MMUCTRL_PT_DATA_PM_SRC_EN                     (IMG_UINT64_C(0X0000000000000010))
+/*
+SLC Bypass Ctrl
+*/
+#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_SHIFT         (3U)
+#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
+#define RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN            (IMG_UINT64_C(0X0000000000000008))
+/*
+Cache Coherency bit
+*/
+#define RGX_MMUCTRL_PT_DATA_CC_SHIFT                      (2U)
+#define RGX_MMUCTRL_PT_DATA_CC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
+#define RGX_MMUCTRL_PT_DATA_CC_EN                         (IMG_UINT64_C(0X0000000000000004))
+/*
+Read only
+*/
+#define RGX_MMUCTRL_PT_DATA_READ_ONLY_SHIFT               (1U)
+#define RGX_MMUCTRL_PT_DATA_READ_ONLY_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_MMUCTRL_PT_DATA_READ_ONLY_EN                  (IMG_UINT64_C(0X0000000000000002))
+/*
+Entry valid
+*/
+#define RGX_MMUCTRL_PT_DATA_VALID_SHIFT                   (0U)
+#define RGX_MMUCTRL_PT_DATA_VALID_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_MMUCTRL_PT_DATA_VALID_EN                      (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+
+               Format of Page Directory data
+       
+*/
+/*
+Entry pending
+*/
+#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_SHIFT           (40U)
+#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_CLRMSK          (IMG_UINT64_C(0XFFFFFEFFFFFFFFFF))
+#define RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN              (IMG_UINT64_C(0X0000010000000000))
+/*
+Page Table base address
+*/
+#define RGX_MMUCTRL_PD_DATA_PT_BASE_SHIFT                 (5U)
+#define RGX_MMUCTRL_PD_DATA_PT_BASE_CLRMSK                (IMG_UINT64_C(0XFFFFFF000000001F))
+/*
+Page Size
+*/
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_SHIFT               (1U)
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFFF1))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB                 (IMG_UINT64_C(0000000000000000))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB                (IMG_UINT64_C(0x0000000000000002))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB                (IMG_UINT64_C(0x0000000000000004))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB               (IMG_UINT64_C(0x0000000000000006))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB                 (IMG_UINT64_C(0x0000000000000008))
+#define RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB                 (IMG_UINT64_C(0x000000000000000a))
+/*
+Entry valid
+*/
+#define RGX_MMUCTRL_PD_DATA_VALID_SHIFT                   (0U)
+#define RGX_MMUCTRL_PD_DATA_VALID_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_MMUCTRL_PD_DATA_VALID_EN                      (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+
+               Format of Page Catalogue data
+       
+*/
+/*
+Page Catalogue base address
+*/
+#define RGX_MMUCTRL_PC_DATA_PD_BASE_SHIFT                 (4U)
+#define RGX_MMUCTRL_PC_DATA_PD_BASE_CLRMSK                (0X0000000FU)
+#define RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT            (12U)
+#define RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSIZE             (4096U)
+/*
+Entry pending
+*/
+#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_SHIFT           (1U)
+#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_CLRMSK          (0XFFFFFFFDU)
+#define RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN              (0X00000002U)
+/*
+Entry valid
+*/
+#define RGX_MMUCTRL_PC_DATA_VALID_SHIFT                   (0U)
+#define RGX_MMUCTRL_PC_DATA_VALID_CLRMSK                  (0XFFFFFFFEU)
+#define RGX_MMUCTRL_PC_DATA_VALID_EN                      (0X00000001U)
+
+
+#endif /* _RGXMMUDEFS_KM_H_ */
+
+/*****************************************************************************
+ End of file (rgxmmudefs_km.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/adf/adf_ext.h b/drivers/gpu/rogue_m/include/adf/adf_ext.h
new file mode 100644 (file)
index 0000000..68e972f
--- /dev/null
@@ -0,0 +1,111 @@
+/*************************************************************************/ /*!
+@File           adf_ext.h
+@Title          IMG extension ioctls and ioctl packages for ADF
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#ifndef __ADF_EXT_H__
+#define __ADF_EXT_H__
+
+#include <drm/drm.h>
+
+#define ADF_BUFFER_TRANSFORM_NONE_EXT          (0 << 0)
+#define ADF_BUFFER_TRANSFORM_FLIP_H_EXT                (1 << 0)
+#define ADF_BUFFER_TRANSFORM_FLIP_V_EXT                (1 << 1)
+#define ADF_BUFFER_TRANSFORM_ROT_90_EXT                (1 << 2)
+#define ADF_BUFFER_TRANSFORM_ROT_180_EXT       ((1 << 0) + (1 << 1))
+#define ADF_BUFFER_TRANSFORM_ROT_270_EXT       ((1 << 0) + (1 << 1) + (1 << 2))
+
+#define ADF_BUFFER_BLENDING_NONE_EXT           0
+#define ADF_BUFFER_BLENDING_PREMULT_EXT                1
+#define ADF_BUFFER_BLENDING_COVERAGE_EXT       2
+
+struct adf_buffer_config_ext {
+       /* Crop applied to surface (BEFORE transformation) */
+       struct drm_clip_rect    crop;
+
+       /* Region of screen to display surface in (AFTER scaling) */
+       struct drm_clip_rect    display;
+
+       /* Surface rotation / flip / mirror */
+       __u32                   transform;
+
+       /* Alpha blending mode e.g. none / premult / coverage */
+       __u32                   blend_type;
+
+       /* Plane alpha */
+       __u8                    plane_alpha;
+       __u8                    reserved[3];
+} __packed;
+
+struct adf_post_ext {
+       __u32   post_id;
+       struct adf_buffer_config_ext bufs_ext[];
+} __packed;
+
+struct adf_validate_config_ext {
+       __u32 n_interfaces;
+       __u32 __user *interfaces;
+
+       __u32 n_bufs;
+
+       struct adf_buffer_config __user *bufs;
+       struct adf_post_ext __user *post_ext;
+} __packed;
+
+/* These shouldn't be stripped by the uapi process in the bionic headers,
+ * but currently are being. Redefine them so the custom ioctl interface is
+ * actually useful. Fixed in Lollipop.
+ */
+#ifndef ADF_IOCTL_TYPE
+#define ADF_IOCTL_TYPE 'D'
+#endif
+
+#ifndef ADF_IOCTL_NR_CUSTOM
+#define ADF_IOCTL_NR_CUSTOM 128
+#endif
+
+#define ADF_IOCTL_NR_VALIDATE_IMG (ADF_IOCTL_NR_CUSTOM + 0)
+
+#define ADF_VALIDATE_CONFIG_EXT \
+       _IOW(ADF_IOCTL_TYPE, ADF_IOCTL_NR_VALIDATE_IMG, \
+               struct adf_validate_config_ext)
+
+#endif /* __ADF_EXT_H__ */
diff --git a/drivers/gpu/rogue_m/include/cache_external.h b/drivers/gpu/rogue_m/include/cache_external.h
new file mode 100644 (file)
index 0000000..2967f1e
--- /dev/null
@@ -0,0 +1,75 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services cache management header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines for cache management which are visible internally
+                and externally
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _CACHE_EXTERNAL_H_
+#define _CACHE_EXTERNAL_H_
+#include "img_types.h"
+
+typedef IMG_UINT32 PVRSRV_CACHE_OP;
+
+#define PVRSRV_CACHE_OP_NONE           0x0                     /*!< No operation */
+#define PVRSRV_CACHE_OP_CLEAN          0x1                     /*!< Flush w/o invalidate */
+#define PVRSRV_CACHE_OP_INVALIDATE     0x2                     /*!< Invalidate w/o flush */
+#define PVRSRV_CACHE_OP_FLUSH          0x3                     /*!< Flush w/ invalidate */
+
+/*
+       If we get multiple cache operations before the operation which will
+       trigger the operation to happen then we need to make sure we do
+       the right thing.
+
+       Note: PVRSRV_CACHE_OP_INVALIDATE should never be passed into here
+*/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SetCacheOp)
+#endif
+static INLINE PVRSRV_CACHE_OP SetCacheOp(PVRSRV_CACHE_OP uiCurrent,
+                                                                                PVRSRV_CACHE_OP uiNew)
+{
+       PVRSRV_CACHE_OP uiRet;
+
+       uiRet = uiCurrent | uiNew;
+       return uiRet;
+}
+
+#endif /* _CACHE_EXTERNAL_H_ */
diff --git a/drivers/gpu/rogue_m/include/dbgdrvif_srv5.h b/drivers/gpu/rogue_m/include/dbgdrvif_srv5.h
new file mode 100644 (file)
index 0000000..4f61359
--- /dev/null
@@ -0,0 +1,264 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug driver for Services 5
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Debug Driver Interface
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DBGDRVIF_SRV5_
+#define _DBGDRVIF_SRV5_
+
+#if defined(_MSC_VER) 
+#pragma  warning(disable:4200)
+#endif
+
+#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
+
+
+/*****************************************************************************
+ Stream mode stuff.
+*****************************************************************************/
+#define DEBUG_CAPMODE_FRAMED                   0x00000001UL /* Default capture mode, set when streams created */
+#define DEBUG_CAPMODE_CONTINUOUS               0x00000002UL /* Only set in WDDM, streams created with it set to this mode */
+
+#define DEBUG_FLAGS_USE_NONPAGED_MEM   0x00000001UL /* Only set in WDDM */
+#define DEBUG_FLAGS_NO_BUF_EXPANDSION  0x00000002UL
+#define DEBUG_FLAGS_READONLY                   0x00000008UL
+#define DEBUG_FLAGS_WRITEONLY                  0x00000010UL
+#define DEBUG_FLAGS_CIRCULAR                   0x00000020UL
+
+/*****************************************************************************
+ IOCTL values.
+*****************************************************************************/
+/* IOCTL values defined here so that the windows based OS layer of PDump
+   in the server can access the GetServiceTable method.
+ */
+#define DEBUG_SERVICE_IOCTL_BASE               0x800UL
+#define DEBUG_SERVICE_GETSERVICETABLE  CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETSTREAM                        CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_READ                             CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_SETMARKER                        CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETMARKER                        CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_WAITFOREVENT             CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_GETFRAME                 CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#if defined(__QNXNTO__)
+#define DEBUG_SERVICE_CREATESTREAM             CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define DEBUG_SERVICE_MAX_API                  8
+#else
+#define DEBUG_SERVICE_MAX_API                  9
+#endif
+
+
+#if defined(_WIN32)
+/*****************************************************************************
+ Debug driver device name
+*****************************************************************************/
+#if defined (DBGDRV_MODULE_NAME)
+#define REGISTRY_PATH_TO_DEBUG_DRIVER \
+       L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" DBGDRV_MODULE_NAME
+#define DBGDRV_NT_DEVICE_NAME                          L"\\Device\\" DBGDRV_MODULE_NAME
+#define DBGDRV_NT_SYMLINK                                      L"\\DosDevices\\" DBGDRV_MODULE_NAME
+#else
+#error Debug driver name must be specified
+/*
+#define DBGDRV_NT_DEVICE_NAME                          L"\\Device\\VLDbgDrv"
+#define DBGDRV_NT_SYMLINK                                      L"\\DosDevices\\VLDBGDRV"
+*/
+#endif
+
+/* symbolic link name */
+#define DBGDRV_WIN32_DEVICE_NAME                       "\\\\.\\VLDBGDRV"
+
+#define DBGDRV_WINCE_DEVICE_NAME                       L"DBD1:"
+#endif
+
+#ifdef __GNUC__
+#define DBG_ALIGN(n) __attribute__ ((aligned (n)))
+#else
+#define DBG_ALIGN(n)
+#endif
+
+/* A pointer type which is at least 64 bits wide. The fixed width ensures
+ * consistency in structures between 32 and 64-bit code.
+ * The UM code (be it 32 or 64 bit) can simply write to the native pointer type (pvPtr).
+ * 64-bit KM code must read ui32Ptr if in the case of a 32-bit client, otherwise it can
+ * just read pvPtr if the client is also 64-bit
+ *
+ * ui64Ptr ensures the union is 64-bits wide in a 32-bit client.
+ *
+ * The union is explicitly 64-bit aligned as it was found gcc on x32 only
+ * aligns it to 32-bit, as the ABI permits aligning 64-bit types to a 32-bit
+ * boundary.
+ */
+typedef union
+{
+       /* native pointer type for UM to write to */
+       IMG_VOID *pvPtr;
+       /* the pointer written by a 32-bit client */
+       IMG_UINT32 ui32Ptr;
+       /* force the union width */
+       IMG_UINT64 ui64Ptr;
+} DBG_WIDEPTR DBG_ALIGN(8);
+
+/* Helper macro for dbgdriv (KM) to get the pointer value from the WIDEPTR type,
+ * depending on whether the client is 32 or 64-bit.
+ *
+ * note: double cast is required to avoid
+ * 'cast to pointer from integer of different size' warning.
+ * this is solved by first casting to an integer type.
+ */
+
+#if defined(CONFIG_COMPAT)
+#define WIDEPTR_GET_PTR(p, bCompat) (bCompat ? \
+                                       (IMG_VOID *) (IMG_UINTPTR_T) (p).ui32Ptr : \
+                                       (p).pvPtr)
+#else
+#define WIDEPTR_GET_PTR(p, bCompat) (p).pvPtr
+#endif
+
+typedef enum _DBG_EVENT_
+{
+       DBG_EVENT_STREAM_DATA = 1
+} DBG_EVENT;
+
+
+/*****************************************************************************
+ In/Out Structures
+*****************************************************************************/
+#if defined(__QNXNTO__)
+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_OUT_CREATESTREAM_
+{
+       IMG_HANDLE phInit;
+       IMG_HANDLE phMain;
+       IMG_HANDLE phDeinit;
+} DBG_OUT_CREATESTREAM, *PDBG_OUT_CREATESTREAM;
+#endif
+
+typedef struct _DBG_IN_FINDSTREAM_
+{
+       DBG_WIDEPTR pszName;
+       IMG_BOOL bResetStream;
+}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
+
+#define DEBUG_READ_BUFID_MAIN                  0
+#define DEBUG_READ_BUFID_INIT                  1
+#define DEBUG_READ_BUFID_DEINIT                        2
+
+typedef struct _DBG_IN_READ_
+{
+       DBG_WIDEPTR pui8OutBuffer;
+       IMG_SID hStream;
+       IMG_UINT32 ui32BufID;
+       IMG_UINT32 ui32OutBufferSize;
+} DBG_IN_READ, *PDBG_IN_READ;
+
+typedef struct _DBG_OUT_READ_
+{
+       IMG_UINT32 ui32DataRead;
+       IMG_UINT32 ui32SplitMarker;
+} DBG_OUT_READ, *PDBG_OUT_READ;
+
+typedef struct _DBG_IN_SETMARKER_
+{
+       IMG_SID hStream;
+       IMG_UINT32 ui32Marker;
+} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER;
+
+/*
+       DBG STREAM abstract types
+*/
+
+typedef struct _DBG_STREAM_CONTROL_* PDBG_STREAM_CONTROL;
+typedef struct _DBG_STREAM_* PDBG_STREAM;
+
+/*
+       Lookup identifiers for the GetState method in the KM service table.
+ */
+#define DBG_GET_STATE_FLAG_IS_READONLY    0x03
+
+
+/*****************************************************************************
+ Kernel mode service table
+*****************************************************************************/
+typedef struct _DBGKM_SERVICE_TABLE_
+{
+       IMG_UINT32 ui32Size;
+       IMG_BOOL        (IMG_CALLCONV *pfnCreateStream)                 (IMG_CHAR * pszName,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages, IMG_HANDLE* phInit, IMG_HANDLE* phMain, IMG_HANDLE* phDeinit);
+       IMG_VOID        (IMG_CALLCONV *pfnDestroyStream)                (IMG_HANDLE hInit, IMG_HANDLE hMain, IMG_HANDLE hDeinit);
+       IMG_UINT32      (IMG_CALLCONV *pfnDBGDrivWrite2)                (PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize);
+       IMG_VOID        (IMG_CALLCONV *pfnSetMarker)                    (PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+       IMG_VOID        (IMG_CALLCONV *pfnWaitForEvent)                 (DBG_EVENT eEvent);
+       IMG_UINT32  (IMG_CALLCONV *pfnGetCtrlState)                     (PDBG_STREAM psStream, IMG_UINT32 ui32StateID);
+       IMG_VOID        (IMG_CALLCONV *pfnSetFrame)                             (IMG_UINT32 ui32Frame);
+} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE;
+
+#if defined(_MSC_VER) 
+#pragma  warning(default:4200)
+#endif
+
+#endif
+
+/*****************************************************************************
+ End of file
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/include/devicemem_typedefs.h b/drivers/gpu/rogue_m/include/devicemem_typedefs.h
new file mode 100644 (file)
index 0000000..561d75f
--- /dev/null
@@ -0,0 +1,105 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Client side part of device memory management -- this file
+                is forked from new_devmem_allocation.h as this one has to
+                reside in the top level include so that client code is able
+                to make use of the typedefs.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_TYPEDEFS_H
+#define DEVICEMEM_TYPEDEFS_H
+
+#include "img_types.h"
+#include "pvrsrv_memallocflags.h"
+
+typedef struct _DEVMEM_CONTEXT_ DEVMEM_CONTEXT;     /*!< Convenience typedef for struct _DEVMEM_CONTEXT_ */
+typedef struct _DEVMEM_HEAP_ DEVMEM_HEAP;           /*!< Convenience typedef for struct _DEVMEM_HEAP_ */
+typedef struct _DEVMEM_MEMDESC_ DEVMEM_MEMDESC;     /*!< Convenience typedef for struct _DEVMEM_MEMDESC_ */
+typedef struct _DEVMEM_PAGELIST_ DEVMEM_PAGELIST;      /*!< Convenience typedef for struct _DEVMEM_PAGELIST_ */
+typedef PVRSRV_MEMALLOCFLAGS_T DEVMEM_FLAGS_T;      /*!< Conveneince typedef for PVRSRV_MEMALLOCFLAGS_T */
+
+typedef IMG_HANDLE /* FIXME: should be a SID */ DEVMEM_EXPORTHANDLE; /*!< Typedef for DeviceMem Export Handle */
+typedef IMG_UINT64 DEVMEM_EXPORTKEY;                                /*!< Typedef for DeviceMem Export Key */
+typedef IMG_DEVMEM_SIZE_T DEVMEM_SIZE_T;                            /*!< Typedef for DeviceMem SIZE_T */
+typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T;                  /*!< Typdef for DeviceMem LOG2 Alignment */
+
+/*! calling code needs all the info in this struct, to be able to pass it around */
+typedef struct
+{
+    /*! A handle to the PMR.  Should be a SID.  FIXME: decide whether
+       this is right... as the PMR would have to be a cross-process
+       handle */
+    IMG_HANDLE hPMRExportHandle;
+    /*! The "key" to prove we have authorization to use this PMR */
+    IMG_UINT64 uiPMRExportPassword;
+    /*! Size and alignment properties for this PMR.  Note, these
+       numbers are not trusted in kernel, but we need to cache them
+       client-side in order to allocate from the VM arena.  The kernel
+       will know the actual alignment and size of the PMR and thus
+       would prevent client code from breaching security here.  Ditto
+       for physmem granularity (aka page size) if this is different
+       from alignment */
+    IMG_DEVMEM_SIZE_T uiSize;
+    /*! We call this "contiguity guarantee" to be more precise than
+       calling it "alignment" or "page size", terms which may seem
+       similar but have different emphasis.  The number reported here
+       is the minimum contiguity guarantee from the creator of the
+       PMR.  Now, there is no requirement to allocate that coarsely
+       from the RA.  The alignment given to the RA simply needs to be
+       at least as coarse as the device page size for the heap we
+       ultimately intend to map into.  What is important is that the
+       device MMU data page size is not greater than the minimum
+       contiguity guarantee from the PMR.  This value is reported to
+       the client in order that it can choose to make early checks and
+       perhaps decide which heap (in a variable page size scenario) it
+       would be safe to map this PMR into.  For convenience, the
+       client may choose to use this argument as the alignment of the
+       virtual range he chooses to allocate, but this is _not_
+       necessary and in many cases would be able to get away with a
+       finer alignment, should the heap into which this PMR will be
+       mapped support it. */
+    IMG_DEVMEM_LOG2ALIGN_T uiLog2ContiguityGuarantee;
+} DEVMEM_EXPORTCOOKIE;
+
+typedef IMG_HANDLE DEVMEM_SERVER_EXPORTCOOKIE; /*!< typedef for DeviceMem Server Export Cookie */
+
+#endif /* #ifndef SRVCLIENT_NEW_DEVMEM_ALLOCATION_TYPEDEFS_H */
+
diff --git a/drivers/gpu/rogue_m/include/img_3dtypes.h b/drivers/gpu/rogue_m/include/img_3dtypes.h
new file mode 100644 (file)
index 0000000..d7ad113
--- /dev/null
@@ -0,0 +1,236 @@
+/*************************************************************************/ /*!
+@File
+@Title          Global 3D types for use by IMG APIs
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines 3D types for use by IMG APIs
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __IMG_3DTYPES_H__
+#define __IMG_3DTYPES_H__
+
+/**
+ * Comparison functions
+ * This comparison function is defined as:
+ * A {CmpFunc} B
+ * A is a reference value, e.g., incoming depth etc.
+ * B is the sample value, e.g., value in depth buffer. 
+ */
+typedef enum _IMG_COMPFUNC_
+{
+       IMG_COMPFUNC_NEVER,                     /**< The comparison never succeeds */
+       IMG_COMPFUNC_LESS,                      /**< The comparison is a less-than operation */
+       IMG_COMPFUNC_EQUAL,                     /**< The comparison is an equal-to operation */
+       IMG_COMPFUNC_LESS_EQUAL,        /**< The comparison is a less-than or equal-to 
+                                                                        operation */
+       IMG_COMPFUNC_GREATER,           /**< The comparison is a greater-than operation 
+                                                               */
+       IMG_COMPFUNC_NOT_EQUAL,         /**< The comparison is a no-equal-to operation
+                                                               */
+       IMG_COMPFUNC_GREATER_EQUAL,     /**< The comparison is a greater-than or 
+                                                                        equal-to operation */
+       IMG_COMPFUNC_ALWAYS,            /**< The comparison always succeeds */
+} IMG_COMPFUNC;
+
+/**
+ * Stencil op functions
+ */
+typedef enum _IMG_STENCILOP_
+{
+       IMG_STENCILOP_KEEP,             /**< Keep original value */
+       IMG_STENCILOP_ZERO,             /**< Set stencil to 0 */
+       IMG_STENCILOP_REPLACE,  /**< Replace stencil entry */
+       IMG_STENCILOP_INCR_SAT, /**< Increment stencil entry, clamping to max */
+       IMG_STENCILOP_DECR_SAT, /**< Decrement stencil entry, clamping to zero */
+       IMG_STENCILOP_INVERT,   /**< Invert bits in stencil entry */
+       IMG_STENCILOP_INCR,             /**< Increment stencil entry, 
+                                                                wrapping if necessary */
+       IMG_STENCILOP_DECR,             /**< Decrement stencil entry, 
+                                                                wrapping if necessary */
+} IMG_STENCILOP;
+
+/**
+ * Memory layout enumeration.
+ * Defines how pixels are layed out within a surface.
+ */
+typedef enum _IMG_MEMLAYOUT_
+{
+       IMG_MEMLAYOUT_STRIDED,                  /**< Resource is strided, one row at a time */
+    IMG_MEMLAYOUT_TWIDDLED,                    /**< Resource is 2D twiddled, classic style */
+    IMG_MEMLAYOUT_3DTWIDDLED,       /**< Resource is 3D twiddled, classic style */
+       IMG_MEMLAYOUT_TILED,                    /**< Resource is tiled, tiling config specified elsewhere. */
+       IMG_MEMLAYOUT_PAGETILED,                /**< Resource is pagetiled */
+} IMG_MEMLAYOUT;
+
+/**
+ * Alpha blending allows colours and textures on one surface
+ * to be blended with transparancy onto another surface.
+ * These definitions apply to both source and destination blending
+ * states
+ */
+typedef enum _IMG_BLEND_
+{
+       IMG_BLEND_ZERO = 0,        /**< Blend factor is (0,0,0,0) */
+       IMG_BLEND_ONE,             /**< Blend factor is (1,1,1,1) */
+       IMG_BLEND_SRC_COLOUR,      /**< Blend factor is the source colour */
+       IMG_BLEND_INV_SRC_COLOUR,  /**< Blend factor is the inverted source colour
+                                                                       (i.e. 1-src_col) */
+       IMG_BLEND_SRC_ALPHA,       /**< Blend factor is the source alpha */
+       IMG_BLEND_INV_SRC_ALPHA,   /**< Blend factor is the inverted source alpha
+                                                                       (i.e. 1-src_alpha) */
+       IMG_BLEND_DEST_ALPHA,      /**< Blend factor is the destination alpha */
+       IMG_BLEND_INV_DEST_ALPHA,  /**< Blend factor is the inverted destination 
+                                                                       alpha */
+       IMG_BLEND_DEST_COLOUR,     /**< Blend factor is the destination colour */
+       IMG_BLEND_INV_DEST_COLOUR, /**< Blend factor is the inverted destination 
+                                                                       colour */
+       IMG_BLEND_SRC_ALPHASAT,    /**< Blend factor is the alpha saturation (the 
+                                                                       minimum of (Src alpha, 
+                                                                       1 - destination alpha)) */
+       IMG_BLEND_BLEND_FACTOR,    /**< Blend factor is a constant */
+       IMG_BLEND_INVBLEND_FACTOR, /**< Blend factor is a constant (inverted)*/
+       IMG_BLEND_SRC1_COLOUR,     /**< Blend factor is the colour outputted from 
+                                                                       the pixel shader */
+       IMG_BLEND_INV_SRC1_COLOUR, /**< Blend factor is the inverted colour 
+                                                                       outputted from the pixel shader */
+       IMG_BLEND_SRC1_ALPHA,      /**< Blend factor is the alpha outputted from 
+                                                                       the pixel shader */
+       IMG_BLEND_INV_SRC1_ALPHA   /**< Blend factor is the inverted alpha
+                                                                       outputted from the pixel shader */
+} IMG_BLEND;
+
+/**
+ * The arithmetic operation to perform when blending
+ */
+typedef enum _IMG_BLENDOP_
+{
+       IMG_BLENDOP_ADD = 0,      /**< Result = (Source + Destination) */
+       IMG_BLENDOP_SUBTRACT,     /**< Result = (Source - Destination) */
+       IMG_BLENDOP_REV_SUBTRACT, /**< Result = (Destination - Source) */
+       IMG_BLENDOP_MIN,          /**< Result = min (Source, Destination) */
+       IMG_BLENDOP_MAX           /**< Result = max (Source, Destination) */
+} IMG_BLENDOP;
+
+/**
+ * Logical operation to perform when logic ops are enabled
+ */
+typedef enum _IMG_LOGICOP_
+{
+       IMG_LOGICOP_CLEAR = 0,     /**< Result = 0 */
+       IMG_LOGICOP_SET,           /**< Result = -1 */
+       IMG_LOGICOP_COPY,          /**< Result = Source */
+       IMG_LOGICOP_COPY_INVERTED, /**< Result = ~Source */
+       IMG_LOGICOP_NOOP,          /**< Result = Destination */
+       IMG_LOGICOP_INVERT,        /**< Result = ~Destination */
+       IMG_LOGICOP_AND,           /**< Result = Source & Destination */
+       IMG_LOGICOP_NAND,          /**< Result = ~(Source & Destination) */
+       IMG_LOGICOP_OR,            /**< Result = Source | Destination */
+       IMG_LOGICOP_NOR,           /**< Result = ~(Source | Destination) */
+       IMG_LOGICOP_XOR,           /**< Result = Source ^ Destination */
+       IMG_LOGICOP_EQUIV,         /**< Result = ~(Source ^ Destination) */
+       IMG_LOGICOP_AND_REVERSE,   /**< Result = Source & ~Destination */
+       IMG_LOGICOP_AND_INVERTED,  /**< Result = ~Source & Destination */
+       IMG_LOGICOP_OR_REVERSE,    /**< Result = Source | ~Destination */
+       IMG_LOGICOP_OR_INVERTED    /**< Result = ~Source | Destination */
+} IMG_LOGICOP;
+
+/**
+ * Type of fog blending supported
+ */
+typedef enum _IMG_FOGMODE_
+{
+       IMG_FOGMODE_NONE, /**< No fog blending - fog calculations are
+                                          *   based on the value output from the vertex phase */
+       IMG_FOGMODE_LINEAR, /**< Linear interpolation */
+       IMG_FOGMODE_EXP, /**< Exponential */
+       IMG_FOGMODE_EXP2, /**< Exponential squaring */
+} IMG_FOGMODE;
+
+/**
+ * Types of filtering
+ */
+typedef enum _IMG_FILTER_
+{
+       IMG_FILTER_DONTCARE,    /**< Any filtering mode is acceptable */
+       IMG_FILTER_POINT,               /**< Point filtering */
+       IMG_FILTER_LINEAR,              /**< Bi-linear filtering */
+       IMG_FILTER_BICUBIC,             /**< Bi-cubic filtering */
+} IMG_FILTER;
+
+/**
+ * Addressing modes for textures
+ */
+typedef enum _IMG_ADDRESSMODE_
+{
+       IMG_ADDRESSMODE_REPEAT, /**< Texture repeats conintuously */
+       IMG_ADDRESSMODE_FLIP, /**< Texture flips on odd integer part */
+       IMG_ADDRESSMODE_CLAMP, /**< Texture clamped at 0 or 1 */
+       IMG_ADDRESSMODE_FLIPCLAMP, /**< Flipped once, then clampe */
+       IMG_ADDRESSMODE_CLAMPBORDER,
+       IMG_ADDRESSMODE_OGL_CLAMP,
+       IMG_ADDRESSMODE_OVG_TILEFILL,
+       IMG_ADDRESSMODE_DONTCARE,
+} IMG_ADDRESSMODE;
+
+/**
+ * Culling based on winding order of triangle.
+ */
+typedef enum _IMG_CULLMODE_
+{
+       IMG_CULLMODE_NONE,                      /**< Don't cull */
+       IMG_CULLMODE_FRONTFACING,       /**< Front facing triangles */
+       IMG_CULLMODE_BACKFACING,        /**< Back facing triangles */
+} IMG_CULLMODE;
+
+/**
+ * Rotation clockwise
+ */
+typedef enum _IMG_ROTATION_
+{
+       IMG_ROTATION_0DEG = 0,
+       IMG_ROTATION_90DEG = 1,
+       IMG_ROTATION_180DEG = 2,
+       IMG_ROTATION_270DEG = 3,
+       IMG_ROTATION_FLIP_Y = 4
+} IMG_ROTATION;
+
+
+#endif /* __IMG_3DTYPES_H__ */
+/******************************************************************************
+ End of file (img_3dtypes.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/include/img_defs.h b/drivers/gpu/rogue_m/include/img_defs.h
new file mode 100644 (file)
index 0000000..a4a3c22
--- /dev/null
@@ -0,0 +1,226 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common header containing type definitions for portability
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Contains variable and structure definitions. Any platform
+                specific types should be defined in this file.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__IMG_DEFS_H__)
+#define __IMG_DEFS_H__
+
+#include <stddef.h>
+
+#include "img_types.h"
+
+#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
+#if defined(UNDER_WDDM) && defined(_X86_)
+       #define FORCE_INLINE                    __forceinline
+#else
+       #define FORCE_INLINE                    static __inline
+#endif
+#endif
+#endif
+
+
+/* Use this in any file, or use attributes under GCC - see below */
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define        PVR_UNREFERENCED_PARAMETER(param) ((void)(param))
+#endif
+
+/*! Macro used to check structure size and alignment at compile time. */
+#define BLD_ASSERT(expr, file) _impl_ASSERT_LINE(expr,__LINE__,file)
+#define _impl_JOIN(a,b) a##b
+#define _impl_ASSERT_LINE(expr, line, file) \
+       typedef char _impl_JOIN(build_assertion_failed_##file##_,line)[2*!!(expr)-1];
+
+/*! Macro to calculate the n-byte aligned value from that supplied rounding up.
+ * n must be a power of two.
+ *
+ * Both arguments should be of a type with the same size otherwise the macro may
+ * cut off digits, e.g. imagine a 64 bit address in _x and a 32 bit value in _n.
+ */
+#define PVR_ALIGN(_x, _n)   (((_x)+((_n)-1)) & ~((_n)-1))
+
+
+/* The best way to supress unused parameter warnings using GCC is to use a
+ * variable attribute.  Place the unref__ between the type and name of an
+ * unused parameter in a function parameter list, eg `int unref__ var'. This
+ * should only be used in GCC build environments, for example, in files that
+ * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */
+#ifdef __GNUC__
+#define unref__ __attribute__ ((unused))
+#else
+#define unref__
+#endif
+
+#if defined(_WIN32)
+       #define IMG_CALLCONV __stdcall
+       #define IMG_INTERNAL
+       #define IMG_EXPORT      __declspec(dllexport)
+       #define IMG_RESTRICT __restrict
+       #define C_CALLCONV      __cdecl
+
+       /* IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations match.
+        * Some compilers require the header to be declared IMPORT, while the implementation is declared EXPORT 
+        */
+       #define IMG_IMPORT      IMG_EXPORT
+
+#if defined(UNDER_WDDM)
+       #ifndef _INC_STDLIB
+                       #if defined (UNDER_MSBUILD)
+                       _CRTIMP __declspec(noreturn) void __cdecl abort(void);
+               #else
+                       _CRTIMP void __cdecl abort(void);
+               #endif
+       #endif
+       #if defined(EXIT_ON_ABORT)
+               #define IMG_ABORT()     exit(1);
+       #else
+               #define IMG_ABORT()     abort();
+       #endif
+//     #define IMG_ABORT()     img_abort()
+#endif /* UNDER_WDDM */
+#else
+       #if defined(LINUX) || defined(__METAG) || defined(__QNXNTO__)
+
+               #define IMG_CALLCONV
+               #define C_CALLCONV
+               #if defined(__linux__) || defined(__QNXNTO__)
+                       #define IMG_INTERNAL    __attribute__((visibility("hidden")))
+               #else
+                       #define IMG_INTERNAL
+               #endif
+               #define IMG_EXPORT              __attribute__((visibility("default")))
+               #define IMG_IMPORT
+               #define IMG_RESTRICT    __restrict__
+
+       #else
+               #error("define an OS")
+       #endif
+#endif
+
+// Use default definition if not overridden
+#ifndef IMG_ABORT
+       #if defined(EXIT_ON_ABORT)
+               #define IMG_ABORT()     exit(1)
+       #else
+               #define IMG_ABORT()     abort()
+       #endif
+#endif
+
+#if defined(__GNUC__)
+#define IMG_FORMAT_PRINTF(x,y)         __attribute__((format(printf,x,y)))
+#else
+#define IMG_FORMAT_PRINTF(x,y)
+#endif
+
+#if defined(__GNUC__)
+#define IMG_WARN_UNUSED_RESULT         __attribute__((warn_unused_result))
+#else
+#define IMG_WARN_UNUSED_RESULT
+#endif
+
+#if defined(_MSC_VER) || defined(CC_ARM)
+       #define IMG_NORETURN __declspec(noreturn)
+#else
+       #if defined(__GNUC__)
+               #define IMG_NORETURN __attribute__((noreturn))
+       #else
+               #define IMG_NORETURN
+       #endif
+#endif
+
+#define MAX(a,b)                                       (((a) > (b)) ? (a) : (b))
+#define MIN(a,b)                                       (((a) < (b)) ? (a) : (b))
+
+/* Get a structures address from the address of a member */
+#define IMG_CONTAINER_OF(ptr, type, member) \
+       (type *) ((IMG_UINT8 *) (ptr) - offsetof(type, member))
+
+/* The number of elements in a fixed-sized array, IMGs ARRAY_SIZE macro */
+#define IMG_ARR_NUM_ELEMS(ARR) \
+       (sizeof(ARR) / sizeof((ARR)[0]))
+
+/* To guarantee that __func__ can be used, define it as a macro here if it
+   isn't already provided by the compiler. */
+#if defined(_MSC_VER)
+#define __func__ __FUNCTION__
+#endif
+
+#if defined(__cplusplus)
+/* C++ Specific:
+ * Disallow use of copy and assignment operator within a class.
+ * Should be placed under private. */
+#define IMG_DISALLOW_COPY_AND_ASSIGN(C) \
+       C(const C&); \
+       void operator=(const C&)
+#endif
+
+#if defined(SUPPORT_PVR_VALGRIND)
+       #if !defined(__METAG)
+               #include "/usr/include/valgrind/memcheck.h"
+
+               #define VALGRIND_HEADER_PRESENT
+
+               #define VG_MARK_INITIALIZED(pvData,ui32Size)  VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size)
+       #else
+               #define VG_MARK_INITIALIZED(pvData,ui32Size) do { } while(0)
+       #endif
+#else
+
+       #define VG_MARK_INITIALIZED(pvData,ui32Size) do { } while(0)
+#endif
+
+
+#endif /* #if !defined (__IMG_DEFS_H__) */
+/*****************************************************************************
+ End of file (IMG_DEFS.H)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/img_types.h b/drivers/gpu/rogue_m/include/img_types.h
new file mode 100644 (file)
index 0000000..54a752c
--- /dev/null
@@ -0,0 +1,289 @@
+/*************************************************************************/ /*!
+@File
+@Title          Global types for use by IMG APIs
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines type aliases for use by IMG APIs.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __IMG_TYPES_H__
+#define __IMG_TYPES_H__
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* To use C99 types and definitions, there are two special cases we need to
+ * cater for:
+ *
+ * - Visual Studio: in VS2010 or later, some standard headers are available,
+ *   and MSVC has its own built-in sized types. We can define the C99 types
+ *   in terms of these.
+ *
+ * - Linux kernel code: C99 sized types are defined in <linux/types.h>, but
+ *   some other features (like macros for constants or printf format
+ *   strings) are missing, so we need to fill in the gaps ourselves.
+ *
+ * For other cases (userspace code under Linux, Android or Neutrino, or
+ * firmware code), we can include the standard headers.
+ */
+#if defined(_MSC_VER)
+       #include "msvc_types.h"
+#elif defined(LINUX) && defined(__KERNEL__)
+       #include "kernel_types.h"
+#elif defined(LINUX) || defined(__METAG) || defined(__QNXNTO__)
+       #include <stddef.h>                     /* NULL */
+       #include <inttypes.h>           /* intX_t/uintX_t, format specifiers */
+       #include <limits.h>                     /* INT_MIN, etc */
+#else
+       #error C99 support not set up for this build
+#endif
+
+/* number of bits in the units returned by sizeof */
+#define IMG_CHAR_BIT CHAR_BIT
+
+typedef unsigned int   IMG_UINT,       *IMG_PUINT;
+typedef int                            IMG_INT,        *IMG_PINT;
+
+typedef uint8_t                        IMG_UINT8,      *IMG_PUINT8;
+typedef uint8_t                        IMG_BYTE,       *IMG_PBYTE;
+typedef int8_t                 IMG_INT8,       *IMG_PINT8;
+typedef char                   IMG_CHAR,       *IMG_PCHAR;
+typedef IMG_CHAR const                         *IMG_PCCHAR;
+
+typedef uint16_t               IMG_UINT16,     *IMG_PUINT16;
+typedef int16_t                        IMG_INT16,      *IMG_PINT16;
+typedef uint32_t               IMG_UINT32,     *IMG_PUINT32;
+typedef int32_t                        IMG_INT32,      *IMG_PINT32;
+
+typedef uint64_t               IMG_UINT64,     *IMG_PUINT64;
+typedef int64_t                        IMG_INT64,      *IMG_PINT64;
+#define IMG_INT64_C(c) INT64_C(c)
+#define IMG_UINT64_C(c)        UINT64_C(c)
+#define IMG_UINT64_FMTSPECX PRIX64
+#define IMG_UINT64_FMTSPEC PRIu64
+
+#define IMG_UINT16_MAX UINT16_MAX
+#define IMG_UINT32_MAX UINT32_MAX
+#define IMG_UINT64_MAX UINT64_MAX
+
+typedef IMG_UINT16 const* IMG_PCUINT16;
+typedef IMG_INT16 const* IMG_PCINT16;
+typedef IMG_UINT32 const* IMG_PCUINT32;
+typedef IMG_INT32 const* IMG_PCINT32;
+
+/* Linux kernel mode does not use floating point */
+typedef float                  IMG_FLOAT,      *IMG_PFLOAT;
+typedef double                 IMG_DOUBLE, *IMG_PDOUBLE;
+
+typedef union _IMG_UINT32_FLOAT_
+{
+       IMG_UINT32 ui32;
+       IMG_FLOAT f;
+} IMG_UINT32_FLOAT;
+
+typedef int                            IMG_SECURE_TYPE;
+
+typedef        enum tag_img_bool
+{
+       IMG_FALSE               = 0,
+       IMG_TRUE                = 1,
+       IMG_FORCE_ALIGN = 0x7FFFFFFF
+} IMG_BOOL, *IMG_PBOOL;
+typedef IMG_BOOL const* IMG_PCBOOL;
+
+typedef void            IMG_VOID, *IMG_PVOID;
+typedef IMG_VOID const* IMG_PCVOID;
+
+typedef uintptr_t              IMG_UINTPTR_T;
+typedef size_t                 IMG_SIZE_T;
+
+#define IMG_SIZE_T_MAX SIZE_MAX
+
+#if defined(_MSC_VER)
+#define IMG_SIZE_FMTSPEC  "%Iu"
+#define IMG_SIZE_FMTSPECX "%Ix"
+#else
+#define IMG_SIZE_FMTSPEC  "%zu"
+#define IMG_SIZE_FMTSPECX "%zx"
+#endif
+
+typedef IMG_PVOID       IMG_HANDLE;
+
+#define IMG_NULL        NULL
+
+#if defined(LINUX) && defined(__KERNEL__)
+/* prints the function name when used with printk */
+#define IMG_PFN_FMTSPEC "%pf"
+#else
+#define IMG_PFN_FMTSPEC "%p"
+#endif
+
+/* services/stream ID */
+typedef IMG_UINT64      IMG_SID;
+
+/* Process IDs */
+typedef IMG_UINT32      IMG_PID;
+
+
+/*
+ * Address types.
+ * All types used to refer to a block of memory are wrapped in structures
+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot
+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the
+ * same thing.
+ *
+ * There is an assumption that the system contains at most one non-cpu mmu,
+ * and a memory block is only mapped by the MMU once.
+ *
+ * Different devices could have offset views of the physical address space.
+ * 
+ */
+
+
+/*
+ *
+ * +------------+    +------------+      +------------+        +------------+
+ * |    CPU     |    |    DEV     |      |    DEV     |        |    DEV     |
+ * +------------+    +------------+      +------------+        +------------+
+ *       |                 |                   |                     |
+ *       | PVOID           |IMG_DEV_VIRTADDR   |IMG_DEV_VIRTADDR     |
+ *       |                 \-------------------/                     |
+ *       |                          |                                |
+ * +------------+             +------------+                         |     
+ * |    MMU     |             |    MMU     |                         |
+ * +------------+             +------------+                         | 
+ *       |                          |                                | 
+ *       |                          |                                |
+ *       |                          |                                |
+ *   +--------+                +---------+                      +--------+
+ *   | Offset |                | (Offset)|                      | Offset |
+ *   +--------+                +---------+                      +--------+    
+ *       |                          |                IMG_DEV_PHYADDR | 
+ *       |                          |                                |
+ *       |                          | IMG_DEV_PHYADDR                |
+ * +---------------------------------------------------------------------+ 
+ * |                         System Address bus                          |
+ * +---------------------------------------------------------------------+
+ *
+ */
+
+typedef IMG_PVOID IMG_CPU_VIRTADDR;
+
+/* device virtual address */
+typedef struct _IMG_DEV_VIRTADDR
+{
+       IMG_UINT64  uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var)         (IMG_UINT64)(var)
+       
+} IMG_DEV_VIRTADDR;
+
+typedef IMG_UINT64 IMG_DEVMEM_SIZE_T;
+typedef IMG_UINT64 IMG_DEVMEM_ALIGN_T;
+typedef IMG_UINT64 IMG_DEVMEM_OFFSET_T;
+typedef IMG_UINT32 IMG_DEVMEM_LOG2ALIGN_T;
+
+#define IMG_DEV_VIRTADDR_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_SIZE_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_ALIGN_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_OFFSET_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+
+/* cpu physical address */
+typedef struct _IMG_CPU_PHYADDR
+{
+#if defined(UNDER_WDDM)
+       IMG_UINTPTR_T uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var)               (IMG_UINTPTR_T)(var)
+#else
+       IMG_UINT64 uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var)               (IMG_UINT64)(var)
+#endif
+} IMG_CPU_PHYADDR;
+
+/* device physical address */
+typedef struct _IMG_DEV_PHYADDR
+{
+       IMG_UINT64 uiAddr;
+} IMG_DEV_PHYADDR;
+
+/* system physical address */
+typedef struct _IMG_SYS_PHYADDR
+{
+#if defined(UNDER_WDDM)
+       IMG_UINTPTR_T uiAddr;
+#else
+       IMG_UINT64 uiAddr;
+#endif
+} IMG_SYS_PHYADDR;
+
+/* 32-bit device virtual address (e.g. MSVDX) */
+typedef struct _IMG_DEV_VIRTADDR32
+{
+       IMG_UINT32 uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT32(var) (IMG_UINT32)(var)
+} IMG_DEV_VIRTADDR32;
+
+/*
+       rectangle structure
+*/
+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;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#include "img_defs.h"
+
+#endif /* __IMG_TYPES_H__ */
+/******************************************************************************
+ End of file (img_types.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/kernel_types.h b/drivers/gpu/rogue_m/include/kernel_types.h
new file mode 100644 (file)
index 0000000..b53da19
--- /dev/null
@@ -0,0 +1,136 @@
+/*************************************************************************/ /*!
+@Title          C99-compatible types and definitions for Linux kernel code
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/kernel.h>
+
+/* Limits of specified-width integer types */
+
+/* S8_MIN, etc were added in kernel version 3.14. The other versions are for
+ * earlier kernels. They can be removed once older kernels don't need to be
+ * supported.
+ */
+#ifdef S8_MIN
+       #define INT8_MIN        S8_MIN
+#else
+       #define INT8_MIN        (-128)
+#endif
+
+#ifdef S8_MAX
+       #define INT8_MAX        S8_MAX
+#else
+       #define INT8_MAX        127
+#endif
+
+#ifdef U8_MAX
+       #define UINT8_MAX       U8_MAX
+#else
+       #define UINT8_MAX       0xFF
+#endif
+
+#ifdef S16_MIN
+       #define INT16_MIN       S16_MIN
+#else
+       #define INT16_MIN       (-32768)
+#endif
+
+#ifdef S16_MAX
+       #define INT16_MAX       S16_MAX
+#else
+       #define INT16_MAX       32767
+#endif
+
+#ifdef U16_MAX
+       #define UINT16_MAX      U16_MAX
+#else
+       #define UINT16_MAX      0xFFFF
+#endif
+
+#ifdef S32_MIN
+       #define INT32_MIN       S32_MIN
+#else
+       #define INT32_MIN       (-2147483647 - 1)
+#endif
+
+#ifdef S32_MAX
+       #define INT32_MAX       S32_MAX
+#else
+       #define INT32_MAX       2147483647
+#endif
+
+#ifdef U32_MAX
+       #define UINT32_MAX      U32_MAX
+#else
+       #define UINT32_MAX      0xFFFFFFFF
+#endif
+
+#ifdef S64_MIN
+       #define INT64_MIN       S64_MIN
+#else
+       #define INT64_MIN       (-9223372036854775807LL)
+#endif
+
+#ifdef S64_MAX
+       #define INT64_MAX       S64_MAX
+#else
+       #define INT64_MAX       9223372036854775807LL
+#endif
+
+#ifdef U64_MAX
+       #define UINT64_MAX      U64_MAX
+#else
+       #define UINT64_MAX      0xFFFFFFFFFFFFFFFFULL
+#endif
+
+/* Macros for integer constants */
+#define INT8_C                 S8_C
+#define UINT8_C                        U8_C
+#define INT16_C                        S16_C
+#define UINT16_C               U16_C
+#define INT32_C                        S32_C
+#define UINT32_C               U32_C
+#define INT64_C                        S64_C
+#define UINT64_C               U64_C
+
+/* Format conversion of integer types <inttypes.h> */
+/* Only define PRIX64 for the moment, as this is the only format macro that
+ * img_types.h needs.
+ */
+#define PRIX64         "llX"
diff --git a/drivers/gpu/rogue_m/include/lock_types.h b/drivers/gpu/rogue_m/include/lock_types.h
new file mode 100644 (file)
index 0000000..8caf861
--- /dev/null
@@ -0,0 +1,90 @@
+/*************************************************************************/ /*!
+@File           lock_types.h
+@Title          Locking types
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Locking specific enums, defines and structures
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _LOCK_TYPES_H_
+#define _LOCK_TYPES_H_
+
+/* In Linux kernel mode we are using the kernel mutex implementation directly
+ * with macros. This allows us to use the kernel lockdep feature for lock
+ * debugging. */
+#if defined(LINUX) && defined(__KERNEL__)
+
+#include <linux/types.h>
+#include <linux/mutex.h>
+/* The mutex is defined as a pointer to be compatible with the other code. This
+ * isn't ideal and usually you wouldn't do that in kernel code. */
+typedef struct mutex *POS_LOCK;
+typedef atomic_t ATOMIC_T;
+
+#else /* defined(LINUX) && defined(__KERNEL__) */
+
+typedef struct _OS_LOCK_ *POS_LOCK;
+#if defined(LINUX)
+       typedef struct _OS_ATOMIC {IMG_INT counter;} ATOMIC_T;
+#elif defined(__QNXNTO__)
+       typedef struct _OS_ATOMIC {IMG_INT counter;} ATOMIC_T;
+#elif defined(_WIN32)
+       /*
+        * Dummy definition. WDDM doesn't use Services, but some headers
+        * still have to be shared. This is one such case.
+        */
+       typedef struct _OS_ATOMIC {IMG_INT counter;} ATOMIC_T;
+#else
+       #error "Please type-define an atomic lock for this environment"
+#endif
+
+#endif /* defined(LINUX) && defined(__KERNEL__) */
+
+typedef enum
+{
+       LOCK_TYPE_NONE                  = 0x00,
+
+       LOCK_TYPE_MASK                  = 0x0F,
+       LOCK_TYPE_PASSIVE               = 0x01,         /* Passive level lock e.g. mutex, system may promote to dispatch */
+       LOCK_TYPE_DISPATCH              = 0x02,         /* Dispatch level lock e.g. spin lock, may be used in ISR/MISR */
+
+       LOCK_TYPE_INSIST_FLAG   = 0x80,         /* When set caller can guarantee lock not used in ISR/MISR */
+       LOCK_TYPE_PASSIVE_ONLY  = LOCK_TYPE_INSIST_FLAG | LOCK_TYPE_PASSIVE
+
+} LOCK_TYPE;
+#endif /* _LOCK_TYPES_H_ */
diff --git a/drivers/gpu/rogue_m/include/pdumpdefs.h b/drivers/gpu/rogue_m/include/pdumpdefs.h
new file mode 100644 (file)
index 0000000..e6c7f07
--- /dev/null
@@ -0,0 +1,202 @@
+/*************************************************************************/ /*!
+@File
+@Title          PDUMP definitions header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    PDUMP definitions header
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__PDUMPDEFS_H__)
+#define __PDUMPDEFS_H__
+
+/*! PDump Pixel Format Enumeration */
+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_F16F16F16F16 = 49,
+       PVRSRV_PDUMP_PIXEL_FORMAT_A4 = 50,
+       PVRSRV_PDUMP_PIXEL_FORMAT_ARGB2101010 = 51,
+       PVRSRV_PDUMP_PIXEL_FORMAT_RSGSBS888 = 52,
+       PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32F32 = 53,
+       PVRSRV_PDUMP_PIXEL_FORMAT_F16F16 = 54,
+       PVRSRV_PDUMP_PIXEL_FORMAT_F32F32 = 55,
+       PVRSRV_PDUMP_PIXEL_FORMAT_F16F16F16 = 56,
+       PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32 = 57,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U8 = 58,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U8U8 = 59,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U16 = 60,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U16U16 = 61,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U16U16U16U16 = 62,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U32 = 63,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U32U32 = 64,
+       PVRSRV_PDUMP_PIXEL_FORMAT_U32U32U32U32 = 65,
+       PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32 = 66,
+       
+       PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PDUMP_PIXEL_FORMAT;
+
+/*! PDump addrmode */
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT                  0
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_MASK                   0x000000FF 
+
+#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT                        8
+#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_NEGATIVE             (1 << PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_SHIFT               12
+#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_MASK                        0x000FF000
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT                            20
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_MASK                             0x00F00000
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT                   24
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT                  28
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_MASK                   0xF0000000
+
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_STRIDE                 (0 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE1 (1 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE2 (2 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE3 (3 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE4 (4 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE5 (5 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE6 (6 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE7 (7 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_TWIDDLED               (9 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_PAGETILED              (11 << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_NONE                             (0 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_DIRECT               (1 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_DIRECT              (2 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_32X2_DIRECT              (3 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT             (4 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT            (5 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT_4TILE       (6 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT_4TILE      (7 << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBC_DECOR                                        (1 << PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_BASE                   (1 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_ENHANCED               (2 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V2                             (3 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+
+/*! PDump Poll Operator */
+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;
+
+
+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE                 75  /*!< Max length of a pdump log file name */
+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE                  350 /*!< Max length of a pdump comment */
+
+/*!
+       PDump MMU type
+       (Maps to values listed in "PowerVR Tools.Pdump2 Script Functions.doc" Sec 2.13)
+*/
+typedef enum
+{
+       PDUMP_MMU_TYPE_4KPAGE_32BIT_STDTILE     = 1,
+       PDUMP_MMU_TYPE_VARPAGE_32BIT_STDTILE    = 2,
+       PDUMP_MMU_TYPE_4KPAGE_36BIT_EXTTILE     = 3,
+       PDUMP_MMU_TYPE_4KPAGE_32BIT_EXTTILE     = 4,
+       PDUMP_MMU_TYPE_4KPAGE_36BIT_STDTILE     = 5,
+       PDUMP_MMU_TYPE_VARPAGE_40BIT                    = 6,
+       PDUMP_MMU_TYPE_VIDEO_40BIT_STDTILE              = 7,
+       PDUMP_MMU_TYPE_VIDEO_40BIT_EXTTILE              = 8,
+       PDUMP_MMU_TYPE_LAST
+} PDUMP_MMU_TYPE;
+
+#endif /* __PDUMPDEFS_H__ */
+
+/*****************************************************************************
+ End of file (pdumpdefs.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/pvr_debug.h b/drivers/gpu/rogue_m/include/pvr_debug.h
new file mode 100644 (file)
index 0000000..ec32e51
--- /dev/null
@@ -0,0 +1,478 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Debug Declarations
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Provides debug functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_DEBUG_H__
+#define __PVR_DEBUG_H__
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+
+#if defined(_MSC_VER)
+#      define MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
+#else
+#      define MSC_SUPPRESS_4127
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define PVR_MAX_DEBUG_MESSAGE_LEN      (512)   /*!< Max length of a Debug Message */
+
+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
+#define DBGPRIV_FATAL                  0x001UL  /*!< Debug-Fatal. Privately used by pvr_debug. */
+#define DBGPRIV_ERROR                  0x002UL  /*!< Debug-Error. Privately used by pvr_debug. */
+#define DBGPRIV_WARNING                        0x004UL  /*!< Debug-Warning. Privately used by pvr_debug. */
+#define DBGPRIV_MESSAGE                        0x008UL  /*!< Debug-Message. Privately used by pvr_debug. */
+#define DBGPRIV_VERBOSE                        0x010UL  /*!< Debug-Verbose. Privately used by pvr_debug. */
+#define DBGPRIV_CALLTRACE              0x020UL  /*!< Debug-CallTrace. Privately used by pvr_debug. */
+#define DBGPRIV_ALLOC                  0x040UL  /*!< Debug-Alloc. Privately used by pvr_debug. */
+#define DBGPRIV_BUFFERED               0x080UL  /*!< Debug-Buffered. Privately used by pvr_debug. */
+#define DBGPRIV_DEBUG                  0x100UL  /*!< Debug-AdHoc-Debug. Never submitted. Privately used by pvr_debug. */
+#define DBGPRIV_DBGDRV_MESSAGE 0x200UL  /*!< Debug-DbgDrivMessage. Privately used by pvr_debug. */
+#define DBGPRIV_LAST                   0x200UL  /*!< Always set to highest mask value. Privately used by pvr_debug. */
+
+
+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
+#define PVRSRV_NEED_PVR_ASSERT
+#endif
+
+//zxl: Force open debug info.  gPVRDebugLevel is defined in pvr_debug.c
+//#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
+
+#if defined(__KERNEL__)
+       IMG_IMPORT const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
+#      define PVRSRVGETERRORSTRING PVRSRVGetErrorStringKM
+#else
+       IMG_IMPORT const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
+#      define PVRSRVGETERRORSTRING PVRSRVGetErrorString
+#endif
+
+/* PVR_ASSERT() and PVR_DBG_BREAK handling */
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+/* Unfortunately the klocworks static analysis checker doesn't understand our
+ * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
+ * macros in a special way when the code is analysed by klocworks avoids
+ * them. */
+#if defined(__KLOCWORK__) 
+  #define PVR_ASSERT(x) do { if (!(x)) abort(); } while (0)
+#else /* ! __KLOCWORKS__ */
+
+#if defined(_WIN32)
+#define PVR_ASSERT(expr) do                                                                    \
+       {                                                                                                                       \
+               MSC_SUPPRESS_4127                                                                               \
+               if (!(expr))                                                                                    \
+               {                                                                                                               \
+                       PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__,\
+                                         "*** Debug assertion failed!");                       \
+                       __debugbreak();                                                                         \
+               }                                                                                                               \
+       MSC_SUPPRESS_4127                                                                                       \
+       } while (0)
+
+#else
+
+#if defined(LINUX) && defined(__KERNEL__)
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+/* In Linux kernel mode, use BUG() directly. This produces the correct
+   filename and line number in the panic message. */
+#define PVR_ASSERT(EXPR) do                                                                                    \
+       {                                                                                                                               \
+               if (!(EXPR))                                                                                            \
+               {                                                                                                                       \
+                       PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__,    \
+                                                         "Debug assertion failed!");                   \
+                       BUG();                                                                                                  \
+               }                                                                                                                       \
+       } while (0)
+
+#else /* defined(LINUX) && defined(__KERNEL__) */
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
+                                                                                                          IMG_UINT32 ui32Line,
+                                                                                                          const IMG_CHAR *pszAssertion)
+#if defined(__GNUC__)
+       __attribute__((noreturn))
+#endif
+       ;
+
+#if defined(_MSC_VER)
+/* This alternate definition is for MSVC, which warns about do {} while (0) */
+#define PVR_ASSERT(EXPR)    MSC_SUPPRESS_4127                                                                          \
+                                                       if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__)
+#else
+#define PVR_ASSERT(EXPR) do                                                                            \
+       {                                                                                                                       \
+               if (!(EXPR))                                                                                    \
+                       PVRSRVDebugAssertFail(__FILE__, __LINE__, #EXPR);       \
+       } while (0)
+#endif
+
+#endif /* defined(LINUX) && defined(__KERNEL__) */
+#endif /* __KLOCWORKS__ */
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT)*/
+
+#if defined(__KLOCWORK__)
+       #define PVR_DBG_BREAK do { abort(); } while (0)
+#else
+       #if defined (WIN32)
+               #define PVR_DBG_BREAK __debugbreak();   /*!< Implementation of PVR_DBG_BREAK for (non-WinCE) Win32 */
+       #else
+               #if defined(PVR_DBG_BREAK_ASSERT_FAIL)
+               /*!< Implementation of PVR_DBG_BREAK that maps onto PVRSRVDebugAssertFail */
+                       #if defined(_WIN32)
+                               #define PVR_DBG_BREAK   DBG_BREAK
+                       #else
+                               #if defined(LINUX) && defined(__KERNEL__)
+                                       #define PVR_DBG_BREAK BUG()
+                               #else
+                                       #define PVR_DBG_BREAK   PVRSRVDebugAssertFail(__FILE__, __LINE__, "PVR_DBG_BREAK")
+                               #endif
+                       #endif
+               #else
+                       /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
+                       #define PVR_DBG_BREAK
+               #endif
+       #endif
+#endif
+
+
+#else  /* defined(PVRSRV_NEED_PVR_ASSERT) */
+    /* Unfortunately the klocworks static analysis checker doesn't understand our
+     * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
+     * macros in a special way when the code is analysed by klocworks avoids
+     * them. */
+    #if defined(__KLOCWORK__) 
+        #define PVR_ASSERT(EXPR) do { if (!(EXPR)) abort(); } while (0)
+    #else
+        #define PVR_ASSERT(EXPR) (IMG_VOID)(EXPR) /*!< Null Implementation of PVR_ASSERT (does nothing) */
+    #endif
+
+    #define PVR_DBG_BREAK    /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
+
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+
+/* PVR_DPF() handling */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+       /* New logging mechanism */
+       #define PVR_DBG_FATAL           DBGPRIV_FATAL
+       #define PVR_DBG_ERROR           DBGPRIV_ERROR
+       #define PVR_DBG_WARNING         DBGPRIV_WARNING
+       #define PVR_DBG_MESSAGE         DBGPRIV_MESSAGE
+       #define PVR_DBG_VERBOSE         DBGPRIV_VERBOSE
+       #define PVR_DBG_CALLTRACE       DBGPRIV_CALLTRACE
+       #define PVR_DBG_ALLOC           DBGPRIV_ALLOC
+       #define PVR_DBG_BUFFERED        DBGPRIV_BUFFERED
+       #define PVR_DBG_DEBUG           DBGPRIV_DEBUG
+       #define PVR_DBGDRIV_MESSAGE     DBGPRIV_DBGDRV_MESSAGE
+
+       /* These levels are always on with PVRSRV_NEED_PVR_DPF */
+       #define __PVR_DPF_0x001UL(...) PVRSRVDebugPrintf(DBGPRIV_FATAL, __VA_ARGS__)
+       #define __PVR_DPF_0x002UL(...) PVRSRVDebugPrintf(DBGPRIV_ERROR, __VA_ARGS__)
+       #define __PVR_DPF_0x080UL(...) PVRSRVDebugPrintf(DBGPRIV_BUFFERED, __VA_ARGS__)
+
+       /*
+         The AdHoc-Debug level is only supported when enabled in the local
+         build environment and may need to be used in both debug and release
+         builds. An error is generated in the formal build if it is checked in.
+       */
+#if defined(PVR_DPF_ADHOC_DEBUG_ON)
+       #define __PVR_DPF_0x100UL(...) PVRSRVDebugPrintf(DBGPRIV_DEBUG, __VA_ARGS__)
+#else
+    /* Use an undefined token here to stop compilation dead in the offending module */
+       #define __PVR_DPF_0x100UL(...) __ERROR__PVR_DBG_DEBUG_is_in_use_but_has_not_been_enabled__Note_Debug_DPF_must_not_be_checked_in__Define_PVR_DPF_ADHOC_DEBUG_ON_for_testing
+#endif
+
+       /* Some are compiled out completely in release builds */
+#if defined(DEBUG)
+       #define __PVR_DPF_0x004UL(...) PVRSRVDebugPrintf(DBGPRIV_WARNING, __VA_ARGS__)
+       #define __PVR_DPF_0x008UL(...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, __VA_ARGS__)
+       #define __PVR_DPF_0x010UL(...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, __VA_ARGS__)
+       #define __PVR_DPF_0x020UL(...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, __VA_ARGS__)
+       #define __PVR_DPF_0x040UL(...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, __VA_ARGS__)
+       #define __PVR_DPF_0x200UL(...) PVRSRVDebugPrintf(DBGPRIV_DBGDRV_MESSAGE, __VA_ARGS__)
+#else
+       #define __PVR_DPF_0x004UL(...)
+       #define __PVR_DPF_0x008UL(...)
+       #define __PVR_DPF_0x010UL(...)
+       #define __PVR_DPF_0x020UL(...)
+       #define __PVR_DPF_0x040UL(...)
+       #define __PVR_DPF_0x200UL(...)
+#endif
+
+       /* Translate the different log levels to separate macros
+        * so they can each be compiled out.
+        */
+//zxl: Force open debug info.  gPVRDebugLevel is defined in pvr_debug.c
+#if 1
+       #define __PVR_DPF(lvl, ...) __PVR_DPF_ ## lvl (__FILE__, __LINE__, __VA_ARGS__)
+#else
+       #define __PVR_DPF(lvl, ...) __PVR_DPF_ ## lvl ("", 0, __VA_ARGS__)
+#endif
+
+       /* Get rid of the double bracketing */
+       #define PVR_DPF(x) __PVR_DPF x
+
+       #define PVR_LOG_ERROR(_rc, _call) \
+               PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__));
+
+       #define PVR_LOG_IF_ERROR(_rc, _call) do \
+               { if (_rc != PVRSRV_OK) \
+                       PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+
+       #define PVR_LOGR_IF_ERROR(_rc, _call) do \
+               { if (_rc != PVRSRV_OK) { \
+                       PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+                       return (_rc); }\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+       #define PVR_LOGRN_IF_ERROR(_rc, _call) do \
+               { if (_rc != PVRSRV_OK) { \
+                       PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+                       return; }\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+       #define PVR_LOGG_IF_ERROR(_rc, _call, _go) do \
+               { if (_rc != PVRSRV_OK) { \
+                       PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+                       goto _go; }\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+       #define PVR_LOG_IF_FALSE(_expr, _msg) do \
+               { if (!(_expr)) \
+                       PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+       #define PVR_LOGR_IF_FALSE(_expr, _msg, _rc) do \
+               { if (!(_expr)) { \
+                       PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+                       return (_rc); }\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+       #define PVR_LOGG_IF_FALSE(_expr, _msg, _go) do \
+               { if (!(_expr)) { \
+                       PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+                       goto _go; }\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+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);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintfDumpCCB(void);
+
+#else  /* defined(PVRSRV_NEED_PVR_DPF) */
+
+       #define PVR_DPF(X)  /*!< Null Implementation of PowerVR Debug Printf (does nothing) */
+
+       #define PVR_LOG_ERROR(_rc, _call) (void)(_rc)
+       #define PVR_LOG_IF_ERROR(_rc, _call) (void)(_rc)
+       #define PVR_LOGR_IF_ERROR(_rc, _call) do { if (_rc != PVRSRV_OK) { return (_rc); } MSC_SUPPRESS_4127 } while(0)
+       #define PVR_LOGRN_IF_ERROR(_rc, _call) do { if (_rc != PVRSRV_OK) { return; } MSC_SUPPRESS_4127 } while(0)
+       #define PVR_LOGG_IF_ERROR(_rc, _call, _go) do { if (_rc != PVRSRV_OK) { goto _go; } MSC_SUPPRESS_4127 } while(0)
+       
+       #define PVR_LOG_IF_FALSE(_expr, _msg) (void)(_expr)
+       #define PVR_LOGR_IF_FALSE(_expr, _msg, _rc) do { if (!(_expr)) { return (_rc); } MSC_SUPPRESS_4127 } while(0)
+       #define PVR_LOGG_IF_FALSE(_expr, _msg, _go) do { if (!(_expr)) { goto _go; } MSC_SUPPRESS_4127 } while(0)
+
+       #undef PVR_DPF_FUNCTION_TRACE_ON
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+
+#if defined(PVR_DPF_FUNCTION_TRACE_ON)
+
+       #define PVR_DPF_ENTERED \
+        PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered", __func__, __LINE__))
+
+       #define PVR_DPF_ENTERED1(p1) \
+               PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered (0x%lx)", __func__, __LINE__, ((unsigned long)p1)))
+
+       #define PVR_DPF_RETURN_RC(a) \
+        do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned %d", __func__, __LINE__, (_r))); return (_r); MSC_SUPPRESS_4127 } while (0)
+
+       #define PVR_DPF_RETURN_RC1(a,p1) \
+               do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned %d (0x%lx)", __func__, __LINE__, (_r), ((unsigned long)p1))); return (_r); MSC_SUPPRESS_4127 } while (0)
+
+       #define PVR_DPF_RETURN_VAL(a) \
+               do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned with value", __func__, __LINE__ )); return (a); MSC_SUPPRESS_4127 } while (0)
+
+       #define PVR_DPF_RETURN_OK \
+               do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned ok", __func__, __LINE__)); return PVRSRV_OK; MSC_SUPPRESS_4127 } while (0)
+
+       #define PVR_DPF_RETURN \
+               do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned", __func__, __LINE__)); return; MSC_SUPPRESS_4127 } while (0)
+
+       #if !defined(DEBUG)
+       #error PVR DPF Function trace enabled in release build, rectify
+       #endif
+
+#else /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
+
+       #define PVR_DPF_ENTERED
+       #define PVR_DPF_ENTERED1(p1)
+       #define PVR_DPF_RETURN_RC(a)     return (a)
+       #define PVR_DPF_RETURN_RC1(a,p1) return (a)
+       #define PVR_DPF_RETURN_VAL(a)    return (a)
+       #define PVR_DPF_RETURN_OK                return PVRSRV_OK
+       #define PVR_DPF_RETURN                   return
+
+#endif /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
+
+
+/* PVR_TRACE() handling */
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+       #define PVR_TRACE(X)    PVRSRVTrace X    /*!< PowerVR Debug Trace Macro */
+       /* Empty string implementation that is -O0 build friendly */
+       #define PVR_TRACE_EMPTY_LINE()  PVR_TRACE(("%s", ""))
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
+       IMG_FORMAT_PRINTF(1, 2);
+
+#else /* defined(PVRSRV_NEED_PVR_TRACE) */
+    /*! Null Implementation of PowerVR Debug Trace Macro (does nothing) */
+       #define PVR_TRACE(X)    
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_64BITS_TO_32BITS)
+#endif
+       INLINE static IMG_UINT32 TRUNCATE_64BITS_TO_32BITS(IMG_UINT64 uiInput)
+       {
+                IMG_UINT32 uiTruncated;
+
+                uiTruncated = (IMG_UINT32)uiInput;
+                PVR_ASSERT(uiInput == uiTruncated);
+                return uiTruncated;
+       }
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_64BITS_TO_SIZE_T)
+#endif
+       INLINE static IMG_SIZE_T TRUNCATE_64BITS_TO_SIZE_T(IMG_UINT64 uiInput)
+       {
+                IMG_SIZE_T uiTruncated;
+
+                uiTruncated = (IMG_SIZE_T)uiInput;
+                PVR_ASSERT(uiInput == uiTruncated);
+                return uiTruncated;
+       }
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_SIZE_T_TO_32BITS)
+#endif
+       INLINE static IMG_UINT32 TRUNCATE_SIZE_T_TO_32BITS(IMG_SIZE_T uiInput)
+       {
+                IMG_UINT32 uiTruncated;
+
+                uiTruncated = (IMG_UINT32)uiInput;
+                PVR_ASSERT(uiInput == uiTruncated);
+                return uiTruncated;
+       }
+
+
+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */
+       #define TRUNCATE_64BITS_TO_32BITS(expr) ((IMG_UINT32)(expr))
+       #define TRUNCATE_64BITS_TO_SIZE_T(expr) ((IMG_SIZE_T)(expr))
+       #define TRUNCATE_SIZE_T_TO_32BITS(expr) ((IMG_UINT32)(expr))
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+/* Macros used to trace calls */
+#if defined(DEBUG)
+       #define PVR_DBG_FILELINE , __FILE__, __LINE__
+       #define PVR_DBG_FILELINE_PARAM , const IMG_CHAR *pszaFile, IMG_UINT32 ui32Line
+       #define PVR_DBG_FILELINE_ARG , pszaFile, ui32Line
+       #define PVR_DBG_FILELINE_FMT " %s:%u"
+       #define PVR_DBG_FILELINE_UNREF() do { PVR_UNREFERENCED_PARAMETER(pszaFile); \
+                               PVR_UNREFERENCED_PARAMETER(ui32Line); } while(0)
+#else
+       #define PVR_DBG_FILELINE
+       #define PVR_DBG_FILELINE_PARAM
+       #define PVR_DBG_FILELINE_ARG
+       #define PVR_DBG_FILELINE_FMT
+       #define PVR_DBG_FILELINE_UNREF()
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_DEBUG_H__ */
+
+/******************************************************************************
+ End of file (pvr_debug.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/pvr_fd_sync_kernel.h b/drivers/gpu/rogue_m/include/pvr_fd_sync_kernel.h
new file mode 100644 (file)
index 0000000..1134333
--- /dev/null
@@ -0,0 +1,114 @@
+/*************************************************************************/ /*!
+@File           pvr_fd_sync_kernel.h
+@Title          Kernel/userspace interface definitions to use the kernel sync
+                driver
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+
+#ifndef _PVR_FD_SYNC_KERNEL_H_
+#define _PVR_FD_SYNC_KERNEL_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define PVR_SYNC_MAX_QUERY_FENCE_POINTS 14
+
+#define PVR_SYNC_IOC_MAGIC 'W'
+
+#define PVR_SYNC_IOC_CREATE_FENCE \
+ _IOWR(PVR_SYNC_IOC_MAGIC, 0, struct pvr_sync_create_fence_ioctl_data)
+
+#define PVR_SYNC_IOC_ENABLE_FENCING \
+ _IOW(PVR_SYNC_IOC_MAGIC,  1, struct pvr_sync_enable_fencing_ioctl_data)
+
+#define PVR_SYNC_IOC_ALLOC_FENCE \
+ _IOWR(PVR_SYNC_IOC_MAGIC, 3, struct pvr_sync_alloc_fence_ioctl_data)
+
+#define PVR_SYNC_IOC_RENAME \
+ _IOWR(PVR_SYNC_IOC_MAGIC, 4, struct pvr_sync_rename_ioctl_data)
+
+#define PVR_SYNC_IOC_FORCE_SW_ONLY \
+ _IO(PVR_SYNC_IOC_MAGIC,   5)
+
+#define PVRSYNC_MODNAME "pvr_sync"
+
+struct pvr_sync_alloc_fence_ioctl_data
+{
+       /* Output */
+       int                             iFenceFd;
+       int                             bTimelineIdle;
+}
+__attribute__((packed, aligned(8)));
+
+struct pvr_sync_create_fence_ioctl_data
+{
+       /* Input */
+       int                             iAllocFenceFd;
+       char                            szName[32];
+
+       /* Output */
+       int                             iFenceFd;
+}
+__attribute__((packed, aligned(8)));
+
+struct pvr_sync_enable_fencing_ioctl_data
+{
+       /* Input */
+       int                             bFencingEnabled;
+}
+__attribute__((packed, aligned(8)));
+
+struct pvr_sync_pt_info {
+       /* Output */
+       __u32 id;
+       __u32 ui32FWAddr;
+       __u32 ui32CurrOp;
+       __u32 ui32NextOp;
+       __u32 ui32TlTaken;
+} __attribute__((packed, aligned(8)));
+
+struct pvr_sync_rename_ioctl_data
+{
+       /* Input */
+       char szName[32];
+} __attribute__((packed, aligned(8)));
+
+#endif /* _PVR_FD_SYNC_KERNEL_H_ */
diff --git a/drivers/gpu/rogue_m/include/pvrmodule.h b/drivers/gpu/rogue_m/include/pvrmodule.h
new file mode 100644 (file)
index 0000000..267c7b6
--- /dev/null
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@Title          Module Author and License.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef        _PVRMODULE_H_
+#define        _PVRMODULE_H_
+
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("Dual MIT/GPL");
+
+#endif /* _PVRMODULE_H_ */
diff --git a/drivers/gpu/rogue_m/include/pvrsrv_device_types.h b/drivers/gpu/rogue_m/include/pvrsrv_device_types.h
new file mode 100644 (file)
index 0000000..de54d87
--- /dev/null
@@ -0,0 +1,112 @@
+/*************************************************************************/ /*!
+@File
+@Title          PowerVR device type definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__PVRSRV_DEVICE_TYPES_H__)
+#define __PVRSRV_DEVICE_TYPES_H__
+
+#include "img_types.h"
+
+#define PVRSRV_MAX_DEVICES             16      /*!< Largest supported number of devices on the system */
+
+/*!
+ ******************************************************************************
+ * List of known device types.
+ *****************************************************************************/
+typedef enum PVRSRV_DEVICE_TYPE
+{
+       PVRSRV_DEVICE_TYPE_UNKNOWN                      = 0,  /*!< Unknown device type */
+       PVRSRV_DEVICE_TYPE_MBX1                         = 1,  /*!< MBX1 */
+       PVRSRV_DEVICE_TYPE_MBX1_LITE            = 2,  /*!< MBX1 Lite */
+       PVRSRV_DEVICE_TYPE_M24VA                        = 3,  /*!< M24VA */
+       PVRSRV_DEVICE_TYPE_MVDA2                        = 4,  /*!< MVDA2 */
+       PVRSRV_DEVICE_TYPE_MVED1                        = 5,  /*!< MVED1 */
+       PVRSRV_DEVICE_TYPE_MSVDX                        = 6,  /*!< MSVDX */
+       PVRSRV_DEVICE_TYPE_SGX                          = 7,  /*!< SGX */
+       PVRSRV_DEVICE_TYPE_VGX                          = 8,  /*!< VGX */
+       PVRSRV_DEVICE_TYPE_EXT                          = 9,  /*!< 3rd party devices take ext type */
+       PVRSRV_DEVICE_TYPE_RGX                          = 10, /*!< RGX */
+
+    PVRSRV_DEVICE_TYPE_LAST             = 10, /*!< Last device type */
+
+       PVRSRV_DEVICE_TYPE_FORCE_I32            = 0x7fffffff /*!< Force enum to be 32-bit width */
+
+} PVRSRV_DEVICE_TYPE;
+
+
+/*!
+ *****************************************************************************
+ * List of known device classes.
+ *****************************************************************************/
+typedef enum _PVRSRV_DEVICE_CLASS_
+{
+       PVRSRV_DEVICE_CLASS_3D                          = 0 ,       /*!< 3D Device Class */
+       PVRSRV_DEVICE_CLASS_DISPLAY                     = 1 ,       /*!< Display Device Class */
+       PVRSRV_DEVICE_CLASS_BUFFER                      = 2 ,       /*!< Buffer Class */
+       PVRSRV_DEVICE_CLASS_VIDEO                       = 3 ,       /*!< Video Device Class */
+
+       PVRSRV_DEVICE_CLASS_FORCE_I32           = 0x7fffffff /* Force enum to be at least 32-bits wide */
+
+} PVRSRV_DEVICE_CLASS;
+
+
+/*!
+ ******************************************************************************
+ * Device identifier structure
+ *****************************************************************************/
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+       PVRSRV_DEVICE_TYPE              eDeviceType;            /*!< Identifies the type of the device */
+       PVRSRV_DEVICE_CLASS             eDeviceClass;           /*!< Identifies more general class of device - display/3d/mpeg etc */
+       IMG_UINT32                              ui32DeviceIndex;        /*!< Index of the device within the system */
+       IMG_CHAR                                *pszPDumpDevName;       /*!< Pdump memory bank name */
+       IMG_CHAR                                *pszPDumpRegName;       /*!< Pdump register bank name */
+
+} PVRSRV_DEVICE_IDENTIFIER;
+
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+#endif /* __PVRSRV_DEVICE_TYPES_H__ */
+
diff --git a/drivers/gpu/rogue_m/include/pvrsrv_devmem.h b/drivers/gpu/rogue_m/include/pvrsrv_devmem.h
new file mode 100644 (file)
index 0000000..f6967a7
--- /dev/null
@@ -0,0 +1,577 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management core
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Client side part of device memory management -- This
+                file defines the exposed Services API to core memory management
+                functions.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_DEVMEM_H
+#define PVRSRV_DEVMEM_H
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "devicemem_typedefs.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+#include "services.h"  /* For PVRSRV_DEV_DATA */
+#include "sync_external.h"
+
+/*
+  Device memory contexts, heaps and memory descriptors are passed
+  through to underlying memory APIs directly, but are to be regarded
+  as an opaque handle externally.
+*/
+typedef DEVMEM_CONTEXT *PVRSRV_DEVMEMCTX;       /*!< Device-Mem Client-Side Interface: Typedef for Context Ptr */
+typedef DEVMEM_HEAP *PVRSRV_HEAP;               /*!< Device-Mem Client-Side Interface: Typedef for Heap Ptr */
+typedef DEVMEM_MEMDESC *PVRSRV_MEMDESC;         /*!< Device-Mem Client-Side Interface: Typedef for Memory Descriptor Ptr */
+typedef DEVMEM_EXPORTCOOKIE PVRSRV_DEVMEM_EXPORTCOOKIE;     /*!< Device-Mem Client-Side Interface: Typedef for Export Cookie */
+typedef DEVMEM_FLAGS_T PVRSRV_MEMMAP_FLAGS_T;               /*!< Device-Mem Client-Side Interface: Typedef for Memory-Mapping Flags Enum */
+typedef DEVMEM_SERVER_EXPORTCOOKIE PVRSRV_DEVMEM_SERVER_EXPORTCOOKIE;   /*!< Device-Mem Client-Side Interface: Typedef for Server Export Cookie */
+
+/* N.B.  Flags are now defined in pvrsrv_memallocflags.h as they need
+         to be omnipresent. */
+
+/*
+ *
+ *  API functions
+ *
+ */
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCreateDeviceMemContext
+@Description    Creates a device memory context.  There is a one-to-one
+                correspondence between this context data structure and the top
+                level MMU page table (known as the Page Catalogue, in the case of a
+                3-tier MMU).  It is intended that a process with its own virtual
+                space on the CPU will also have its own virtual space on the GPU.
+                Thus there is loosely a one-to-one correspondence between process
+                and device memory context, but this is not enforced at this API.
+                Every process must create the device memory context before any
+                memory allocations are made, and is responsible for freeing all
+                such allocations before destroying the context
+     
+                This is a wrapper function above the "bare-metal" device memory
+                context creation function which would create just a context and no
+                heaps.  This function will also create the heaps, according to the
+                heap config that the device specific initialization code has
+                nominated for use by this API.
+     
+                The number of heaps thus created is returned to the caller, such
+                that the caller can allocate an array and the call in to fetch
+                details of each heap, or look up the heap with the "Find Heap" API
+                described below.
+     
+                In order to derive the details of the MMU configuration for the
+                device, and for retrieving the "bridge handle" for communication
+                internally in services, is is necessary to pass in the
+                PVRSRV_DEV_DATA object as populated with a prior call to
+                PVRSRVAcquireDeviceData()
+@Input          psDev           dev data
+@Output         phCtxOut        On success, the returned DevMem Context. The
+                                caller is responsible for providing storage
+                                for this.
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+extern IMG_IMPORT PVRSRV_ERROR
+PVRSRVCreateDeviceMemContext(const PVRSRV_DEV_DATA *psDev,
+                              PVRSRV_DEVMEMCTX *phCtxOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDestroyDeviceMemContext
+@Description    Destroy cannot fail.  Well.  It shouldn't, assuming the caller
+                has obeyed the protocol, i.e. has freed all his allocations 
+                beforehand.
+@Input          hCtx            Handle to a DevMem Context
+@Return         None
+*/ /***************************************************************************/
+extern IMG_IMPORT IMG_VOID
+PVRSRVDestroyDeviceMemContext(PVRSRV_DEVMEMCTX hCtx);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVFindHeapByName
+@Description    Returns the heap handle for the named heap which is assumed to
+                exist in this context. PVRSRV_HEAP *phHeapOut,  
+
+                N.B.  No need for acquire/release semantics here, as when using
+                this wrapper layer, the heaps are automatically instantiated at
+                context creation time and destroyed when the context is 
+                destroyed.
+
+                The caller is required to know the heap names already as these 
+                will vary from device to device and from purpose to purpose.
+@Input          hCtx            Handle to a DevMem Context
+@Input          pszHeapName     Name of the heap to look for
+@Output         phHeapOut       a handle to the heap, for use in future calls 
+                                to OpenAllocation / AllocDeviceMemory / Map 
+                                DeviceClassMemory, etc. (The PVRSRV_HEAP type
+                                to be regarded by caller as an opaque, but 
+                                strongly typed, handle)
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+extern PVRSRV_ERROR
+PVRSRVFindHeapByName(PVRSRV_DEVMEMCTX hCtx,
+                     const IMG_CHAR *pszHeapName,
+                     PVRSRV_HEAP *phHeapOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDevmemGetHeapBaseDevVAddr
+@Description    returns the device virtual address of the base of the heap.
+@Input          hHeap           Handle to a Heap
+@Output         pDevVAddr       On success, the device virtual address of the
+                                base of the heap.
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVDevmemGetHeapBaseDevVAddr(PVRSRV_HEAP hHeap,
+                               IMG_DEV_VIRTADDR *pDevVAddr);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAllocDeviceMem
+@Description    Allocate memory from the specified heap, acquiring physical
+                memory from OS as we go and mapping this into
+                the GPU (mandatorily) and CPU (optionally)
+
+                Size must be a positive integer multiple of alignment, or, to
+                put it another way, the uiLog2Align LSBs should all be zero, but
+                at least one other bit should not be.
+
+                Caller to take charge of the PVRSRV_MEMDESC (the memory
+                descriptor) which is to be regarded as an opaque handle.
+@Input          hHeap               Handle to the heap from which memory will be
+                                    allocated
+@Input          uiSize              Amount of memory to be allocated.
+@Input          uiLog2Align         LOG2 of the required alignment
+@Input          uiMemAllocFlags     Allocation Flags
+@Input          pszText                Text to describe the allocation
+@Output         phMemDescOut        On success, the resulting memory descriptor
+@Return         PVRSRV_OK on success. Otherwise, a PVRSRV_ error code
+*/ /***************************************************************************/
+extern PVRSRV_ERROR
+PVRSRVAllocDeviceMem(PVRSRV_HEAP hHeap,
+                     IMG_DEVMEM_SIZE_T uiSize,
+                     IMG_DEVMEM_LOG2ALIGN_T uiLog2Align,
+                     PVRSRV_MEMALLOCFLAGS_T uiMemAllocFlags,
+                     IMG_PCHAR pszText,
+                     PVRSRV_MEMDESC *phMemDescOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVFreeDeviceMem
+@Description    Free that allocated by PVRSRVAllocDeviceMem (Memory descriptor 
+                will be destroyed)
+@Input          hMemDesc            Handle to the descriptor of the memory to be
+                                    freed
+@Return         None
+*/ /***************************************************************************/
+extern IMG_VOID
+PVRSRVFreeDeviceMem(PVRSRV_MEMDESC hMemDesc);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAcquireCPUMapping
+@Description    Causes the allocation referenced by this memory descriptor to be
+                mapped into cpu virtual memory, if it wasn't already, and the
+                CPU virtual address returned in the caller-provided location.
+
+                The caller must call PVRSRVReleaseCPUMapping to advise when he
+                has finished with the mapping.
+@Input          hMemDesc            Handle to the memory descriptor for which a
+                                    CPU mapping is required
+@Output         ppvCpuVirtAddrOut   On success, the caller's ptr is set to the
+                                    new CPU mapping
+@Return         PVRSRV_ERROR:       PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+*/ /***************************************************************************/
+extern PVRSRV_ERROR
+PVRSRVAcquireCPUMapping(PVRSRV_MEMDESC hMemDesc,
+                        IMG_VOID **ppvCpuVirtAddrOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReleaseCPUMapping
+@Description    Relinquishes the cpu mapping acquired with 
+                PVRSRVAcquireCPUMapping()
+@Input          hMemDesc            Handle of the memory descriptor
+@Return         None
+*/ /***************************************************************************/
+extern IMG_VOID
+PVRSRVReleaseCPUMapping(PVRSRV_MEMDESC hMemDesc);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVMapToDevice
+@Description    Map allocation into the device MMU. This function must only be
+                called once, any further calls will return
+                PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED
+
+                The caller must call PVRSRVReleaseDeviceMapping when they
+                are finished with the mapping.
+
+@Input          hMemDesc            Handle of the memory descriptor
+@Input          hHeap               Device heap to map the allocation into
+@Output         psDevVirtAddrOut    Device virtual address
+@Return         PVRSRV_ERROR:       PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+*/ /***************************************************************************/
+extern PVRSRV_ERROR
+PVRSRVMapToDevice(PVRSRV_MEMDESC hMemDesc,
+                                 PVRSRV_HEAP hHeap,
+                                 IMG_DEV_VIRTADDR *psDevVirtAddrOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAcquireDeviceMapping
+@Description    Acquire a reference on the device mapping the allocation.
+                If the allocation wasn't mapped into the device then 
+                and the device virtual address returned in the
+                PVRSRV_ERROR_DEVICEMEM_NO_MAPPING will be returned as
+                PVRSRVMapToDevice must be called first.
+
+                The caller must call PVRSRVReleaseDeviceMapping when they
+                are finished with the mapping.
+@Input          hMemDesc            Handle to the memory descriptor for which a
+                                    device mapping is required
+@Output         psDevVirtAddrOut    On success, the caller's ptr is set to the
+                                    new device mapping
+@Return         PVRSRV_ERROR:       PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+*/ /***************************************************************************/
+extern PVRSRV_ERROR
+PVRSRVAcquireDeviceMapping(PVRSRV_MEMDESC hMemDesc,
+                                                  IMG_DEV_VIRTADDR *psDevVirtAddrOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReleaseDeviceMapping
+@Description    Relinquishes the device mapping acquired with
+                PVRSRVAcquireDeviceMapping or PVRSRVMapToDevice
+@Input          hMemDesc            Handle of the memory descriptor
+@Return         None
+*/ /***************************************************************************/
+extern IMG_VOID
+PVRSRVReleaseDeviceMapping(PVRSRV_MEMDESC hMemDesc);
+
+/*************************************************************************/ /*!
+@Function       PVRSRVDevmemLocalImport
+
+@Description    Import a PMR that was created with this connection to services.
+
+@Input          hExtHandle              External memory handle
+
+@Input          uiFlags                 Import flags
+
+@Output         phMemDescPtr            Created MemDesc
+
+@Output         puiSizePtr              Size of the created MemDesc
+
+@Return         PVRSRV_OK is succesful
+*/
+/*****************************************************************************/
+PVRSRV_ERROR PVRSRVDevmemLocalImport(const PVRSRV_CONNECTION *psConnection,
+                                                                        IMG_HANDLE hExtHandle,
+                                                                        PVRSRV_MEMMAP_FLAGS_T uiFlags,
+                                                                        PVRSRV_MEMDESC *phMemDescPtr,
+                                                                        IMG_DEVMEM_SIZE_T *puiSizePtr);
+
+/*************************************************************************/ /*!
+@Function       PVRSRVDevmemGetImportUID
+
+@Description    Get the UID of the import that backs this MemDesc
+
+@Input          hMemDesc                MemDesc
+
+@Return         UID of import
+*/
+/*****************************************************************************/
+PVRSRV_ERROR PVRSRVDevmemGetImportUID(PVRSRV_MEMDESC hMemDesc,
+                                                                         IMG_UINT64 *pui64UID);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAllocExportableDevMem
+@Description    Allocate memory without mapping into device memory context.  This
+                memory is exported and ready to be mapped into the device memory
+                context of other processes, or to CPU only with 
+                PVRSRVMapMemoryToCPUOnly(). The caller agrees to later call 
+                PVRSRVFreeUnmappedExportedMemory(). The caller must give the page
+                size of the heap into which this memory may be subsequently 
+                mapped, or the largest of such page sizes if it may be mapped 
+                into multiple places.  This information is to be communicated in
+                the Log2Align field.
+
+                Size must be a positive integer multiple of the page size
+@Input          uiLog2Align         Log2 of the alignment required
+@Input          uiSize              the amount of memory to be allocated
+@Input          uiFlags             Allocation flags
+@Input          pszText                Text to describe the allocation
+@Output         hMemDesc
+@Return         PVRSRV_OK on success. Otherwise, a PVRSRV_ error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVAllocExportableDevMem(const PVRSRV_DEV_DATA *psDevData,
+                                                       IMG_DEVMEM_SIZE_T uiSize,
+                                                       IMG_DEVMEM_LOG2ALIGN_T uiLog2Align,
+                                                       PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                       IMG_PCHAR pszText,
+                                                       PVRSRV_MEMDESC *hMemDesc);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAllocSparseDevMem
+@Description    Allocate sparse memory without mapping into device memory context.
+                               Sparse memory is used where you have an allocation that has a
+                               logical size (i.e. the amount of VM space it will need when
+                               mapping it into a device) that is larger then the amount of
+                               physical memory that allocation will use. An example of this
+                               is a NPOT texture where the twiddling algorithm requires you
+                               to round the width and height to next POT and so you know there
+                               will be pages that are never accessed.
+
+                               This memory is can to be exported and mapped into the device
+                               memory context of other processes, or to CPU.
+
+                Size must be a positive integer multiple of the page size
+@Input          psDevData           Device to allocation the memory for
+@Input          uiSize              The logical size of allocation
+@Input          uiChunkSize         The size of the chunk
+@Input          ui32NumPhysChunks   The number of physical chunks required
+@Input          ui32NumVirtChunks   The number of virtual chunks required
+@Input                 pabMappingTable         Mapping table
+@Input          uiLog2Align         Log2 of the required alignment
+@Input          uiFlags             Allocation flags
+@Input          pszText                Text to describe the allocation
+@Output         hMemDesc
+@Return         PVRSRV_OK on success. Otherwise, a PVRSRV_ error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVAllocSparseDevMem(const PVRSRV_DEV_DATA *psDevData,
+                                               IMG_DEVMEM_SIZE_T uiSize,
+                                               IMG_DEVMEM_SIZE_T uiChunkSize,
+                                               IMG_UINT32 ui32NumPhysChunks,
+                                               IMG_UINT32 ui32NumVirtChunks,
+                                               IMG_BOOL *pabMappingTable,
+                                               IMG_DEVMEM_LOG2ALIGN_T uiLog2Align,
+                                               DEVMEM_FLAGS_T uiFlags,
+                                               IMG_PCHAR pszText,
+                                               PVRSRV_MEMDESC *hMemDesc);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetLog2PageSize
+@Description    Just call AFTER setting up the connection to the kernel module
+                otherwise it will run into an assert.
+                Gives the log2 of the page size that is currently utilised by
+                devmem.
+
+@Return         The page size
+*/ /***************************************************************************/
+
+IMG_UINT32 PVRSRVGetLog2PageSize(void);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetHeapLog2ImportAlignment
+@Description    Queries the import alignment of a passed heap.
+
+@Input          hHeap                   Heap that is queried
+@Output         puiLog2ImportAlignment  Log2 import alignment will be
+                                        returned in this
+
+@Return         PVRSRV_OK on success. Otherwise, a PVRSRV error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVGetHeapLog2ImportAlignment(PVRSRV_HEAP hHeap,
+                                 IMG_UINT32* puiLog2ImportAlignment);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVExport
+@Description    Given a memory allocation allocated with Devmem_Allocate(),
+                create a "cookie" that can be passed intact by the caller's own
+                choice of secure IPC to another process and used as the argument
+                to "map" to map this memory into a heap in the target processes.
+                N.B.  This can also be used to map into multiple heaps in one 
+                process, though that's not the intention.
+
+                Note, the caller must later call Unexport before freeing the
+                memory.
+@Input          hMemDesc        handle to the descriptor of the memory to be
+                                exported
+@Output         phExportCookie  On success, a handle to the exported cookie
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+PVRSRV_ERROR PVRSRVExportDevMem(PVRSRV_MEMDESC hMemDesc,
+                                                               PVRSRV_DEVMEM_EXPORTCOOKIE *phExportCookie);
+
+/**************************************************************************/ /*!
+@Function DevmemMakeServerExportClientExport
+@Description    This is a "special case" function for making a server export 
+                cookie which went through the direct bridge into an export 
+                cookie that can be passed through the client bridge.
+@Input          psConnection        Services connection
+@Input          hServerExportCookie server export cookie
+@Output         psExportCookie      ptr to export cookie
+@Return         PVRSRV_ERROR:       PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVMakeServerExportClientExport(const PVRSRV_CONNECTION *psConnection,
+                                   PVRSRV_DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie,
+                                   PVRSRV_DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+/**************************************************************************/ /*!
+@Function DevmemUnmakeServerExportClientExport
+@Description    Remove any associated resource from the Make operation
+@Input          psConnection        Services connection
+@Output         psExportCookie      ptr to export cookie
+@Return         PVRSRV_ERROR:       PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVUnmakeServerExportClientExport(const PVRSRV_CONNECTION *psConnection,
+                                   PVRSRV_DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVUnexport
+@Description    Undo the export caused by "PVRSRVExport" - note - it doesn't
+                actually tear down any mapping made by processes that received
+                the export cookie.  It will simply make the cookie null and void
+                and prevent further mappings.
+@Input          hMemDesc        handle to the descriptor of the memory which
+                                will no longer be exported
+@Output         phExportCookie  On success, the export cookie provided will be
+                                set to null
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+PVRSRV_ERROR PVRSRVUnexportDevMem(PVRSRV_MEMDESC hMemDesc,
+                                                                 PVRSRV_DEVMEM_EXPORTCOOKIE *phExportCookie);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVImportDevMem
+@Description    Import memory that was previously exported with PVRSRVExport()
+                into the current process.
+
+                Note: This call only makes the memory accessible to this
+                process, it doesn't map it into the device or CPU.
+
+@Input          psConnection    Connection to services
+@Input          phExportCookie  Ptr to the handle of the export-cookie 
+                                identifying                          
+@Output         phMemDescOut    On Success, a handle to a new memory descriptor
+                                representing the memory as mapped into the
+                                local process address space.
+@Input          uiFlags         Device memory mapping flags                                
+@Input          pszText        Text to describe the import
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+PVRSRV_ERROR PVRSRVImportDevMem(const PVRSRV_CONNECTION *psConnection,
+                                                               PVRSRV_DEVMEM_EXPORTCOOKIE *phExportCookie,
+                                                               PVRSRV_MEMMAP_FLAGS_T uiFlags,
+                                                               PVRSRV_MEMDESC *phMemDescOut);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVIsDeviceMemAddrValid
+@Description    Checks if given device virtual memory address is valid
+                from the GPU's point of view.
+@Input          hContext handle to memory context
+@Input          sDevVAddr device 40bit virtual memory address
+@Return         PVRSRV_OK if address is valid or
+                PVRSRV_ERROR_INVALID_GPU_ADDR when address is invalid
+*/ /***************************************************************************/
+PVRSRV_ERROR PVRSRVIsDeviceMemAddrValid(PVRSRV_DEVMEMCTX hContext,
+                                        IMG_DEV_VIRTADDR sDevVAddr);
+
+#if defined (SUPPORT_EXPORTING_MEMORY_CONTEXT)
+/**************************************************************************/ /*!
+@Function       PVRSRVExportDevmemContext
+@Description    Export a device memory context to another process
+
+@Input          hCtx            Memory context to export                        
+@Output         phExport        On Success, a export handle that can be passed
+                                to another process and used with 
+                                PVRSRVImportDeviceMemContext to import the
+                                memory context                            
+@Return         PVRSRV_ERROR:   PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVExportDevmemContext(PVRSRV_DEVMEMCTX hCtx,
+                                                 IMG_HANDLE *phExport);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVUnexportDevmemContext
+@Description    Unexport an exported device memory context
+
+@Input          psConnection    Services connection
+@Input          hExport         Export handle created to be unexported
+
+@Return         None
+*/ /***************************************************************************/
+IMG_VOID
+PVRSRVUnexportDevmemContext(PVRSRV_CONNECTION *psConnection,
+                                                       IMG_HANDLE hExport);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVImportDeviceMemContext
+@Description    Import an exported device memory context
+
+                Note: The memory context created with this function is not
+                complete and can only be used with debugger related functions
+
+@Input          psConnection    Services connection
+@Input          hExport         Export handle to import
+@Output         phCtxOut        Device memory context
+
+@Return         None
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVImportDeviceMemContext(PVRSRV_CONNECTION *psConnection,
+                                                        IMG_HANDLE hExport,
+                                                        PVRSRV_DEVMEMCTX *phCtxOut);
+
+#endif /* SUPPORT_EXPORTING_MEMORY_CONTEXT */
+#if defined __cplusplus
+};
+#endif
+#endif /* PVRSRV_DEVMEM_H */
+
diff --git a/drivers/gpu/rogue_m/include/pvrsrv_error.h b/drivers/gpu/rogue_m/include/pvrsrv_error.h
new file mode 100644 (file)
index 0000000..82ef82a
--- /dev/null
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File           pvrsrv_error.h
+@Title          services error enumerant
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines error codes used by any/all services modules
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__PVRSRV_ERROR_H__)
+#define __PVRSRV_ERROR_H__
+
+/*!
+ *****************************************************************************
+ * Error values
+ *****************************************************************************/
+typedef enum PVRSRV_ERROR
+{
+       PVRSRV_OK,
+#define PVRE(x) x,
+#include "pvrsrv_errors.h"
+#undef PVRE
+       PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_ERROR;
+
+#endif /* !defined (__PVRSRV_ERROR_H__) */
diff --git a/drivers/gpu/rogue_m/include/pvrsrv_errors.h b/drivers/gpu/rogue_m/include/pvrsrv_errors.h
new file mode 100644 (file)
index 0000000..06fa455
--- /dev/null
@@ -0,0 +1,329 @@
+/*************************************************************************/ /*!
+@File           pvrsrv_errors.h
+@Title          services error codes
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines error codes used by any/all services modules
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Don't add include guards to this file! */
+
+PVRE(PVRSRV_ERROR_OUT_OF_MEMORY)
+PVRE(PVRSRV_ERROR_TOO_FEW_BUFFERS)
+PVRE(PVRSRV_ERROR_INVALID_PARAMS)
+PVRE(PVRSRV_ERROR_INIT_FAILURE)
+PVRE(PVRSRV_ERROR_CANT_REGISTER_CALLBACK)
+PVRE(PVRSRV_ERROR_INVALID_DEVICE)
+PVRE(PVRSRV_ERROR_NOT_OWNER)
+PVRE(PVRSRV_ERROR_BAD_MAPPING)
+PVRE(PVRSRV_ERROR_TIMEOUT)
+PVRE(PVRSRV_ERROR_NOT_IMPLEMENTED)
+PVRE(PVRSRV_ERROR_FLIP_CHAIN_EXISTS)
+PVRE(PVRSRV_ERROR_INVALID_SWAPINTERVAL)
+PVRE(PVRSRV_ERROR_SCENE_INVALID)
+PVRE(PVRSRV_ERROR_STREAM_ERROR)
+PVRE(PVRSRV_ERROR_FAILED_DEPENDENCIES)
+PVRE(PVRSRV_ERROR_CMD_NOT_PROCESSED)
+PVRE(PVRSRV_ERROR_CMD_TOO_BIG)
+PVRE(PVRSRV_ERROR_DEVICE_REGISTER_FAILED)
+PVRE(PVRSRV_ERROR_TOOMANYBUFFERS)
+PVRE(PVRSRV_ERROR_NOT_SUPPORTED)
+PVRE(PVRSRV_ERROR_PROCESSING_BLOCKED)
+PVRE(PVRSRV_ERROR_CANNOT_FLUSH_QUEUE)
+PVRE(PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+PVRE(PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS)
+PVRE(PVRSRV_ERROR_RETRY)
+PVRE(PVRSRV_ERROR_DDK_VERSION_MISMATCH)
+PVRE(PVRSRV_ERROR_DDK_BUILD_MISMATCH)
+PVRE(PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH)
+PVRE(PVRSRV_ERROR_BVNC_MISMATCH)
+PVRE(PVRSRV_ERROR_META_MISMATCH)
+PVRE(PVRSRV_ERROR_UPLOAD_TOO_BIG)
+PVRE(PVRSRV_ERROR_INVALID_FLAGS)
+PVRE(PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS)
+PVRE(PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY)
+PVRE(PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR)
+PVRE(PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED)
+PVRE(PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+PVRE(PVRSRV_ERROR_IOCTL_CALL_FAILED)
+PVRE(PVRSRV_ERROR_MMU_API_PROTOCOL_ERROR)
+PVRE(PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_ALLOCATE_PAGETABLES)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_CREATE_HEAP)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_MAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_UNMAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE)
+PVRE(PVRSRV_ERROR_MMU_LIVE_ALLOCATIONS_IN_HEAP)
+PVRE(PVRSRV_ERROR_MMU_RESERVATION_NOT_INSIDE_HEAP)
+PVRE(PVRSRV_ERROR_PMR_CLIENT_NOT_TRUSTED)
+PVRE(PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES)
+PVRE(PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY)
+PVRE(PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES)
+PVRE(PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE)
+PVRE(PVRSRV_ERROR_PMR_NOT_PERMITTED)
+PVRE(PVRSRV_ERROR_PMR_PMR_ALREADY_OCCUPIED)
+PVRE(PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR)
+PVRE(PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR)
+PVRE(PVRSRV_ERROR_PMR_WRONG_PMR_TYPE)
+PVRE(PVRSRV_ERROR_PMR_HAS_BEEN_MAPPED)
+PVRE(PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE)
+PVRE(PVRSRV_ERROR_PMR_BAD_CHUNK_SIZE)
+PVRE(PVRSRV_ERROR_PMR_MAPPINGTABLE_MISMATCH)
+PVRE(PVRSRV_ERROR_PMR_INVALID_CHUNK)
+PVRE(PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING)
+PVRE(PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP)
+PVRE(PVRSRV_ERROR_DEVICEMEM_BAD_IMPORT_SIZE)
+PVRE(PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX)
+PVRE(PVRSRV_ERROR_DEVICEMEM_MAP_FAILED)
+PVRE(PVRSRV_ERROR_DEVICEMEM_NON_ZERO_USAGE_COUNT)
+PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE)
+PVRE(PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA)
+PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM)
+PVRE(PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED)
+PVRE(PVRSRV_ERROR_DEVICEMEM_NO_MAPPING)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS)
+PVRE(PVRSRV_ERROR_INVALID_MMU_TYPE)
+PVRE(PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT)
+PVRE(PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_PCI_CALL_FAILED)
+PVRE(PVRSRV_ERROR_PCI_REGION_TOO_SMALL)
+PVRE(PVRSRV_ERROR_PCI_REGION_UNAVAILABLE)
+PVRE(PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH)
+PVRE(PVRSRV_ERROR_REGISTER_BASE_NOT_SET)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_KERNELVIRTUAL)
+PVRE(PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES)
+PVRE(PVRSRV_ERROR_FAILED_TO_FREE_PAGES)
+PVRE(PVRSRV_ERROR_FAILED_TO_COPY_PAGES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES)
+PVRE(PVRSRV_ERROR_STILL_MAPPED)
+PVRE(PVRSRV_ERROR_MAPPING_NOT_FOUND)
+PVRE(PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_INVALID_SEGMENT_BLOCK)
+PVRE(PVRSRV_ERROR_INVALID_GFXDEVDEVDATA)
+PVRE(PVRSRV_ERROR_INVALID_DEVINFO)
+PVRE(PVRSRV_ERROR_INVALID_MEMINFO)
+PVRE(PVRSRV_ERROR_INVALID_MISCINFO)
+PVRE(PVRSRV_ERROR_UNKNOWN_IOCTL)
+PVRE(PVRSRV_ERROR_INVALID_CONTEXT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT)
+PVRE(PVRSRV_ERROR_INVALID_HEAP)
+PVRE(PVRSRV_ERROR_INVALID_KERNELINFO)
+PVRE(PVRSRV_ERROR_UNKNOWN_POWER_STATE)
+PVRE(PVRSRV_ERROR_INVALID_HANDLE_TYPE)
+PVRE(PVRSRV_ERROR_INVALID_WRAP_TYPE)
+PVRE(PVRSRV_ERROR_INVALID_PHYS_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_CPU_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_HEAPINFO)
+PVRE(PVRSRV_ERROR_INVALID_PERPROC)
+PVRE(PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO)
+PVRE(PVRSRV_ERROR_INVALID_MAP_REQUEST)
+PVRE(PVRSRV_ERROR_INVALID_UNMAP_REQUEST)
+PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP)
+PVRE(PVRSRV_ERROR_MAPPING_STILL_IN_USE)
+PVRE(PVRSRV_ERROR_EXCEEDED_HW_LIMITS)
+PVRE(PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD)
+PVRE(PVRSRV_ERROR_THREAD_READ_ERROR)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR)
+PVRE(PVRSRV_ERROR_ISR_ALREADY_INSTALLED)
+PVRE(PVRSRV_ERROR_ISR_NOT_INSTALLED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE)
+PVRE(PVRSRV_ERROR_INVALID_CCB_COMMAND)
+PVRE(PVRSRV_ERROR_KERNEL_CCB_FULL)
+PVRE(PVRSRV_ERROR_FLIP_FAILED)
+PVRE(PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED)
+PVRE(PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE)
+PVRE(PVRSRV_ERROR_TIMEOUT_WAITING_FOR_CLIENT_CCB)
+PVRE(PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED)
+PVRE(PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG)
+PVRE(PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG)
+PVRE(PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID)
+PVRE(PVRSRV_ERROR_BLIT_SETUP_FAILED)
+PVRE(PVRSRV_ERROR_SUBMIT_NEEDED)
+PVRE(PVRSRV_ERROR_PDUMP_NOT_AVAILABLE)
+PVRE(PVRSRV_ERROR_PDUMP_BUFFER_FULL)
+PVRE(PVRSRV_ERROR_PDUMP_BUF_OVERFLOW)
+PVRE(PVRSRV_ERROR_PDUMP_NOT_ACTIVE)
+PVRE(PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES)
+PVRE(PVRSRV_ERROR_MUTEX_DESTROY_FAILED)
+PVRE(PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR)
+PVRE(PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE)
+PVRE(PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND)
+PVRE(PVRSRV_ERROR_PROCESS_NOT_INITIALISED)
+PVRE(PVRSRV_ERROR_PROCESS_NOT_FOUND)
+PVRE(PVRSRV_ERROR_SRV_CONNECT_FAILED)
+PVRE(PVRSRV_ERROR_SRV_DISCONNECT_FAILED)
+PVRE(PVRSRV_ERROR_DEINT_PHASE_FAILED)
+PVRE(PVRSRV_ERROR_INIT2_PHASE_FAILED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE)
+PVRE(PVRSRV_ERROR_NO_DC_DEVICES_FOUND)
+PVRE(PVRSRV_ERROR_DC_INVALID_MAXDEPTH)
+PVRE(PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNREGISTER_DEVICE)
+PVRE(PVRSRV_ERROR_NO_DEVICEDATA_FOUND)
+PVRE(PVRSRV_ERROR_NO_DEVICENODE_FOUND)
+PVRE(PVRSRV_ERROR_NO_CLIENTNODE_FOUND)
+PVRE(PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INIT_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_KILL_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER)
+PVRE(PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT)
+PVRE(PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION)
+PVRE(PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_ALLOCATED)
+PVRE(PVRSRV_ERROR_HANDLE_TYPE_MISMATCH)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_SHAREABLE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_INVALID_SUBHANDLE)
+PVRE(PVRSRV_ERROR_HANDLE_BATCH_IN_USE)
+PVRE(PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE)
+PVRE(PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP)
+PVRE(PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE)
+PVRE(PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVAILABLE)
+PVRE(PVRSRV_ERROR_INVALID_DEVICEID)
+PVRE(PVRSRV_ERROR_DEVICEID_NOT_FOUND)
+PVRE(PVRSRV_ERROR_MEMORY_TEST_FAILED)
+PVRE(PVRSRV_ERROR_CPUPADDR_TEST_FAILED)
+PVRE(PVRSRV_ERROR_COPY_TEST_FAILED)
+PVRE(PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK)
+PVRE(PVRSRV_ERROR_CLOCK_REQUEST_FAILED)
+PVRE(PVRSRV_ERROR_DISABLE_CLOCK_FAILURE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK)
+PVRE(PVRSRV_ERROR_UNKNOWN_SGL_ERROR)
+PVRE(PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE)
+PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE)
+PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
+PVRE(PVRSRV_ERROR_BAD_SYNC_STATE)
+PVRE(PVRSRV_ERROR_CACHEOP_FAILED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_MMUCONTEXT_ID)
+PVRE(PVRSRV_ERROR_PARAMETER_BUFFER_INVALID_ALIGNMENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ACQUIRE_CONNECTION)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CONNECTION)
+PVRE(PVRSRV_ERROR_PHYSHEAP_ID_IN_USE)
+PVRE(PVRSRV_ERROR_PHYSHEAP_ID_INVALID)
+PVRE(PVRSRV_ERROR_HP_REQUEST_TOO_LONG)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM_OP)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_CONTEXT)
+PVRE(PVRSRV_ERROR_BP_NOT_SET)
+PVRE(PVRSRV_ERROR_BP_ALREADY_SET)
+PVRE(PVRSRV_ERROR_FEATURE_DISABLED)
+PVRE(PVRSRV_ERROR_REG_CONFIG_ENABLED)
+PVRE(PVRSRV_ERROR_REG_CONFIG_FULL)
+PVRE(PVRSRV_ERROR_REG_CONFIG_INVALID_PI)
+PVRE(PVRSRV_ERROR_MEMORY_ACCESS)
+PVRE(PVRSRV_ERROR_NO_SYSTEM_BUFFER)
+PVRE(PVRSRV_ERROR_DC_INVALID_CONFIG)
+PVRE(PVRSRV_ERROR_DC_INVALID_CROP_RECT)
+PVRE(PVRSRV_ERROR_DC_INVALID_DISPLAY_RECT)
+PVRE(PVRSRV_ERROR_DC_INVALID_BUFFER_DIMS)
+PVRE(PVRSRV_ERROR_DC_INVALID_TRANSFORM)
+PVRE(PVRSRV_ERROR_DC_INVALID_SCALE)
+PVRE(PVRSRV_ERROR_DC_INVALID_CUSTOM)
+PVRE(PVRSRV_ERROR_DC_TOO_MANY_PIPES)
+PVRE(PVRSRV_ERROR_DC_INVALID_PLANE_ALPHA)
+PVRE(PVRSRV_ERROR_NOT_READY)
+PVRE(PVRSRV_ERROR_RESOURCE_UNAVAILABLE)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_PIXEL_FORMAT)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_DIMS)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_TIMER)
+PVRE(PVRSRV_ERROR_NOT_FOUND)
+PVRE(PVRSRV_ERROR_ALREADY_OPEN)
+PVRE(PVRSRV_ERROR_STREAM_MISUSE)
+PVRE(PVRSRV_ERROR_STREAM_FULL)
+PVRE(PVRSRV_ERROR_PHYSMEM_NOT_ALLOCATED)
+PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MAX)
+PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MIN)
+PVRE(PVRSRV_ERROR_INVALID_PB_CONFIG)
+PVRE(PVRSRV_ERROR_META_THREAD0_NOT_ENABLED)
+PVRE(PVRSRV_ERROR_NOT_AUTHENTICATED)
+PVRE(PVRSRV_ERROR_REQUEST_TDMETACODE_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_INIT_TDMETACODE_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_REQUEST_TDSECUREBUF_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_INIT_TDSECUREBUF_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_MUTEX_ALREADY_CREATED)
+PVRE(PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED)
+PVRE(PVRSRV_ERROR_ALREADY_EXISTS)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SEND_PULSE)
+PVRE(PVRSRV_ERROR_TASK_FAILED)
+PVRE(PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+PVRE(PVRSRV_ERROR_INVALID_GPU_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_OFFSET)
+PVRE(PVRSRV_ERROR_CCCB_STALLED)
+PVRE(PVRSRV_ERROR_BUFFER_TOO_SMALL)
+PVRE(PVRSRV_ERROR_INTERNAL_ERROR)
diff --git a/drivers/gpu/rogue_m/include/pvrsrv_memallocflags.h b/drivers/gpu/rogue_m/include/pvrsrv_memallocflags.h
new file mode 100644 (file)
index 0000000..094f157
--- /dev/null
@@ -0,0 +1,528 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This file defines flags used on memory allocations and mappings
+                These flags are relevant throughout the memory management 
+                software stack and are specified by users of services and 
+                understood by all levels of the memory management in both 
+                client and server.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_MEMALLOCFLAGS_H
+#define PVRSRV_MEMALLOCFLAGS_H
+
+#include "img_types.h"
+#if defined(SUPPORT_RGX)
+#include "rgx_memallocflags.h"
+#endif
+typedef IMG_UINT32 PVRSRV_MEMALLOCFLAGS_T;
+
+/*!
+ *  **********************************************************
+ *  *                                                        *
+ *  *                       MAPPING FLAGS                    *
+ *  *                                                        *
+ *  **********************************************************
+ *
+ * PVRSRV_MEMALLOCFLAG_GPU_READABLE
+ *
+ * This flag affects the device MMU protection flags, and specifies
+ * that the memory may be read by the GPU (is this always true?)
+ *
+ * Typically all device memory allocations would specify this flag.
+ *
+ * At the moment, memory allocations without this flag are not supported
+ *
+ * This flag will live with the PMR, thus subsequent mappings would
+ * honour this flag.
+ *
+ * This is a dual purpose flag.  It specifies that memory is permitted
+ * to be read by the GPU, and also requests that the allocation is
+ * mapped into the GPU as a readable mapping
+ *
+ * To be clear:
+ * - When used as an argument on PMR creation; it specifies
+ *       that GPU readable mappings will be _permitted_
+ * - When used as an argument to a "map" function: it specifies
+ *       that a GPU readable mapping is _desired_
+ * - When used as an argument to "AllocDeviceMem": it specifies
+ *       that the PMR will be created with permission to be mapped
+ *       with a GPU readable mapping, _and_ that this PMR will be
+ *       mapped with a GPU readble mapping.
+ * This distinction becomes important when (a) we export allocations;
+ * and (b) when we separate the creation of the PMR from the mapping.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_READABLE               (1U<<0)
+#define PVRSRV_CHECK_GPU_READABLE(uiFlags)             ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_READABLE) != 0)
+
+/*!
+ * PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE
+ *
+ * This flag affects the device MMU protection flags, and specifies
+ * that the memory may be written by the GPU
+ *
+ * Using this flag on an allocation signifies that the allocation is
+ * intended to be written by the GPU.
+ *
+ * Omitting this flag causes a read-only mapping.
+ *
+ * This flag will live with the PMR, thus subsequent mappings would
+ * honour this flag.
+ *
+ * This is a dual purpose flag.  It specifies that memory is permitted
+ * to be written by the GPU, and also requests that the allocation is
+ * mapped into the GPU as a writeable mapping (see note above about
+ * permission vs. mapping mode, and why this flag causes permissions
+ * to be inferred from mapping mode on first allocation)
+ *
+ * N.B.  This flag has no relevance to the CPU's MMU mapping, if any,
+ * and would therefore not enforce read-only mapping on CPU.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE       (1U<<1) /*!< mapped as writeable to the GPU */
+#define PVRSRV_CHECK_GPU_WRITEABLE(uiFlags)                            ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED  (1U<<2) /*!< can be mapped is GPU readable in another GPU mem context */
+#define PVRSRV_CHECK_GPU_READ_PERMITTED(uiFlags)               ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED (1U<<3) /*!< can be mapped is GPU writable in another GPU mem context */
+#define PVRSRV_CHECK_GPU_WRITE_PERMITTED(uiFlags)              ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CPU_READABLE        (1U<<4) /*!< mapped as readable to the CPU */
+#define PVRSRV_CHECK_CPU_READABLE(uiFlags)                             ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_READABLE) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE       (1U<<5) /*!< mapped as writeable to the CPU */
+#define PVRSRV_CHECK_CPU_WRITEABLE(uiFlags)                            ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED  (1U<<6) /*!< can be mapped is CPU readable in another CPU mem context */
+#define PVRSRV_CHECK_CPU_READ_PERMITTED(uiFlags)               ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED (1U<<7) /*!< can be mapped is CPU writable in another CPU mem context */
+#define PVRSRV_CHECK_CPU_WRITE_PERMITTED(uiFlags)              ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED) != 0)
+
+
+/*
+ *  **********************************************************
+ *  *                                                        *
+ *  *                    CACHE CONTROL FLAGS                 *
+ *  *                                                        *
+ *  **********************************************************
+ */
+
+/*
+       GPU domain
+       ==========
+
+       The following defines are used to control the GPU cache bit field.
+       The defines are mutually exclusive.
+       
+       A helper macro, PVRSRV_GPU_CACHE_MODE, is provided to obtain just the GPU cache
+       bit field from the flags. This should be used whenever the GPU cache mode
+       needs to be determined.
+*/
+
+/*!
+   GPU domain. Request uncached memory. This means that any writes to memory
+  allocated with this flag are written straight to memory and thus are coherent
+  for any device in the system.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_UNCACHED                       (0U<<8)
+#define PVRSRV_CHECK_GPU_UNCACHED(uiFlags)                             ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_UNCACHED) != 0)
+
+/*!
+   GPU domain. Use write combiner (if supported) to combine sequential writes 
+   together to reduce memory access by doing burst writes.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE                  (1U<<8)
+#define PVRSRV_CHECK_GPU_WRITE_COMBINE(uiFlags)                        ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE) != 0)
+
+/*!
+    GPU domain. This flag affects the device MMU protection flags.
+    This flag ensures that the GPU and the CPU will always be coherent.
+    This is done by either by snooping each others caches or, if this is
+    not supported, by making the allocation uncached. Please note that
+    this will _not_ guaranty coherency with memory so if this memory
+    is accessed by another device (eg display controller) a flush will
+    be required.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT                 (2U<<8)
+#define PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags)               ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) != 0)
+
+/*!
+   GPU domain. Request cached memory, but not coherent (i.e. no cache snooping).
+   This means that if the allocation needs to transition from one device
+   to another services has to be informed so it can flush/invalidate the 
+   appropriate caches.
+
+    Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future
+    expansion.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT               (3U<<8)
+#define PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags)             ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT) != 0)
+
+/*!
+    GPU domain.
+       Request cached cached coherent memory. This is like 
+       PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT but doesn't fall back on
+       uncached memory if the system doesn't support cache-snooping
+       but rather returns an error.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT   (4U<<8)
+#define PVRSRV_CHECK_GPU_CACHED_CACHE_COHERENT(uiFlags)        ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT) != 0)
+
+/*!
+       GPU domain.
+
+       This flag is for internal use only and is used to indicate
+       that the underlying allocation should be cached on the GPU
+       after all the snooping and coherent checks have been done
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHED                                 (7U<<8)
+#define PVRSRV_CHECK_GPU_CACHED(uiFlags)                               ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHED) != 0)
+
+/*!
+       GPU domain.
+       
+       GPU cache mode mask
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK                (7U<<8)
+#define PVRSRV_GPU_CACHE_MODE(uiFlags)                                 (uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK)
+
+
+/*
+       CPU domain
+       ==========
+
+       The following defines are used to control the CPU cache bit field.
+       The defines are mutually exclusive.
+       
+       A helper macro, PVRSRV_CPU_CACHE_MODE, is provided to obtain just the CPU cache
+       bit field from the flags. This should be used whenever the CPU cache mode
+       needs to be determined.
+*/
+
+/*!
+   CPU domain. Request uncached memory. This means that any writes to memory
+  allocated with this flag are written straight to memory and thus are coherent
+  for any device in the system.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_UNCACHED                       (0U<<11)
+#define PVRSRV_CHECK_CPU_UNCACHED(uiFlags)                             ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_UNCACHED) != 0)
+
+/*!
+   CPU domain. Use write combiner (if supported) to combine sequential writes 
+   together to reduce memory access by doing burst writes.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE                  (1U<<11)
+#define PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags)                        ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE) != 0)
+
+/*!
+    CPU domain. This flag affects the device MMU protection flags.
+    This flag ensures that the GPU and the CPU will always be coherent.
+    This is done by either by snooping each others caches or, if this is
+    not supported, by making the allocation uncached. Please note that
+    this will _not_ guaranty coherency with memory so if this memory
+    is accessed by another device (eg display controller) a flush will
+    be required.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT                 (2U<<11)
+#define PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags)               ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) != 0)
+
+/*!
+   CPU domain. Request cached memory, but not coherent (i.e. no cache snooping).
+   This means that if the allocation needs to transition from one device
+   to another services has to be informed so it can flush/invalidate the 
+   appropriate caches.
+
+    Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future
+    expansion.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT               (3U<<11)
+#define PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags)             ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT) != 0)
+
+/*!
+    CPU domain.
+       Request cached cached coherent memory. This is like 
+       PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT but doesn't fall back on
+       uncached memory if the system doesn't support cache-snooping
+       but rather returns an error.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT   (4U<<11)
+#define PVRSRV_CHECK_CPU_CACHED_CACHE_COHERENT(uiFlags)        ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT) != 0)
+
+/*!
+       CPU domain.
+
+       This flag is for internal use only and is used to indicate
+       that the underlying allocation should be cached on the CPU
+       after all the snooping and coherent checks have been done
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHED                                 (7U<<11)
+#define PVRSRV_CHECK_CPU_CACHED(uiFlags)                               ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHED) != 0)
+
+/*!
+       CPU domain.
+       
+       CPU cache mode mask
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK                (7U<<11)
+#define PVRSRV_CPU_CACHE_MODE(uiFlags)                                 (uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK)
+
+/* Helper flags for usual cases */
+#define PVRSRV_MEMALLOCFLAG_UNCACHED                           (PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED) /*!< Memory will be uncached */
+#define PVRSRV_CHECK_UNCACHED(uiFlags)                                 ((uiFlags & PVRSRV_MEMALLOCFLAG_UNCACHED) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_WRITE_COMBINE                      (PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE | PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE)   /*!< Memory will be write-combined */
+#define PVRSRV_CHECK_WRITE_COMBINE(uiFlags)                            ((uiFlags & PVRSRV_MEMALLOCFLAG_WRITE_COMBINE) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CACHE_COHERENT                     (PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT)  /*!< Memory will be cache-coherent */
+#define PVRSRV_CHECK_CACHE_COHERENT(uiFlags)                   ((uiFlags & PVRSRV_MEMALLOCFLAG_CACHE_COHERENT) != 0)
+
+#define PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT                   (PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT) /*!< Memory will be cache-incoherent */
+#define PVRSRV_CHECK_CACHE_INCOHERENT(uiFlags)                 ((uiFlags & PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT) != 0)
+
+
+/*!
+   CPU MMU Flags mask -- intended for use internal to services only
+ */
+#define PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK  (PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+                                                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+                                                                                               PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK)
+
+/*!
+   MMU Flags mask -- intended for use internal to services only - used
+   for partitioning the flags bits and determining which flags to pass
+   down to mmu_common.c
+ */
+#define PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK  (PVRSRV_MEMALLOCFLAG_GPU_READABLE | \
+                                                PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \
+                                                PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK)
+
+/*!
+    PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE
+    Indicates that the PMR created due to this allocation will support
+    in-kernel CPU mappings.  Only privileged processes may use this
+    flag as it may cause wastage of precious kernel virtual memory on
+    some platforms.
+ */
+#define PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE                (1U<<14)
+#define PVRSRV_CHECK_KERNEL_CPU_MAPPABLE(uiFlags)              ((uiFlags & PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE) != 0)
+
+
+
+/*
+ *
+ *  **********************************************************
+ *  *                                                        *
+ *  *            ALLOC MEMORY FLAGS                          *
+ *  *                                                        *
+ *  **********************************************************
+ *
+ * (Bits 15)
+ *
+ */
+#define PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC                        (1U<<15)
+#define PVRSRV_CHECK_ON_DEMAND(uiFlags)                                        ((uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) != 0)
+
+/*!
+    PVRSRV_MEMALLOCFLAG_CPU_LOCAL
+
+    Indicates that the allocation will primarily be accessed by
+    the CPU, so a UMA allocation (if available) is preferable.
+    If not set, the allocation will primarily be accessed by
+    the GPU, so LMA allocation (if available) is preferable.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_LOCAL                                  (1U<<16)
+#define PVRSRV_CHECK_CPU_LOCAL(uiFlags)                                        ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_LOCAL) != 0)
+
+/*
+ *
+ *  **********************************************************
+ *  *                                                        *
+ *  *            MEMORY ZEROING AND POISONING FLAGS          *
+ *  *                                                        *
+ *  **********************************************************
+ *
+ * Zero / Poison, on alloc/free
+ *
+ * We think the following usecases are required:
+ *
+ *  don't poison or zero on alloc or free
+ *     (normal operation, also most efficient)
+ *  poison on alloc
+ *     (for helping to highlight bugs)
+ *  poison on alloc and free
+ *     (for helping to highlight bugs)
+ *  zero on alloc
+ *     (avoid highlighting security issues in other uses of memory)
+ *  zero on alloc and poison on free
+ *     (avoid highlighting security issues in other uses of memory,
+ *      while helping to highlight a subset of bugs e.g. memory
+ *      freed prematurely)
+ *
+ * Since there are more than 4, we can't encode this in just two bits,
+ * so we might as well have a separate flag for each of the three
+ * actions.
+ */
+
+/*!
+    PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC
+    Ensures that the memory allocated is initialized with zeroes.
+ */
+#define PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC                              (1U<<31)
+#define PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags)                            ((uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) != 0)
+
+/*!
+    VRSRV_MEMALLOCFLAG_POISON_ON_ALLOC
+
+    Scribbles over the allocated memory with a poison value
+
+    Not compatible with ZERO_ON_ALLOC
+
+    Poisoning is very deliberately _not_ reflected in PDump as we want
+    a simulation to cry loudly if the initialised data propogates to a
+    result.
+ */
+#define PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC                    (1U<<30)
+#define PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags)                  ((uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC) != 0)
+
+/*!
+    PVRSRV_MEMALLOCFLAG_POISON_ON_FREE
+
+    Causes memory to be trashed when freed, as a lazy man's security
+    measure.
+ */
+#define PVRSRV_MEMALLOCFLAG_POISON_ON_FREE (1U<<29)
+#define PVRSRV_CHECK_POISON_ON_FREE(uiFlags)                   ((uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE) != 0)
+
+/*
+ *
+ *  **********************************************************
+ *  *                                                        *
+ *  *                Device specific MMU flags               *
+ *  *                                                        *
+ *  **********************************************************
+ *
+ * (Bits 24 to 27)
+ *
+ * Some services controled devices have device specific control
+ * bits in their page table entries, we need to allow these flags
+ * to be passed down the memory managament layers so the user
+ * can control these bits.
+ */
+
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET                24
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK          0x0f000000UL
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(n)     \
+                       (((n) << PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET) & \
+                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK)
+
+/*!
+  PMR flags mask -- for internal services use only.  This is the set
+  of flags that will be passed down and stored with the PMR, this also
+  includes the MMU flags which the PMR has to pass down to mm_common.c
+  at PMRMap time.
+*/
+#define PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK  (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \
+                                                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \
+                                            PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+                                            PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \
+                                            PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \
+                                            PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \
+                                            PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \
+                                            PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \
+                                            PVRSRV_MEMALLOCFLAG_CPU_LOCAL)
+
+#if ((~(PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK) & PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK) != 0)
+#error PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK is not a subset of PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK
+#endif
+
+/*!
+  RA differentiation mask
+
+  for use internal to services
+
+  this is the set of flags bits that are able to determine whether a
+  pair of allocations are permitted to live in the same page table.
+  Allocations whose flags differ in any of these places would be
+  allocated from separate RA Imports and therefore would never coexist
+  in the same page
+*/
+#define PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK (PVRSRV_MEMALLOCFLAG_GPU_READABLE | \
+                                                      PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \
+                                                      PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+                                                      PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+                                                      PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK | \
+                                                      PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | \
+                                                      PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \
+                                                      PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK | \
+                                                      PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+
+#if ((~(PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK) & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK) != 0)
+#error PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK is not a subset of PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK
+#endif
+
+/*!
+  Flags that affect _allocation_
+*/
+#define PVRSRV_MEMALLOCFLAGS_PERALLOCFLAGSMASK (0xFFFFFFFFU)
+
+/*!
+  Flags that affect _mapping_
+*/
+#define PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK   (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \
+                                                                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE | \
+                                                    PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \
+                                                    PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+                                                    PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+                                                    PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK | \
+                                                    PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | \
+                                                    PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+
+#if ((~(PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK) & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK) != 0)
+#error PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK is not a subset of PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK
+#endif
+
+#endif /* #ifndef PVRSRV_MEMALLOCFLAGS_H */
+
diff --git a/drivers/gpu/rogue_m/include/pvrversion.h b/drivers/gpu/rogue_m/include/pvrversion.h
new file mode 100644 (file)
index 0000000..94d0002
--- /dev/null
@@ -0,0 +1,91 @@
+/*************************************************************************/ /*!
+@File
+@Title          Version numbers and strings.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Version numbers and strings for PVR Consumer services
+                components.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PVRVERSION_H_
+#define _PVRVERSION_H_
+
+/*
+ *  Rogue KM Version Note
+ *
+ *  L 1.17:
+ *          Support gpu disable dvfs case.
+ *          Add rk_tf_check_version to compatible for rk3328.
+ *  L 1.18:
+ *                     If fix freq,then don't force to drop freq to the lowest.
+ *
+ *  M 1.21:
+ *          Merge 1.5_RTM3604260 DDK code.
+ *  M 1.24:
+ *          Merge 1.5_ED3653583 DDK code.
+ *  M 1.28:
+ *         Merge 1.5_ED3776568 DDK code.
+ */
+
+#define PVR_STR(X) #X
+#define PVR_STR2(X) PVR_STR(X)
+
+#define PVRVERSION_MAJ               1
+#define PVRVERSION_MIN               5
+
+#define PVRVERSION_FAMILY           "rogueddk"
+#define PVRVERSION_BRANCHNAME       "1.5"
+#define PVRVERSION_BUILD             3776568
+#define PVRVERSION_BSCONTROL        "Rogue_DDK_Android"
+
+#define PVRVERSION_STRING           "Rogue_DDK_Android rogueddk 1.5@" PVR_STR2(PVRVERSION_BUILD)
+#define PVRVERSION_STRING_SHORT     "1.5@" PVR_STR2(PVRVERSION_BUILD) ""
+
+#define COPYRIGHT_TXT               "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
+
+#define PVRVERSION_BUILD_HI          377
+#define PVRVERSION_BUILD_LO          6568
+#define PVRVERSION_STRING_NUMERIC    PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
+
+#define PVRVERSION_PACK(MAJ,MIN) ((((MAJ)&0xFFFF) << 16) | (((MIN)&0xFFFF) << 0))
+#define PVRVERSION_UNPACK_MAJ(VERSION) (((VERSION) >> 16) & 0xFFFF)
+#define PVRVERSION_UNPACK_MIN(VERSION) (((VERSION) >> 0) & 0xFFFF)
+
+//chenli:define rockchip version
+#define RKVERSION                   "KM M 1.28"
+#endif /* _PVRVERSION_H_ */
diff --git a/drivers/gpu/rogue_m/include/rgx_common.h b/drivers/gpu/rogue_m/include/rgx_common.h
new file mode 100644 (file)
index 0000000..1ffd810
--- /dev/null
@@ -0,0 +1,146 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Common Types and Defines Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Common types and definitions for RGX software
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_COMMON_H_
+#define RGX_COMMON_H_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+
+/* Included to get the BVNC_KM_N defined and other feature defs */
+#include "km/rgxdefs_km.h"
+
+/*! This macro represents a mask of LSBs that must be zero on data structure
+ * sizes and offsets to ensure they are 8-byte granular on types shared between
+ * the FW and host driver */
+#define RGX_FW_ALIGNMENT_LSB (7)
+
+/*! Macro to test structure size alignment */
+#define RGX_FW_STRUCT_SIZE_ASSERT(_a)  \
+       BLD_ASSERT((sizeof(_a)&RGX_FW_ALIGNMENT_LSB)==0, _a##struct_size)
+
+/*! Macro to test structure member alignment */
+#define RGX_FW_STRUCT_OFFSET_ASSERT(_a, _b)    \
+       BLD_ASSERT((offsetof(_a, _b)&RGX_FW_ALIGNMENT_LSB)==0, _a##struct_offset)
+
+
+/*! The number of performance counters in each layout block */
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_HWPERF_CNTRS_IN_BLK 6
+#define RGX_HWPERF_CNTRS_IN_BLK_MIN 4
+#else
+#define RGX_HWPERF_CNTRS_IN_BLK 4
+#define RGX_HWPERF_CNTRS_IN_BLK_MIN 4
+#endif
+
+
+/*! The master definition for data masters known to the firmware of RGX.
+ * The DM in a V1 HWPerf packet uses this definition. */
+typedef enum _RGXFWIF_DM_
+{
+       RGXFWIF_DM_GP                   = 0,
+       RGXFWIF_DM_2D                   = 1,
+       RGXFWIF_DM_TA                   = 2,
+       RGXFWIF_DM_3D                   = 3,
+       RGXFWIF_DM_CDM                  = 4,
+#if defined(RGX_FEATURE_RAY_TRACING)
+       RGXFWIF_DM_RTU                  = 5,
+       RGXFWIF_DM_SHG                  = 6,
+#endif
+       RGXFWIF_DM_LAST,
+
+       RGXFWIF_DM_FORCE_I32  = 0x7fffffff   /*!< Force enum to be at least 32-bits wide */
+} RGXFWIF_DM;
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGXFWIF_DM_MAX_MTS 8
+#else
+#define RGXFWIF_DM_MAX_MTS 6
+#endif
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+/* Maximum number of DM in use: GP, 2D, TA, 3D, CDM, SHG, RTU */
+#define RGXFWIF_DM_MAX                 (7)
+#else
+#define RGXFWIF_DM_MAX                 (5)
+#endif
+
+/* Min/Max number of HW DMs (all but GP) */
+#if defined(RGX_FEATURE_TLA)
+#define RGXFWIF_HWDM_MIN               (1)
+#else
+#define RGXFWIF_HWDM_MIN               (2)
+#endif
+#define RGXFWIF_HWDM_MAX               (RGXFWIF_DM_MAX)
+
+/*!
+ ******************************************************************************
+ * RGXFW Compiler alignment definitions
+ *****************************************************************************/
+#if defined(__GNUC__)
+#define RGXFW_ALIGN                    __attribute__ ((aligned (8)))
+#elif defined(_MSC_VER)
+#define RGXFW_ALIGN                    __declspec(align(8))
+#pragma warning (disable : 4324)
+#else
+#error "Align MACROS need to be defined for this compiler"
+#endif
+
+/*!
+ ******************************************************************************
+ * Force 8-byte alignment for structures allocated uncached.
+ *****************************************************************************/
+#define UNCACHED_ALIGN      RGXFW_ALIGN
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* RGX_COMMON_H_ */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/rgx_heaps.h b/drivers/gpu/rogue_m/include/rgx_heaps.h
new file mode 100644 (file)
index 0000000..e476f94
--- /dev/null
@@ -0,0 +1,98 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX heap definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGX_HEAPS_H__)
+#define __RGX_HEAPS_H__
+
+#include "km/rgxdefs_km.h"
+
+/* RGX Heap IDs, note: not all heaps are available to clients */
+/* N.B.  Old heap identifiers are deprecated now that the old memory
+   management is. New heap identifiers should be suitably renamed */
+#define RGX_UNDEFINED_HEAP_ID                                  (~0LU)          /*!< RGX Undefined Heap ID */
+#define RGX_GENERAL_HEAP_ID                                            0               /*!< RGX General Heap ID */
+#define RGX_PDSCODEDATA_HEAP_ID                                        1               /*!< RGX PDS Code/Data Heap ID */
+//#define RGX_3DPARAMETERS_HEAP_ID                             2               /*!< RGX 3D Parameters Heap ID */
+#define RGX_USCCODE_HEAP_ID                                            2               /*!< RGX USC Code Heap ID */
+#define RGX_FIRMWARE_HEAP_ID                                   3               /*!< RGX Firmware Heap ID */
+#define RGX_TQ3DPARAMETERS_HEAP_ID                             4               /*!< RGX Firmware Heap ID */
+#define RGX_BIF_TILING_HEAP_1_ID                               5                               /*!< RGX BIF Tiling Heap 1 ID */
+#define RGX_BIF_TILING_HEAP_2_ID                               6                               /*!< RGX BIF Tiling Heap 2 ID */
+#define RGX_BIF_TILING_HEAP_3_ID                               7                               /*!< RGX BIF Tiling Heap 3 ID */
+#define RGX_BIF_TILING_HEAP_4_ID                               8                               /*!< RGX BIF Tiling Heap 4 ID */
+#define RGX_HWBRN37200_HEAP_ID                                 9                               /*!< RGX HWBRN37200 */
+#define RGX_DOPPLER_HEAP_ID                                            10                              /*!< Doppler Heap ID */
+#define RGX_DOPPLER_OVERFLOW_HEAP_ID                   11                              /*!< Doppler Overflow Heap ID */
+
+/* FIXME: work out what this ought to be.  In the old days it was
+   typically bigger than it needed to be.  Is the correct thing
+   "max + 1" ?? */
+#define RGX_MAX_HEAP_ID        (RGX_DOPPLER_OVERFLOW_HEAP_ID + 1)              /*!< Max Valid Heap ID */
+
+/*
+  Identify heaps by their names
+*/
+#define RGX_GENERAL_HEAP_IDENT                         "General"               /*!< RGX General Heap Identifier */
+#define RGX_PDSCODEDATA_HEAP_IDENT             "PDS Code and Data"     /*!< RGX PDS Code/Data Heap Identifier */
+#define RGX_USCCODE_HEAP_IDENT                 "USC Code"              /*!< RGX USC Code Heap Identifier */
+#define RGX_TQ3DPARAMETERS_HEAP_IDENT  "TQ3DParameters"        /*!< RGX TQ 3D Parameters Heap Identifier */
+#define RGX_BIF_TILING_HEAP_1_IDENT        "BIF Tiling Heap l"     /*!< RGX BIF Tiling Heap 1 identifier */
+#define RGX_BIF_TILING_HEAP_2_IDENT        "BIF Tiling Heap 2"     /*!< RGX BIF Tiling Heap 2 identifier */
+#define RGX_BIF_TILING_HEAP_3_IDENT        "BIF Tiling Heap 3"     /*!< RGX BIF Tiling Heap 3 identifier */
+#define RGX_BIF_TILING_HEAP_4_IDENT        "BIF Tiling Heap 4"     /*!< RGX BIF Tiling Heap 4 identifier */
+#define RGX_DOPPLER_HEAP_IDENT                 "Doppler"                               /*!< Doppler Heap Identifier */
+#define RGX_DOPPLER_OVERFLOW_HEAP_IDENT        "Doppler Overflow"                              /*!< Doppler Heap Identifier */
+
+/* BIF tiling heaps have specific buffer requirements based on their XStride
+ * configuration. This is detailed in the BIF tiling documentation and ensures
+ * that the bits swapped by the BIF tiling algorithm do not result in addresses
+ * outside the allocated buffer. The representation here reflects the diagram
+ * in the BIF tiling documentation.
+ * XStride is defined for a platform in sysconfig.h, but the resulting alignment
+ * can be queried through the PVRSRVGetHeapLog2ImportAlignment() API.
+ */
+#define RGX_BIF_TILING_HEAP_STRIDE_LOG2_FROM_XSTRIDE(X)        (X+1+8)
+#define RGX_BIF_TILING_HEAP_ALIGN_LOG2_FROM_XSTRIDE(X)       (4+X+1+8)
+#define RGX_BIF_TILING_HEAP_STRIDE_LOG2_FROM_ALIGN_LOG2(A)       (A-4)
+
+#endif /* __RGX_HEAPS_H__ */
+
diff --git a/drivers/gpu/rogue_m/include/rgx_hwperf_km.h b/drivers/gpu/rogue_m/include/rgx_hwperf_km.h
new file mode 100644 (file)
index 0000000..86880b4
--- /dev/null
@@ -0,0 +1,385 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX HWPerf Types and Defines Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Common data types definitions for hardware performance API
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_HWPERF_KM_H_
+#define RGX_HWPERF_KM_H_
+
+/* 
+ * This header file holds the HWPerf related macros and types needed by the
+ * code in the Kernel Mode (KM) server/driver module and its content is
+ * intended to be suitable for distribution under a public software license.
+ * The definitions within are common and may be used in user-mode, kernel-mode
+ * and firmware compilation units.
+ */
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define RGX_HWPERF_V2_FORMAT 2
+
+#include "rgx_common.h"
+
+
+/******************************************************************************
+ *     Data Stream Common Types
+ *****************************************************************************/
+
+/* These structures are used on both GPU and CPU and must be a size that is a
+ * multiple of 64 bits, 8 bytes to allow the FW to write 8 byte quantities
+ * at 8 byte aligned addresses.  BLD_ASSERT() is used to check this.
+ */
+/*! Type used to encode the event that generated the HW performance packet.
+ * NOTE: When this type is updated the corresponding hwperfbin2json tool source
+ * needs to be updated as well. Also need to update the table in rgxhwperf.c.
+ * The RGX_HWPERF_EVENT_MASK_* macros will also need updating when adding new
+ * types.
+ */
+typedef enum
+{
+       RGX_HWPERF_INVALID                              = 0x00,
+       /* FW types 0x01..0x07 */
+       RGX_HWPERF_FW_BGSTART                   = 0x01,
+       RGX_HWPERF_FW_BGEND                             = 0x02,
+       RGX_HWPERF_FW_IRQSTART                  = 0x03,
+
+       RGX_HWPERF_FW_IRQEND                    = 0x04,
+       RGX_HWPERF_FW_DBGSTART                  = 0x05,
+       RGX_HWPERF_FW_DBGEND                    = 0x06,
+
+       /* HW types 0x08..0x18 */
+       RGX_HWPERF_HW_TAKICK                    = 0x08,
+       RGX_HWPERF_HW_TAFINISHED                = 0x09,
+       RGX_HWPERF_HW_3DTQKICK                  = 0x0A,
+/*     RGX_HWPERF_HW_3DTQFINISHED              = 0x17, */
+/*     RGX_HWPERF_HW_3DSPMKICK                 = 0x11, */
+/*     RGX_HWPERF_HW_3DSPMFINISHED             = 0x18, */
+       RGX_HWPERF_HW_3DKICK                    = 0x0B,
+
+       RGX_HWPERF_HW_3DFINISHED                = 0x0C,
+       RGX_HWPERF_HW_CDMKICK                   = 0x0D,
+       RGX_HWPERF_HW_CDMFINISHED               = 0x0E,
+       RGX_HWPERF_HW_TLAKICK                   = 0x0F,
+
+       RGX_HWPERF_HW_TLAFINISHED               = 0x10,
+       RGX_HWPERF_HW_3DSPMKICK                 = 0x11,
+       RGX_HWPERF_HW_PERIODIC                  = 0x12,
+       RGX_HWPERF_HW_RTUKICK                   = 0x13,
+       
+       RGX_HWPERF_HW_RTUFINISHED               = 0x14,
+       RGX_HWPERF_HW_SHGKICK                   = 0x15,
+       RGX_HWPERF_HW_SHGFINISHED               = 0x16,
+       RGX_HWPERF_HW_3DTQFINISHED              = 0x17,
+
+       RGX_HWPERF_HW_3DSPMFINISHED             = 0x18,
+
+       /* other types 0x1A..0x1F */
+       RGX_HWPERF_CLKS_CHG                             = 0x1A,
+       RGX_HWPERF_GPU_STATE_CHG                = 0x1B,
+
+       /* power types 0x20..0x27 */
+       RGX_HWPERF_PWR_EST_REQUEST              = 0x20,
+       RGX_HWPERF_PWR_EST_READY                = 0x21,
+       RGX_HWPERF_PWR_EST_RESULT               = 0x22,
+       RGX_HWPERF_PWR_CHG                              = 0x23,
+
+       /* context switch types 0x30..0x31 */
+       RGX_HWPERF_CSW_START                    = 0x30,
+       RGX_HWPERF_CSW_FINISHED                 = 0x31,
+       
+       /* last */
+       RGX_HWPERF_LAST_TYPE,
+
+       /* This enumeration must have a value that is a power of two as it is
+        * used in masks and a filter bit field (currently 64 bits long).
+        */
+       RGX_HWPERF_MAX_TYPE                             = 0x40
+} RGX_HWPERF_EVENT_TYPE;
+
+/* The event type values are incrementing integers for use as a shift ordinal
+ * in the event filtering process at the point events are generated.
+ * This scheme thus implies a limit of 63 event types.
+ */
+BLD_ASSERT((RGX_HWPERF_LAST_TYPE<RGX_HWPERF_MAX_TYPE), rgx_hwperf_h)
+
+/*! Type obsolete and will be removed in a later release, use RGXFWIF_DM */
+typedef RGXFWIF_DM RGX_HWPERF_DM;
+#define RGX_HWPERF_DM_GP       RGXFWIF_DM_GP
+#define RGX_HWPERF_DM_2D       RGXFWIF_DM_2D
+#define RGX_HWPERF_DM_TA       RGXFWIF_DM_TA
+#define RGX_HWPERF_DM_3D       RGXFWIF_DM_3D
+#define RGX_HWPERF_DM_CDM      RGXFWIF_DM_CDM
+#define RGX_HWPERF_DM_RTU      RGXFWIF_DM_RTU
+#define RGX_HWPERF_DM_SHG   RGXFWIF_DM_SHG
+#define RGX_HWPERF_DM_LAST     RGXFWIF_DM_LAST
+
+
+/******************************************************************************
+ *     Packet Format Version 2 Types
+ *****************************************************************************/
+
+/*! Signature ASCII pattern 'HWP2' found in the first word of a HWPerfV2 packet
+ */
+#define HWPERF_PACKET_V2_SIG           0x48575032
+/*! Signature ASCII pattern 'HWPA' found in the first word of a HWPerfV2a packet
+ */
+#define HWPERF_PACKET_V2A_SIG          0x48575041
+
+/*! Signature ASCII pattern 'HWPB' found in the first word of a HWPerfV2b packet
+ */
+#define HWPERF_PACKET_V2B_SIG          0x48575042
+
+#define HWPERF_PACKET_ISVALID(_ptr) (((_ptr) == HWPERF_PACKET_V2_SIG) || ((_ptr) == HWPERF_PACKET_V2A_SIG)|| ((_ptr) == HWPERF_PACKET_V2B_SIG))
+
+/*! This structure defines version 2 of the packet format which is
+ * based around a header and a variable length data payload structure.
+ * The address of the next packet can be found by adding the ui16Size field
+ * in the header to the current packet address.
+ * Producers of packets must always ensure the size field is a multiple of 8
+ * as packets must start on an 8-byte granular address.
+ */
+typedef struct
+{
+       /* HEADER - packet header fields common to all packet types */
+       IMG_UINT32  ui32Sig;        /*!< Always the value HWPERF_PACKET_SIG */
+
+       IMG_UINT32  ui32Size;       /*!< Overall packet size in bytes, includes
+                                    * header and payload. Size is a 16-bit field
+                                    * stored in the 16 LSb. 16 MSb reserved.
+                                    * Use RGX_HWPERF_MAKE_SIZE_* and RGX_HWPERF_GET_SIZE
+                                    * macros to set/get, never write directly. */
+
+       IMG_UINT32  eTypeId;        /*!< Includes event type and META thread ID in
+                                    * the 16 LSb. 16 MSb reserved.
+                                    * Use RGX_HWPERF_MAKE_TYPEID and RGX_HWPERF_GET_*
+                                    * macros to set/get, never write directly. */
+
+       IMG_UINT32  ui32Ordinal;    /*!< Sequential number of the packet */
+       IMG_UINT64  ui64RGXTimer;   /*!< Value of RGX_CR_TIMER at event */
+
+       /* PAYLOAD - bytes from this point on in the buffer are from the
+        * RGX_HWPERF_V2_PACKET_DATA union which encodes the payload data specific
+        * to the event type set in the header. When the structure in the union
+        * has a variable length member e.g. HW packets the payload length
+        * varies.
+        */
+} RGX_HWPERF_V2_PACKET_HDR, *RGX_PHWPERF_V2_PACKET_HDR;
+
+RGX_FW_STRUCT_OFFSET_ASSERT(RGX_HWPERF_V2_PACKET_HDR, ui64RGXTimer)
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_HDR)
+
+
+/*! Mask for use with the IMG_UINT32 ui32Size header field */
+#define RGX_HWPERF_SIZE_MASK                   0xFFFFU
+
+/*! Macro which takes a structure name and provides the packet size for
+ * a fixed size payload packet for assignment to the ui16Size field. */
+#define RGX_HWPERF_MAKE_SIZE_FIXED(_struct)       ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+sizeof(_struct))))
+
+/*! Macro which takes the number of bytes written in the data payload of a
+ * packet for a variable size payload packet, rounds it up to 8 bytes where
+ * it may be assigned to the ui16Size field. */
+#define RGX_HWPERF_MAKE_SIZE_VARIABLE(_size)       ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN(_size, 8))))
+
+/*! Macro to obtain the size of the packet */
+#define RGX_HWPERF_GET_SIZE(_packet_addr)    ((IMG_UINT16)(((_packet_addr)->ui32Size) & RGX_HWPERF_SIZE_MASK))
+
+/*! Macro to obtain the size of the packet data */
+#define RGX_HWPERF_GET_DATA_SIZE(_packet_addr)   (RGX_HWPERF_GET_SIZE(_packet_addr) - sizeof(RGX_HWPERF_V2_PACKET_HDR))
+
+
+/*! Masks for use with the IMG_UINT32 eTypeId header field */
+#define RGX_HWPERF_TYPEID_MASK                 0xFFFFU
+#define RGX_HWPERF_TYPEID_THREAD_MASK  0x8000U
+#define RGX_HWPERF_TYPEID_EVENT_MASK   (RGX_HWPERF_MAX_TYPE-1)
+
+/*! Meta thread macros for encoding the ID into the type field of a packet */
+#define RGX_HWPERF_META_THREAD_SHIFT   15U
+#define RGX_HWPERF_META_THREAD_ID0             0x0U
+#define RGX_HWPERF_META_THREAD_ID1             0x1U
+/*! Obsolete, kept for source compatibility */
+#define RGX_HWPERF_META_THREAD_MASK            0x1U
+
+/*! Macros used to set the packet type and encode meta thread ID (0|1) within */
+#define RGX_HWPERF_MAKE_TYPEID(_type,_thread) ((IMG_UINT32) ((RGX_HWPERF_TYPEID_THREAD_MASK&((_thread)<<RGX_HWPERF_META_THREAD_SHIFT)) | (RGX_HWPERF_TYPEID_EVENT_MASK&(_type))))
+
+/*! Obtains the event type that generated the packet */
+#define RGX_HWPERF_GET_TYPE(_packet_addr)            (((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_EVENT_MASK)
+
+/*! Obtains the META Thread number that generated the packet */
+#define RGX_HWPERF_GET_THREAD_ID(_packet_addr)       (((((_packet_addr)->eTypeId)&RGX_HWPERF_TYPEID_THREAD_MASK) >> RGX_HWPERF_META_THREAD_SHIFT))
+
+/*! Macros to obtain a typed pointer to a packet or data structure given a packet address */
+#define RGX_HWPERF_GET_PACKET(_buffer_addr)            ((RGX_HWPERF_V2_PACKET_HDR*)  (_buffer_addr))
+#define RGX_HWPERF_GET_PACKET_DATA_BYTES(_packet_addr) ((IMG_BYTE*) ( ((IMG_BYTE*)(_packet_addr)) +sizeof(RGX_HWPERF_V2_PACKET_HDR) ) )
+#define RGX_HWPERF_GET_NEXT_PACKET(_packet_addr)       ((RGX_HWPERF_V2_PACKET_HDR*)  ( ((IMG_BYTE*)(_packet_addr))+(RGX_HWPERF_SIZE_MASK&(_packet_addr)->ui32Size)) )
+
+/*! Obtains a typed pointer to a packet header given the packed data address */
+#define RGX_HWPERF_GET_PACKET_HEADER(_packet_addr)     ((RGX_HWPERF_V2_PACKET_HDR*)  ( ((IMG_BYTE*)(_packet_addr)) - sizeof(RGX_HWPERF_V2_PACKET_HDR) ))
+
+
+/*! Masks for use with the IMG_UINT32 ui32BlkInfo field */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_MASK       0xFFFF0000U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_MASK      0x0000FFFFU
+
+/*! Shift for the NumBlocks and counter block offset field in ui32BlkInfo */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT      16U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT 0U
+
+/*! Macro used to set the block info word as a combination of two 16-bit integers */
+#define RGX_HWPERF_MAKE_BLKINFO(_numblks,_blkoffset) ((IMG_UINT32) ((RGX_HWPERF_BLKINFO_BLKCOUNT_MASK&((_numblks) << RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)) | (RGX_HWPERF_BLKINFO_BLKOFFSET_MASK&((_blkoffset) << RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT))))
+
+/*! Macro used to obtain get the number of counter blocks present in the packet */
+#define RGX_HWPERF_GET_BLKCOUNT(_blkinfo)            ((_blkinfo & RGX_HWPERF_BLKINFO_BLKCOUNT_MASK) >> RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)
+
+/*! Obtains the offset of the counter block stream in the packet */
+#define RGX_HWPERF_GET_BLKOFFSET(_blkinfo)           ((_blkinfo & RGX_HWPERF_BLKINFO_BLKOFFSET_MASK) >> RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT)
+
+/* This is the maximum frame contexts that are supported in the driver at the moment */
+#define RGX_HWPERF_HW_MAX_WORK_CONTEXT               2
+/*! This structure holds the field data of a Hardware packet.
+ */
+#define RGX_HWPERF_HW_DATA_FIELDS_LIST \
+IMG_UINT32 ui32DMCyc;         /*!< DataMaster cycle count register, 0 if none */\
+IMG_UINT32 ui32FrameNum;      /*!< Frame number */\
+IMG_UINT32 ui32PID;           /*!< Process identifier */\
+IMG_UINT32 ui32DMContext;     /*!< RenderContext for a TA,3D, Compute context for CDM, etc. */\
+IMG_UINT32 ui32RenderTarget;  /*!< RenderTarget for a TA,3D, 0x0 otherwise */\
+IMG_UINT32 ui32ExtJobRef;     /*!< Externally provided job reference used to track work for debugging purposes */\
+IMG_UINT32 ui32IntJobRef;     /*!< Internally provided job reference used to track work for debugging purposes */\
+IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the time correlation at the time the packet was generated */\
+IMG_UINT32 ui32BlkInfo;       /*!< <31..16> NumBlocks <15..0> Counterblock stream offset */\
+IMG_UINT32 ui32WorkContext;   /*!< Work context number. Frame number for RTU DM, 0x0 otherwise */
+
+typedef struct
+{
+       RGX_HWPERF_HW_DATA_FIELDS_LIST
+} RGX_HWPERF_HW_DATA_FIELDS;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA_FIELDS)
+
+
+/******************************************************************************
+ *     API Types
+ *****************************************************************************/
+
+
+/*! Mask macros for use with RGXCtrlHWPerf() API.
+ * RGX_HWPERF_EVENT_ALL is obsolete, use RGX_HWPERF_EVENT_MASK_ALL
+ */
+#define RGX_HWPERF_EVENT_MASK_NONE          (IMG_UINT64_C(0x0000000000000000))
+#define RGX_HWPERF_EVENT_MASK_ALL           (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_HWPERF_EVENT_MASK_ALL_FW        (IMG_UINT64_C(0x000000000000007E))
+#define RGX_HWPERF_EVENT_MASK_HW_KICKFINISH (IMG_UINT64_C(0x0000000001FBFF00))
+#define RGX_HWPERF_EVENT_MASK_HW_PERIODIC   (IMG_UINT64_C(0x0000000000040000))
+#define RGX_HWPERF_EVENT_MASK_ALL_HW        (RGX_HWPERF_EVENT_MASK_HW_KICKFINISH \
+                                            | RGX_HWPERF_EVENT_MASK_HW_PERIODIC)
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR_EST   (IMG_UINT64_C(0X0000000700000000))
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR       (IMG_UINT64_C(0X0000000800000000))
+#define RGX_HWPERF_EVENT_MASK_VALUE(e)      (((IMG_UINT64)1)<<(e))
+
+/*! Type used in the RGX API RGXConfigureAndEnableHWPerfCounters()
+ * It is used to configure the performance counter module in a layout
+ * block and allows one or more counters in the block to be 
+ * configured in one operation based on the counter select mask. The bit
+ * shifts for this are the values in RGX_HWPERF_CNTBLK_COUNTER_ID. This mask
+ * also encodes which values in the arrays are valid, for example, if bit 1 set
+ * then aui8Mode[1], aui16GroupSelect[1], aui16BitSelect[1], aui32BatchMax[1],
+ * and aui32BatchMin[1] must be set. If these array elements are all set to 
+ * 0 then the counter will not count and will not be in the HW event, 
+ * effectively disabling the counter from the callers point of view. 
+ * If any are non zero then the counter will be included in the HW event.
+ *
+ * Each layout block has 4 or 6 counters that can be programmed independently to
+ * profile the performance of a HW block. Each counter can be configured to
+ * accumulate statistics from 1 of 32 counter groups defined for that block.
+ * Each counter group can have up to 16        signals/bits defined that can be
+ * selected. Each counter may accumulate in one of two modes.
+ * See hwdefs/regapiperf.h for block/group/signal definitions.
+ */
+ typedef struct _RGX_HWPERF_CONFIG_CNTBLK_
+{
+       /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+       IMG_UINT16 ui16BlockID;
+
+       /*! 4 or 6 LSBs are a mask of which counters to configure. Bit 0 is counter 0,
+        * bit 1 is counter 1 on so on. */
+       IMG_UINT8   ui8CounterSelect;
+
+       /*! 4 or 6 LSBs 0 for counting 1's in the group, 1 for treating the group
+        * signals as a number for unsigned addition. Bit 0 is counter 0, bit 1 is
+        * counter 1 on so on. This member relates to the MODE field
+        * in the RGX_CR_<N>_PERF_SELECTm register for each counter */
+       IMG_UINT8       ui8Mode;
+
+       /*! 5 or 6 LSBs used as the GROUP_SELECT field in the RGX_CR_<N>_PERF_SELECTm
+        * register. Array index 0 is counter 0, index 1 is counter 1 and so on. */
+       IMG_UINT8       aui8GroupSelect[RGX_HWPERF_CNTRS_IN_BLK];
+
+       /*! 16 LSBs used as the BIT_SELECT field in the RGX_CR_<N>_PERF_SELECTm
+        * register. Array indexes relate to counters as above. */
+       IMG_UINT16  aui16BitSelect[RGX_HWPERF_CNTRS_IN_BLK];
+
+       /*! 14 LSBs used as the BATCH_MAX field in the RGX_CR_<N>_PERF_SELECTm
+        * register. Array indexes relate to counters as above. */
+       IMG_UINT32  aui32BatchMax[RGX_HWPERF_CNTRS_IN_BLK];
+
+       /*! 14 LSBs used as the BATCH_MIN field in the RGX_CR_<N>_PERF_SELECTm
+        * register. Array indexes relate to counters as above. */
+       IMG_UINT32  aui32BatchMin[RGX_HWPERF_CNTRS_IN_BLK];
+} UNCACHED_ALIGN RGX_HWPERF_CONFIG_CNTBLK;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_CNTBLK)
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* RGX_HWPERF_KM_H_ */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/rgx_memallocflags.h b/drivers/gpu/rogue_m/include/rgx_memallocflags.h
new file mode 100644 (file)
index 0000000..5fa1909
--- /dev/null
@@ -0,0 +1,49 @@
+/**************************************************************************/ /*!
+@File
+@Title          RGX memory allocation flags
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RGX_MEMALLOCFLAGS_H_
+#define _RGX_MEMALLOCFLAGS_H_
+
+#define PMMETA_PROTECT         (1 << 0)        /* Memory that only the PM and Meta can access */
+#define META_CACHED                (1 << 1)    /* Memory that is cached in META */
+
+#endif
diff --git a/drivers/gpu/rogue_m/include/rgx_meta.h b/drivers/gpu/rogue_m/include/rgx_meta.h
new file mode 100644 (file)
index 0000000..b1c0aaa
--- /dev/null
@@ -0,0 +1,352 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX META definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX META helper definitions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_META_H__)
+#define __RGX_META_H__
+
+
+/***** The META HW register definitions in the file are updated manually *****/
+
+
+#include "img_defs.h"
+
+/************************************************************************
+* META registers and MACROS 
+************************************************************************/
+#define        META_CR_CTRLREG_BASE(T)                                 (0x04800000 + 0x1000*(T))
+
+#define META_CR_TXPRIVEXT                                              (0x048000E8)
+#define META_CR_TXPRIVEXT_MINIM_EN                             (0x1<<7)
+
+#define META_CR_SYSC_JTAG_THREAD                               (0x04830030)
+#define META_CR_SYSC_JTAG_THREAD_PRIV_EN               (0x00000004)
+
+#define META_CR_PERF_COUNT0                                            (0x0480FFE0)
+#define META_CR_PERF_COUNT1                                            (0x0480FFE8)
+#define META_CR_PERF_COUNT_CTRL_SHIFT                  (28)
+#define META_CR_PERF_COUNT_CTRL_MASK                   (0xF0000000)
+#define META_CR_PERF_COUNT_CTRL_DCACHEHITS             (0x8 << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICACHEHITS             (0x9 << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICACHEMISS             (0xA << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICORE                  (0xD << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_THR_SHIFT                   (24)
+#define META_CR_PERF_COUNT_THR_MASK                            (0x0F000000)
+#define META_CR_PERF_COUNT_THR_0                               (0x1 << META_CR_PERF_COUNT_THR_SHIFT)
+#define META_CR_PERF_COUNT_THR_1                               (0x2 << META_CR_PERF_COUNT_THR_1)
+
+#define META_CR_TxVECINT_BHALT                                 (0x04820500)
+#define META_CR_PERF_ICORE0                                            (0x0480FFD0)
+#define META_CR_PERF_ICORE1                                            (0x0480FFD8)
+#define META_CR_PERF_ICORE_DCACHEMISS                  (0x8)
+
+typedef enum
+{
+       META_PERF_CONF_NONE = 0,
+       META_PERF_CONF_ICACHE = 1,
+       META_PERF_CONF_DCACHE = 2,
+       META_PERF_CONF_POLLS = 3,
+       META_PERF_CONF_CUSTOM_TIMER = 4
+} META_PERF_CONF;
+
+#define META_CR_PERF_COUNT(CTRL, THR)                  ((META_CR_PERF_COUNT_CTRL_##CTRL << META_CR_PERF_COUNT_CTRL_SHIFT) | \
+                                                                                                (THR << META_CR_PERF_COUNT_THR_SHIFT))
+
+#define        META_CR_TXUXXRXDT_OFFSET                                (META_CR_CTRLREG_BASE(0) + 0x0000FFF0)
+#define        META_CR_TXUXXRXRQ_OFFSET                                (META_CR_CTRLREG_BASE(0) + 0x0000FFF8)
+
+#define META_CR_TXUXXRXRQ_DREADY_BIT                   (0x80000000)    /* Poll for done */
+#define META_CR_TXUXXRXRQ_RDnWR_BIT                    (0x00010000)    /* Set for read  */
+#define META_CR_TXUXXRXRQ_TX_S                         (12)
+#define META_CR_TXUXXRXRQ_RX_S                         (4)
+#define META_CR_TXUXXRXRQ_UXX_S                        (0)
+
+#define META_CR_TXUA0_ID                                               (0x3)                   /* Address unit regs */
+#define META_CR_TXUPC_ID                                               (0x5)                   /* PC registers */
+
+/* Macros to calculate register access values */
+#define META_CR_CORE_REG(Thr, RegNum, Unit)    (((Thr)                 << META_CR_TXUXXRXRQ_TX_S ) | \
+                                                                                        ((RegNum)              << META_CR_TXUXXRXRQ_RX_S ) | \
+                                                                                        ((Unit)                << META_CR_TXUXXRXRQ_UXX_S))
+
+#define META_CR_THR0_PC                META_CR_CORE_REG(0, 0, META_CR_TXUPC_ID)
+#define META_CR_THR0_PCX       META_CR_CORE_REG(0, 1, META_CR_TXUPC_ID)
+#define META_CR_THR0_SP                META_CR_CORE_REG(0, 0, META_CR_TXUA0_ID)
+
+#define META_CR_THR1_PC                META_CR_CORE_REG(1, 0, META_CR_TXUPC_ID)
+#define META_CR_THR1_PCX       META_CR_CORE_REG(1, 1, META_CR_TXUPC_ID)
+#define META_CR_THR1_SP                META_CR_CORE_REG(1, 0, META_CR_TXUA0_ID)
+
+#define SP_ACCESS(Thread)      META_CR_CORE_REG(Thread, 0, META_CR_TXUA0_ID)
+#define PC_ACCESS(Thread)      META_CR_CORE_REG(Thread, 0, META_CR_TXUPC_ID)
+
+#define        META_CR_COREREG_ENABLE                  (0x0000000)
+#define        META_CR_COREREG_STATUS                  (0x0000010)
+#define        META_CR_COREREG_DEFR                    (0x00000A0)
+
+#define        META_CR_T0ENABLE_OFFSET                 (META_CR_CTRLREG_BASE(0) + META_CR_COREREG_ENABLE)
+#define        META_CR_T0STATUS_OFFSET                 (META_CR_CTRLREG_BASE(0) + META_CR_COREREG_STATUS)
+#define        META_CR_T0DEFR_OFFSET                   (META_CR_CTRLREG_BASE(0) + META_CR_COREREG_DEFR)
+
+#define        META_CR_T1ENABLE_OFFSET                 (META_CR_CTRLREG_BASE(1) + META_CR_COREREG_ENABLE)
+#define        META_CR_T1STATUS_OFFSET                 (META_CR_CTRLREG_BASE(1) + META_CR_COREREG_STATUS)
+#define        META_CR_T1DEFR_OFFSET                   (META_CR_CTRLREG_BASE(1) + META_CR_COREREG_DEFR)
+
+#define META_CR_TXENABLE_ENABLE_BIT            (0x00000001)   /* Set if running */
+#define META_CR_TXSTATUS_PRIV                  (0x00020000)   
+
+#define META_MEM_GLOBAL_RANGE_BIT                              (0x80000000)
+
+
+/************************************************************************
+* META LDR Format
+************************************************************************/
+/* Block header structure */
+typedef struct 
+{
+       IMG_UINT32      ui32DevID;
+       IMG_UINT32      ui32SLCode;
+       IMG_UINT32      ui32SLData;
+       IMG_UINT16      ui16PLCtrl;
+       IMG_UINT16      ui16CRC;
+
+} RGX_META_LDR_BLOCK_HDR;
+
+/* High level data stream block  structure */
+typedef struct 
+{
+       IMG_UINT16      ui16Cmd;
+       IMG_UINT16      ui16Length;
+       IMG_UINT32      ui32Next;
+       IMG_UINT32      aui32CmdData[4];
+
+} RGX_META_LDR_L1_DATA_BLK;
+
+/* High level data stream block  structure */
+typedef struct
+{
+       IMG_UINT16      ui16Tag;
+       IMG_UINT16      ui16Length;
+       IMG_UINT32      aui32BlockData[4];
+
+} RGX_META_LDR_L2_DATA_BLK;
+
+/* Config command structure */
+typedef struct
+{
+       IMG_UINT32      ui32Type;
+       IMG_UINT32      aui32BlockData[4];
+
+} RGX_META_LDR_CFG_BLK;
+
+/* Block type definitions */
+#define RGX_META_LDR_COMMENT_TYPE_MASK                 (0x0010)
+#define RGX_META_LDR_BLK_IS_COMMENT(X)                 ((X & RGX_META_LDR_COMMENT_TYPE_MASK) != 0)
+
+/* Command definitions
+       Value   Name                    Description
+       0               LoadMem                 Load memory with binary data.
+       1               LoadCore                Load a set of core registers.
+       2               LoadMMReg               Load a set of memory mapped registers.
+       3               StartThreads    Set each thread PC and SP, then enable  threads.
+       4               ZeroMem                 Zeros a memory region.
+       5               Config                  Perform a configuration command. */
+#define RGX_META_LDR_CMD_MASK                          (0x000F)
+
+#define RGX_META_LDR_CMD_LOADMEM                       (0x0000)
+#define RGX_META_LDR_CMD_LOADCORE                      (0x0001)
+#define RGX_META_LDR_CMD_LOADMMREG                     (0x0002)
+#define RGX_META_LDR_CMD_START_THREADS         (0x0003)
+#define RGX_META_LDR_CMD_ZEROMEM                       (0x0004)
+#define RGX_META_LDR_CMD_CONFIG                        (0x0005)
+
+/* Config Command definitions
+       Value   Name            Description
+       0               Pause           Pause for x times 100 instructions
+       1               Read            Read a value from register - No value return needed.
+                                               Utilises effects of issuing reads to certain registers
+       2               Write           Write to mem location
+       3               MemSet          Set mem to value
+       4               MemCheck        check mem for specific value.*/
+#define RGX_META_LDR_CFG_PAUSE                 (0x0000)
+#define RGX_META_LDR_CFG_READ                  (0x0001)
+#define RGX_META_LDR_CFG_WRITE                 (0x0002)
+#define RGX_META_LDR_CFG_MEMSET                        (0x0003)
+#define RGX_META_LDR_CFG_MEMCHECK              (0x0004)
+
+/************************************************************************
+* RGX FW segmented MMU definitions
+************************************************************************/
+/* All threads can access the segment */
+#define RGXFW_SEGMMU_ALLTHRS   (0xf << 8)
+/* Writeable */
+#define RGXFW_SEGMMU_WRITEABLE (0x1 << 1)
+/* All threads can access and writeable */
+#define RGXFW_SEGMMU_ALLTHRS_WRITEABLE (RGXFW_SEGMMU_ALLTHRS | RGXFW_SEGMMU_WRITEABLE)
+
+/* Direct map regions mapping (8-10) */
+#define RGXFW_SEGMMU_DMAP_ID_START                     (8)
+#define RGXFW_SEGMMU_DMAP_ADDR_START           (0x06000000U)
+#define RGXFW_SEGMMU_DMAP_ADDR_META                    (0x86000000U)
+#define RGXFW_SEGMMU_DMAP_SIZE                         (8*1024*1024) /* 8 MB */
+
+/* Direct map region 11 used for mapping GPU memory */
+#define RGXFW_SEGMMU_DMAP_GPU_ID                       (11)
+#define RGXFW_SEGMMU_DMAP_GPU_ADDR_START       (RGXFW_SEGMMU_DMAP_ADDR_START + 3*RGXFW_SEGMMU_DMAP_SIZE)
+
+/* Segment IDs */
+#define RGXFW_SEGMMU_TEXT_ID                   (0)
+#define RGXFW_SEGMMU_SHARED_ID                 (1)
+#define RGXFW_SEGMMU_BOOTLDR_ID                        (2)
+#define RGXFW_SEGMMU_DATA_ID                   (3)
+
+#define RGXFW_SEGMMU_META_DM_ID                        (0x7)
+
+#if defined(HW_ERN_45914)
+/* SLC caching strategy is emitted through the segment MMU. All the segments configured 
+   through this macro are CACHED in the SLC. The interface has been kept the same to 
+   simplify the code changes. The bifdm argument is ignored (no longer relevant). */
+#if defined(HW_ERN_49144)
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7(pers, coheren, mmu_ctx)     ( (((IMG_UINT64) ((pers)    & 0x3))  << 50) | \
+                                                                  (((IMG_UINT64) ((mmu_ctx) & 0xFF)) << 42) | \
+                                                                  (((IMG_UINT64) ((coheren) & 0x1))  << 40) )
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_CACHED(mmu_ctx)         RGXFW_SEGMMU_OUTADDR_TOP_S7(0x3, 0x0, mmu_ctx)
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_UNCACHED(mmu_ctx)       RGXFW_SEGMMU_OUTADDR_TOP_S7(0x0, 0x1, mmu_ctx)
+
+/* Set FW code/data cached in the SLC as default */
+#define RGXFW_SEGMMU_OUTADDR_TOP(mmu_ctx, bifdm)                RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_CACHED(mmu_ctx | (bifdm&0x0))
+#else
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7(pers, coheren, mmu_ctx)     ( (((IMG_UINT64) ((pers)    & 0x3))  << 52) | \
+                                                                  (((IMG_UINT64) ((mmu_ctx) & 0xFF)) << 44) | \
+                                                                  (((IMG_UINT64) ((coheren) & 0x1))  << 40) )
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_CACHED(mmu_ctx)         RGXFW_SEGMMU_OUTADDR_TOP_S7(0x3, 0x0, mmu_ctx)
+#define RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_UNCACHED(mmu_ctx)       RGXFW_SEGMMU_OUTADDR_TOP_S7(0x0, 0x1, mmu_ctx)
+
+/* Set FW code/data cached in the SLC as default */
+#define RGXFW_SEGMMU_OUTADDR_TOP(mmu_ctx, bifdm)                RGXFW_SEGMMU_OUTADDR_TOP_S7_SLC_CACHED(mmu_ctx | (bifdm&0x0))
+#endif
+#else
+/* To configure the Page Catalog and BIF-DM fed into the BIF for Garten accesses through this segment */
+#define RGXFW_SEGMMU_OUTADDR_TOP(pc, bifdm)                                ( (((IMG_UINT64) ((pc)    & 0xF)) << 44) | \
+                                                                  (((IMG_UINT64) ((bifdm) & 0xF)) << 40) )
+#endif
+
+/* META segments have 4kB minimum size */
+#define RGXFW_SEGMMU_ALIGN                     (0x1000) 
+
+/* Segmented MMU registers (n = segment id) */
+#define META_CR_MMCU_SEGMENTn_BASE(n)                  (0x04850000 + (n)*0x10)
+#define META_CR_MMCU_SEGMENTn_LIMIT(n)                 (0x04850004 + (n)*0x10)
+#define META_CR_MMCU_SEGMENTn_OUTA0(n)                 (0x04850008 + (n)*0x10)
+#define META_CR_MMCU_SEGMENTn_OUTA1(n)                 (0x0485000C + (n)*0x10)
+
+/* Win mode for data cache */
+#define RGXFW__SEGMMU_DMAP_DC_WIN (0x3)
+#define RGXFW__SEGMMU_DMAP_DC_SHIFT (0x6)
+
+/************************************************************************
+* RGX FW Bootloader defaults
+************************************************************************/
+#define RGXFW_BOOTLDR_META_ADDR                (0x40000000)
+#define RGXFW_BOOTLDR_DEVV_ADDR_0      (0xC0000000)
+#define RGXFW_BOOTLDR_DEVV_ADDR_1      (0x000000E1)
+#define RGXFW_BOOTLDR_DEVV_ADDR                ((((IMG_UINT64) RGXFW_BOOTLDR_DEVV_ADDR_1) << 32) | RGXFW_BOOTLDR_DEVV_ADDR_0)
+#define RGXFW_BOOTLDR_LIMIT                    (0x1FFFF000)
+
+/* Bootloader configuration offset is in dwords (512 bytes) */
+#define RGXFW_BOOTLDR_CONF_OFFSET      (0x80)
+
+/************************************************************************
+* RGX META Stack
+************************************************************************/
+#define RGX_META_STACK_SIZE  (0xC00)
+
+/************************************************************************
+* RGX META Core memory
+************************************************************************/
+#define RGX_META_COREMEM_BSS_SIZE    (0xA00)
+#define RGX_META_COREMEM_DATA_SIZE   (RGX_META_COREMEM_BSS_SIZE + RGX_META_STACK_SIZE)
+#define RGX_META_COREMEM_CODE_SIZE   (RGX_META_COREMEM_SIZE - RGX_META_COREMEM_DATA_SIZE)
+/* code and data both map to the same physical memory */
+#define RGX_META_COREMEM_CODE_ADDR   (0x80000000)
+#define RGX_META_COREMEM_DATA_ADDR   (0x82000000)
+#define RGX_META_COREMEM_STACK_ADDR  (RGX_META_COREMEM_DATA_ADDR)
+#define RGX_META_COREMEM_BSS_ADDR    (RGX_META_COREMEM_STACK_ADDR + RGX_META_STACK_SIZE)
+/* because data and code share the same memory, base address for code is offset by the data */
+#define RGX_META_COREMEM_CODE_BADDR  (RGX_META_COREMEM_CODE_ADDR + RGX_META_COREMEM_DATA_SIZE)
+
+#define RGX_META_IS_COREMEM_CODE(A)  (((A) >= RGX_META_COREMEM_CODE_BADDR) && ((A) < (RGX_META_COREMEM_CODE_ADDR + RGX_META_COREMEM_SIZE)))
+#define RGX_META_IS_COREMEM_DATA(A)  (((A) >= RGX_META_COREMEM_DATA_ADDR) && ((A) < (RGX_META_COREMEM_DATA_ADDR + RGX_META_COREMEM_DATA_SIZE)))
+
+/************************************************************************
+* 2nd thread
+************************************************************************/
+#define RGXFW_THR1_PC          (0x18930000)
+#define RGXFW_THR1_SP          (0x78890000)
+
+/************************************************************************
+* META compatibility
+************************************************************************/
+
+#define META_CR_CORE_ID                        (0x04831000)
+#define META_CR_CORE_ID_VER_SHIFT      (16U)
+#define META_CR_CORE_ID_VER_CLRMSK     (0XFF00FFFFU)
+
+#if (RGX_FEATURE_META == MTP218)
+#define RGX_CR_META_CORE_ID_VALUE 0x19
+#elif (RGX_FEATURE_META == MTP219)
+#define RGX_CR_META_CORE_ID_VALUE 0x1E
+#elif (RGX_FEATURE_META == LTP218)
+#define RGX_CR_META_CORE_ID_VALUE 0x1C
+#elif (RGX_FEATURE_META == LTP217)
+#define RGX_CR_META_CORE_ID_VALUE 0x1F
+#else
+#error "Unknown META ID"
+#endif
+
+#endif /*  __RGX_META_H__ */
+
+/******************************************************************************
+ End of file (rgx_meta.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/include/rgx_options_km.h b/drivers/gpu/rogue_m/include/rgx_options_km.h
new file mode 100644 (file)
index 0000000..475ff51
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX KM build options
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Each build option listed here is packed into a dword which
+ * provides up to log2(RGX_BUILD_OPTIONS_MASK_KM + 1) flags.
+ * The corresponding bit is set if the build option 
+ * was enabled at compile time.
+ *
+ * In order to extract the enabled build flags the INTERNAL_TEST
+ * switch should be enabled in a client program which includes this
+ * header. Then the client can test specific build flags by reading
+ * the bit value at ##OPTIONNAME##_SET_OFFSET in RGX_BUILD_OPTIONS_KM.
+ *
+ * IMPORTANT: add new options to unused bits or define a new dword
+ * (e.g. RGX_BUILD_OPTIONS_KM2) so that the bitfield remains backwards
+ * compatible.
+ */
+
+#define RGX_BUILD_OPTIONS_MASK_KM 0x0000FFFFUL
+
+#if defined(NO_HARDWARE) || defined (INTERNAL_TEST)
+       #define NO_HARDWARE_SET_OFFSET  OPTIONS_BIT0
+       #define OPTIONS_BIT0            (0x1ul << 0)
+       #if OPTIONS_BIT0 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT0            0x0
+#endif /* NO_HARDWARE */
+
+
+#if defined(PDUMP) || defined (INTERNAL_TEST)
+       #define PDUMP_SET_OFFSET        OPTIONS_BIT1
+       #define OPTIONS_BIT1            (0x1ul << 1)
+       #if OPTIONS_BIT1 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT1            0x0
+#endif /* PDUMP */
+
+
+#if defined(SUPPORT_META_SLAVE_BOOT) || defined (INTERNAL_TEST)
+       #define SUPPORT_META_SLAVE_BOOT_SET_OFFSET      OPTIONS_BIT2
+       #define OPTIONS_BIT2            (0x1ul << 2)
+       #if OPTIONS_BIT2 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT2            0x0
+#endif /* SUPPORT_META_SLAVE_BOOT */
+
+
+#if defined(SUPPORT_MMU_FREELIST) || defined (INTERNAL_TEST)
+       #define SUPPORT_MMU_FREELIST_SET_OFFSET OPTIONS_BIT3
+       #define OPTIONS_BIT3            (0x1ul << 3)
+       #if OPTIONS_BIT3 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT3            0x0
+#endif /* SUPPORT_MMU_FREELIST */
+
+
+#if defined(SUPPORT_RGX) || defined (INTERNAL_TEST)
+       #define SUPPORT_RGX_SET_OFFSET  OPTIONS_BIT4
+       #define OPTIONS_BIT4            (0x1ul << 4)
+       #if OPTIONS_BIT4 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT4            0x0
+#endif /* SUPPORT_RGX */
+
+
+#if defined(SUPPORT_SECURE_EXPORT) || defined (INTERNAL_TEST)
+       #define SUPPORT_SECURE_EXPORT_SET_OFFSET        OPTIONS_BIT5
+       #define OPTIONS_BIT5            (0x1ul << 5)
+       #if OPTIONS_BIT5 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT5            0x0
+#endif /* SUPPORT_SECURE_EXPORT */
+
+
+#if defined(SUPPORT_INSECURE_EXPORT) || defined (INTERNAL_TEST)
+       #define SUPPORT_INSECURE_EXPORT_SET_OFFSET      OPTIONS_BIT6
+       #define OPTIONS_BIT6            (0x1ul << 6)
+       #if OPTIONS_BIT6 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT6    0x0
+#endif /* SUPPORT_INSECURE_EXPORT */
+
+
+#if defined(SUPPORT_VFP) || defined (INTERNAL_TEST)
+       #define SUPPORT_VFP_SET_OFFSET  OPTIONS_BIT7
+       #define OPTIONS_BIT7            (0x1ul << 7)
+       #if OPTIONS_BIT7 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT7            0x0
+#endif /* SUPPORT_VFP */
+
+
+#if defined(SUPPORT_DRM) || defined (INTERNAL_TEST)
+       #define SUPPORT_DRM_SET_OFFSET  OPTIONS_BIT8
+       #define OPTIONS_BIT8            (0x1ul << 8)
+       #if OPTIONS_BIT8 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT8            0x0
+#endif /* SUPPORT_DRM */
+
+
+#if defined(SUPPORT_ION) || defined (INTERNAL_TEST)
+       #define SUPPORT_ION_SET_OFFSET  OPTIONS_BIT9
+       #define OPTIONS_BIT9            (0x1ul << 9)
+       #if OPTIONS_BIT9 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT9            0x0
+#endif /* SUPPORT_ION */
+
+#if defined(DEBUG) || defined (INTERNAL_TEST)
+       #define DEBUG_SET_OFFSET        OPTIONS_BIT10
+       #define OPTIONS_BIT10           (0x1ul << 10)
+       #if OPTIONS_BIT10 > RGX_BUILD_OPTIONS_MASK_KM
+       #error "Bit exceeds reserved range"
+       #endif
+#else
+       #define OPTIONS_BIT10           0x0
+#endif /* DEBUG */
+
+
+#define RGX_BUILD_OPTIONS_KM   \
+       OPTIONS_BIT0  |\
+       OPTIONS_BIT1  |\
+       OPTIONS_BIT2  |\
+       OPTIONS_BIT3  |\
+       OPTIONS_BIT4  |\
+       OPTIONS_BIT6  |\
+       OPTIONS_BIT7  |\
+       OPTIONS_BIT8  |\
+       OPTIONS_BIT9  |\
+       OPTIONS_BIT10
+
+
diff --git a/drivers/gpu/rogue_m/include/rgxscript.h b/drivers/gpu/rogue_m/include/rgxscript.h
new file mode 100644 (file)
index 0000000..d6f21c0
--- /dev/null
@@ -0,0 +1,179 @@
+/*************************************************************************/ /*!
+@File
+@Title          rgx kernel services structues/functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX initialisation script definitions.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __RGXSCRIPT_H__
+#define __RGXSCRIPT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define        RGX_MAX_INIT_COMMANDS   (256)
+#define        RGX_MAX_DEBUG_COMMANDS  (320)
+#define        RGX_MAX_DBGBUS_COMMANDS (4096)
+#define        RGX_MAX_DEINIT_COMMANDS (32)
+#define RGX_DBG_CMD_NAME_SIZE  (40)
+
+typedef        enum _RGX_INIT_OPERATION
+{
+       RGX_INIT_OP_ILLEGAL = 0,
+       RGX_INIT_OP_WRITE_HW_REG,
+       RGX_INIT_OP_POLL_64_HW_REG,
+       RGX_INIT_OP_POLL_HW_REG,
+       RGX_INIT_OP_COND_POLL_HW_REG,
+       RGX_INIT_OP_LOOP_POINT,
+       RGX_INIT_OP_COND_BRANCH,
+       RGX_INIT_OP_HALT,
+       RGX_INIT_OP_DBG_READ32_HW_REG,
+       RGX_INIT_OP_DBG_READ64_HW_REG,
+       RGX_INIT_OP_DBG_CALC,
+       RGX_INIT_OP_DBG_WAIT,
+       RGX_INIT_OP_DBG_STRING,
+       RGX_INIT_OP_PDUMP_HW_REG,
+} RGX_INIT_OPERATION;
+
+typedef union _RGX_INIT_COMMAND_
+{
+       RGX_INIT_OPERATION eOp;
+       
+       struct {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_UINT32 ui32Value;
+       } sWriteHWReg;
+
+       struct {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_UINT32 ui32Value;
+       } sPDumpHWReg;
+       
+       struct 
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_UINT64 ui64Value;
+               IMG_UINT64 ui64Mask;            
+       } sPoll64HWReg;
+
+       struct 
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_UINT32 ui32Value;
+               IMG_UINT32 ui32Mask;            
+       } sPollHWReg;
+       
+       struct 
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32CondOffset;
+               IMG_UINT32 ui32CondValue;
+               IMG_UINT32 ui32CondMask;                
+               IMG_UINT32 ui32Offset;
+               IMG_UINT32 ui32Value;
+               IMG_UINT32 ui32Mask;            
+       } sCondPollHWReg;
+       
+       struct
+       {
+               RGX_INIT_OPERATION eOp;
+       } sLoopPoint;
+
+       struct
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_UINT32 ui32Value;
+               IMG_UINT32 ui32Mask;
+
+       } sConditionalBranchPoint;
+
+       struct 
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset;
+               IMG_CHAR aszName[RGX_DBG_CMD_NAME_SIZE];
+       } sDBGReadHWReg;
+
+       struct
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32Offset1;
+               IMG_UINT32 ui32Offset2;
+               IMG_UINT32 ui32Offset3;
+               IMG_CHAR aszName[RGX_DBG_CMD_NAME_SIZE];
+       } sDBGCalc;
+
+       struct
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_UINT32 ui32WaitInUs;
+       } sDBGWait;
+
+       struct
+       {
+               RGX_INIT_OPERATION eOp;
+               IMG_CHAR aszString[RGX_DBG_CMD_NAME_SIZE];
+       } sDBGString;
+
+} RGX_INIT_COMMAND;
+
+typedef struct _RGX_INIT_SCRIPTS_
+{
+       RGX_INIT_COMMAND asInitCommands[RGX_MAX_INIT_COMMANDS];
+       RGX_INIT_COMMAND asDbgCommands[RGX_MAX_DEBUG_COMMANDS];
+       RGX_INIT_COMMAND asDbgBusCommands[RGX_MAX_DBGBUS_COMMANDS];
+       RGX_INIT_COMMAND asDeinitCommands[RGX_MAX_DEINIT_COMMANDS];
+} RGX_SCRIPTS;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __RGXSCRIPT_H__ */
+
+/*****************************************************************************
+ End of file (rgxscript.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/ri_typedefs.h b/drivers/gpu/rogue_m/include/ri_typedefs.h
new file mode 100644 (file)
index 0000000..c7e9a46
--- /dev/null
@@ -0,0 +1,55 @@
+/*************************************************************************/ /*!
+@File
+@Title          Resource Information (RI) Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Client side part of RI management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RI_TYPEDEFS_H
+#define RI_TYPEDEFS_H
+
+#include "img_types.h"
+
+#define RI_MAX_TEXT_LEN 80
+
+typedef struct RI_SUBLIST_ENTRY RI_ENTRY;
+typedef RI_ENTRY* RI_HANDLE;
+
+#endif /* #ifndef RI_TYPEDEFS_H */
+
diff --git a/drivers/gpu/rogue_m/include/services.h b/drivers/gpu/rogue_m/include/services.h
new file mode 100644 (file)
index 0000000..06e1ab5
--- /dev/null
@@ -0,0 +1,1337 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services API Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exported services API details
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SERVICES_H__
+#define __SERVICES_H__
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+       #if !defined(OSID_BITS_FLAGS_OFFSET)
+               #define  OSID_BITS_FLAGS_OFFSET 20
+               #define  OSID_BITS_FLAGS_MASK   7
+       #endif
+
+       #if !defined(GPUVIRT_VALIDATION_MAX_STRING_LENGTH)
+               #define GPUVIRT_VALIDATION_MAX_STRING_LENGTH 100
+       #endif
+
+       #if !defined(GPUVIRT_VALIDATION_NUM_REGIONS)
+               #define GPUVIRT_VALIDATION_NUM_REGIONS  2
+       #endif
+
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "sync_external.h"
+#include "pdumpdefs.h"
+#include "lock_types.h"
+#include "pvr_debug.h"
+
+/* FIXME: Can't do this as dc_client includes services.h
+#include "dc_client.h"
+*/
+
+#if defined(LDDM)
+/* LDDM build needs to include this for the allocation structure */
+#include "umallocation.h"
+#endif
+
+#include "pvrsrv_device_types.h"
+
+/* The comment below is the front page for code-generated doxygen documentation */
+/*!
+ ******************************************************************************
+ @mainpage
+ This document details the APIs and implementation of the Consumer Services.
+ It is intended to be used in conjunction with the Consumer Services
+ Software Architectural Specification and the Consumer Services Software
+ Functional Specification.
+ *****************************************************************************/
+
+/******************************************************************************
+ *     #defines
+ *****************************************************************************/
+
+/*! 4k page size definition */
+#define PVRSRV_4K_PAGE_SIZE                                    4096UL      /*!< Size of a 4K Page */
+#define PVRSRV_4K_PAGE_SIZE_ALIGNSHIFT         12          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+/*! 16k page size definition */
+#define PVRSRV_16K_PAGE_SIZE                                   16384UL      /*!< Size of a 16K Page */
+#define PVRSRV_16K_PAGE_SIZE_ALIGNSHIFT                14          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+/*! 64k page size definition */
+#define PVRSRV_64K_PAGE_SIZE                                   65536UL      /*!< Size of a 64K Page */
+#define PVRSRV_64K_PAGE_SIZE_ALIGNSHIFT                16          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+/*! 256k page size definition */
+#define PVRSRV_256K_PAGE_SIZE                                  262144UL      /*!< Size of a 256K Page */
+#define PVRSRV_256K_PAGE_SIZE_ALIGNSHIFT               18          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+/*! 1MB page size definition */
+#define PVRSRV_1M_PAGE_SIZE                                    1048576UL      /*!< Size of a 1M Page */
+#define PVRSRV_1M_PAGE_SIZE_ALIGNSHIFT         20          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+/*! 2MB page size definition */
+#define PVRSRV_2M_PAGE_SIZE                                    2097152UL      /*!< Size of a 2M Page */
+#define PVRSRV_2M_PAGE_SIZE_ALIGNSHIFT         21          /*!< Amount to shift an address by so that
+                                                          it is always page-aligned */
+
+
+#define EVENTOBJNAME_MAXLENGTH (50) /*!< Max length of an event object name */
+
+
+/*!
+       Flags for Services connection.
+       Allows to define per-client policy for Services
+*/
+#define SRV_FLAGS_PERSIST              (1U << 0)  /*!< Persist client flag */
+#define SRV_FLAGS_INIT_PROCESS (1U << 1)  /*!< Allows connect to succeed if SrvInit
+                                            * has not yet run (used by SrvInit itself) */
+#define SRV_FLAGS_PDUMPCTRL     (1U << 31) /*!< PDump Ctrl client flag */
+
+/*
+       Pdump flags which are accessible to Services clients
+*/
+/* FIXME: defined to be the same as
+ * #define PDUMP_FLAGS_CONTINUOUS              0x40000000UL
+ * (from services/include/pdump.h)
+ * The flags need to either be moved here, or e.g. all PDump functions need a bContinuous parameter
+ */
+#define PVRSRV_PDUMP_FLAGS_CONTINUOUS          0x40000000UL /*!< pdump continuous */
+
+#define PVRSRV_UNDEFINED_HEAP_ID                       (~0LU)
+
+/*!
+ ******************************************************************************
+ * User Module type
+ *****************************************************************************/
+typedef enum
+{
+       IMG_EGL                         = 0x00000001,       /*!< EGL Module */
+       IMG_OPENGLES1           = 0x00000002,       /*!< OGLES1 Module */
+       IMG_OPENGLES3           = 0x00000003,       /*!< OGLES3 Module */
+       IMG_D3DM                        = 0x00000004,       /*!< D3DM Module */
+       IMG_SRV_UM                      = 0x00000005,       /*!< Services User-Mode */
+       IMG_SRV_INIT            = 0x00000006,           /*!< Services initialisation */
+       IMG_SRVCLIENT           = 0x00000007,       /*!< Services Client */
+       IMG_OPENGL                      = 0x00000008,       /*!< OpenGL */
+       IMG_D3D                         = 0x00000009,       /*!< D3D */
+       IMG_OPENCL                      = 0x0000000A,       /*!< OpenCL */
+       IMG_ANDROID_HAL         = 0x0000000B,       /*!< Graphics HAL */
+       IMG_WEC_GPE                     = 0x0000000C,           /*!< WinEC-specific GPE */
+       IMG_PVRGPE                      = 0x0000000D,           /*!< WinEC/WinCE GPE */
+       IMG_RSCOMPUTE       = 0x0000000E,       /*!< RenderScript Compute */
+       IMG_OPENRL          = 0x0000000F,       /*!< OpenRL Module */
+       IMG_PDUMPCTRL           = 0x00000010,       /*!< PDump control client */
+       IMG_USC2                        = 0x00000011,       /*!< Uniflex compiler */
+
+} IMG_MODULE_ID;
+
+/*! Max length of an App-Hint string */
+#define APPHINT_MAX_STRING_SIZE        256
+
+/*!
+ ******************************************************************************
+ * IMG data types
+ *****************************************************************************/
+typedef enum
+{
+       IMG_STRING_TYPE         = 1,                    /*!< String type */
+       IMG_FLOAT_TYPE          ,                       /*!< Float type */
+       IMG_UINT_TYPE           ,                       /*!< Unsigned Int type */
+       IMG_INT_TYPE            ,                       /*!< (Signed) Int type */
+       IMG_FLAG_TYPE                               /*!< Flag Type */
+}IMG_DATA_TYPE;
+
+
+/******************************************************************************
+ * Structure definitions.
+ *****************************************************************************/
+
+/*!
+ * Forward declaration
+ */
+typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
+/*!
+ * Forward declaration (look on connection.h)
+ */
+typedef struct _PVRSRV_CONNECTION_ PVRSRV_CONNECTION;
+
+/*!
+ ******************************************************************************
+ * This structure allows the user mode glue code to have an OS independent
+ * set of prototypes.
+ *****************************************************************************/
+typedef struct _PVRSRV_DEV_DATA_
+{
+       PVRSRV_CONNECTION        *psConnection; /*!< Services connection info */
+       IMG_HANDLE                      hDevCookie;                             /*!< Dev cookie */
+
+} PVRSRV_DEV_DATA;
+
+/*************************************************************************/ /*! 
+    PVR Client Event handling in Services
+*/ /**************************************************************************/
+typedef enum _PVRSRV_CLIENT_EVENT_
+{
+       PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,              /*!< hw timeout event */
+} PVRSRV_CLIENT_EVENT;
+
+/**************************************************************************/ /*!
+@Function       PVRSRVClientEvent
+@Description    Handles timeouts occurring in client drivers
+@Input          eEvent          event type
+@Input          psDevData       pointer to the PVRSRV_DEV_DATA context
+@Input          pvData          client-specific data
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_ 
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(const PVRSRV_CLIENT_EVENT eEvent,
+                                                                                       PVRSRV_DEV_DATA *psDevData,
+                                                                                       IMG_PVOID pvData);
+
+/******************************************************************************
+ * PVR Services API prototypes.
+ *****************************************************************************/
+
+/**************************************************************************/ /*!
+@Function       PVRSRVConnect
+@Description    Creates a services connection from an application to the
+                services module.
+@Output         ppsConnection   on Success, *ppsConnection is set to the new 
+                                PVRSRV_CONNECTION instance.
+@Input          ui32SrvFlags    a bit-wise OR of the following:
+                                SRV_FLAGS_PERSIST
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_ 
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection,
+                                       IMG_UINT32 ui32SrvFlags);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDisconnect 
+@Description    Disconnects from the services module
+@Input          psConnection    the connection to be disconnected
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(PVRSRV_CONNECTION *psConnection);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVEnumerateDevices
+@Description    Enumerate all services managed devices in the 
+                system.
+
+                The function returns a list of the device IDs stored either
+                in the services (or constructed in the user mode glue 
+                component in certain environments). The number of devices 
+                in the list is also returned.
+
+                The user is required to provide a buffer large enough to 
+                receive an array of MAX_NUM_DEVICE_IDS *
+                PVRSRV_DEVICE_IDENTIFIER structures.
+
+                In a binary layered component which does not support dynamic
+                runtime selection, the glue code should compile to return 
+                the supported devices statically, e.g. multiple instances of
+                the same device if multiple devices are supported
+
+                In the case of an environment (for instance) where one 
+                services managed device may connect to two display devices
+                this code would enumerate all three devices and even
+                non-dynamic device selection code should retain the facility
+                to parse the list to find the index of a given device.}
+
+@Input          psConnection    Services connection
+@Output         puiNumDevices   Number of devices present in the system
+@Output         puiDevIDs       Pointer to called supplied array of
+                                PVRSRV_DEVICE_IDENTIFIER structures. The
+                                array is assumed to be at least
+                                PVRSRV_MAX_DEVICES long.
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(const PVRSRV_CONNECTION       *psConnection,
+                                                                                                       IMG_UINT32                                      *puiNumDevices,
+                                                                                                       PVRSRV_DEVICE_IDENTIFIER        *puiDevIDs);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVAcquireDeviceData
+@Description    Returns device info structure pointer for the requested device.
+                This populates a PVRSRV_DEV_DATA structure with appropriate 
+                pointers to the DevInfo structure for the device requested.
+
+                In a non-plug-and-play the first call to GetDeviceInfo for a
+                device causes device initialisation
+
+                Calls to GetDeviceInfo are reference counted
+@Input          psConnection    Services connection
+@Input          uiDevIndex      Index to the required device obtained from the 
+                                PVRSRVEnumerateDevice function 
+@Output         psDevData       The returned Device Data
+@Input          eDeviceType     Required device type. If type is unknown use 
+                                uiDevIndex to locate device data
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(PVRSRV_CONNECTION    *psConnection,
+                                                                                                       IMG_UINT32                      uiDevIndex,
+                                                                                                       PVRSRV_DEV_DATA         *psDevData,
+                                                                                                       PVRSRV_DEVICE_TYPE      eDeviceType);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPollForValue
+@Description    Polls for a value to match a masked read of System Memory.
+                The function returns when either (1) the value read back
+                matches ui32Value, or (2) the maximum number of tries has
+                been reached.
+@Input          psConnection        Services connection
+@Input          hOSEvent            Handle to OS event to wait for
+@Input          pui32LinMemAddr     the address of the memory to poll
+@Input          ui32Value           the required value
+@Input          ui32Mask            the mask to use
+@Input          ui32Waitus          interval between tries (us)
+@Input          ui32Tries           number of tries to make before giving up
+@Return                             PVRSRV_OK on success. Otherwise, a 
+                                    PVRSRV_ error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPollForValue(const PVRSRV_CONNECTION        *psConnection,
+                                                               IMG_HANDLE                              hOSEvent,
+                                                               volatile IMG_UINT32             *pui32LinMemAddr,
+                                                               IMG_UINT32                              ui32Value,
+                                                               IMG_UINT32                              ui32Mask,
+                                                               IMG_UINT32                              ui32Waitus,
+                                                               IMG_UINT32                              ui32Tries);
+
+/* this function is almost the same as PVRSRVPollForValue. The only difference
+ * is that it now handles the interval between tries itself. Therefore it can
+ * correctly handles the differences between the different platforms.
+ */
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVWaitForValue(const PVRSRV_CONNECTION        *psConnection,
+                                IMG_HANDLE                             hOSEvent,
+                                volatile IMG_UINT32            *pui32LinMemAddr,
+                                IMG_UINT32                             ui32Value,
+                                IMG_UINT32                             ui32Mask);
+
+
+/**************************************************************************/ /*!
+ @Function      PVRSRVConditionCheckCallback
+ @Description   Function prototype for use with the PVRSRVWaitForCondition()
+                API. Clients implement this callback to test if the condition
+                waited for has been met and become true.
+
+ @Input         pvUserData      Pointer to client user data needed for
+                                 the check
+ @Output        pbCondMet       Updated on exit with condition state
+
+ @Return        PVRSRV_OK  when condition tested without error
+                PVRSRV_*   other system error that will lead to the
+                           abnormal termination of the wait API.
+ */
+/******************************************************************************/
+typedef
+PVRSRV_ERROR (*PVRSRVConditionCheckCallback)(
+        IMG_PVOID  pvUserData,
+        IMG_BOOL*  pbCondMet);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVWaitForCondition
+@Description    Wait using PVRSRVEventObjectWait() for a
+                condition (pfnCallback) to become true. It periodically
+                checks the condition state by employing a loop and
+                waiting on either the event supplied or sleeping for a brief
+                time (if hEvent is null) each time the condition is
+                checked and found not to be met. When the condition is true
+                the function returns. It will also return when the time
+                period has been exceeded or an error has occurred.
+
+@Input          psConnection    Services connection
+@Input          hEvent          Event to wait on or NULL not to use event
+                                 objects but OS wait for a short time.
+@Input          pfnCallback     Client condition check callback
+@Input          pvUserData      Client user data supplied to callback
+
+@Return         PVRSRV_OK                When condition met
+                PVRSRV_ERROR_TIMEOUT  When condition not met and time is up
+                PVRSRV_*              Otherwise, some other error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForCondition(
+        const PVRSRV_CONNECTION*     psConnection,
+        IMG_HANDLE                   hEvent,
+        PVRSRVConditionCheckCallback pfnCallback,
+        IMG_PVOID                    pvUserData);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVWaitUntilSyncPrimOpReady
+@Description    Wait using PVRSRVWaitForCondition for a sync operation to
+                become ready.
+
+@Input          psConnection    Services connection
+@Input          hEvent          Event to wait on or NULL not to use event
+                                 objects but OS wait for a short time.
+@Input          psOpCookie      Sync operation cookie to test
+
+@Return         PVRSRV_OK                When condition met
+                PVRSRV_ERROR_TIMEOUT  When condition not met and time is up
+                PVRSRV_*              Otherwise, some other error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitUntilSyncPrimOpReady(
+        const PVRSRV_CONNECTION* psConnection,
+        IMG_HANDLE               hEvent,
+        PSYNC_OP_COOKIE          psOpCookie);
+
+
+/******************************************************************************
+ * PDUMP Function prototypes...
+ *****************************************************************************/
+#if defined(PDUMP)
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpInit
+@Description    Pdump initialisation
+@Input          psConnection    Services connection
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(const PVRSRV_CONNECTION *psConnection);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpStartInitPhase
+@Description    Resume the pdump init phase state   
+@Input          psConnection    Services connection
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(const PVRSRV_CONNECTION *psConnection);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpStopInitPhase
+@Description    Stop the pdump init phase state
+@Input          psConnection    Services connection
+@Input          eModuleID       Which module is requesting to stop the init phase
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(const PVRSRV_CONNECTION *psConnection,
+                                                                                               IMG_MODULE_ID eModuleID);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpSetFrame
+@Description    Sets the pdump frame
+@Input          psConnection    Services connection
+@Input          ui32Frame       frame id
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+*/ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(const PVRSRV_CONNECTION *psConnection,
+                                                                                         IMG_UINT32 ui32Frame);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpGetFrame
+@Description    Gets the current pdump frame
+@Input          psConnection    Services connection
+@Output         pui32Frame       frame id
+@Return         PVRSRV_OK on success. Otherwise, a PVRSRV_error code
+*/ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpGetFrame(const PVRSRV_CONNECTION *psConnection,
+                                                                                         IMG_UINT32 *pui32Frame);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpIsLastCaptureFrame
+@Description    Returns whether this is the last frame of the capture range
+@Input          psConnection    Services connection
+@Return                         IMG_TRUE if last frame,
+                                IMG_FALSE otherwise
+*/ /**************************************************************************/
+IMG_IMPORT
+IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsLastCaptureFrame(const PVRSRV_CONNECTION *psConnection);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpAfterRender
+@Description    Executes TraceBuffer and SignatureBuffer commands
+@Input          psDevData       Device data
+*/ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpAfterRender(PVRSRV_DEV_DATA *psDevData);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpComment
+@Description    PDumps a comment
+@Input          psConnection        Services connection
+@Input          pszComment          Comment to be inserted
+@Input          bContinuous         pdump contiunous boolean
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(const PVRSRV_CONNECTION *psConnection,
+                                                                                        const IMG_CHAR *pszComment,
+                                                                                        IMG_BOOL bContinuous);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpCommentf
+@Description    PDumps a formatted comment
+@Input          psConnection        Services connection
+@Input          bContinuous         pdump continuous boolean
+@Input          pszFormat           Format string
+@Input          ...                 vararg list
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(const PVRSRV_CONNECTION *psConnection,
+                                                                                         IMG_BOOL bContinuous,
+                                                                                         const IMG_CHAR *pszFormat, ...)
+                                                                                         IMG_FORMAT_PRINTF(3, 4);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpCommentWithFlagsf
+@Description    PDumps a formatted comment, passing in flags
+@Input          psConnection        Services connection
+@Input          ui32Flags           Flags
+@Input          pszFormat           Format string
+@Input          ...                 vararg list
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(const PVRSRV_CONNECTION *psConnection,
+                                                                                                          IMG_UINT32 ui32Flags,
+                                                                                                          const IMG_CHAR *pszFormat, ...)
+                                                                                                          IMG_FORMAT_PRINTF(3, 4);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpIsCapturing
+@Description    Reports whether PDump is currently capturing or not
+@Input          psConnection        Services connection
+@Output         pbIsCapturing       Indicates whether PDump is currently
+                                    capturing
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(const PVRSRV_CONNECTION *psConnection,
+                                                                                               IMG_BOOL *pbIsCapturing);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVPDumpIsCapturingTest
+@Description    checks whether pdump is currently in frame capture range
+@Input          psConnection        Services connection
+@Return         IMG_BOOL
+ */ /**************************************************************************/
+IMG_IMPORT
+IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(const PVRSRV_CONNECTION *psConnection);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetDefaultCaptureParams(const PVRSRV_CONNECTION *psConnection,
+                                                             IMG_UINT32 ui32Mode,
+                                                             IMG_UINT32 ui32Start,
+                                                             IMG_UINT32 ui32End,
+                                                             IMG_UINT32 ui32Interval,
+                                                             IMG_UINT32 ui32MaxParamFileSize);
+
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpInit)
+#endif
+static INLINE PVRSRV_ERROR 
+PVRSRVPDumpInit(const PVRSRV_CONNECTION *psConnection)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpStartInitPhase)
+#endif
+static INLINE PVRSRV_ERROR 
+PVRSRVPDumpStartInitPhase(const PVRSRV_CONNECTION *psConnection)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpStopInitPhase)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpStopInitPhase(const PVRSRV_CONNECTION *psConnection)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpSetFrame)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpSetFrame(const PVRSRV_CONNECTION *psConnection,
+                                       IMG_UINT32 ui32Frame)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(ui32Frame);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpGetFrame)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpGetFrame(const PVRSRV_CONNECTION *psConnection,
+                                       IMG_UINT32 *pui32Frame)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(pui32Frame);
+       return PVRSRV_OK;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpIsLastCaptureFrame)
+#endif
+static INLINE IMG_BOOL
+PVRSRVPDumpIsLastCaptureFrame(const PVRSRV_CONNECTION *psConnection)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpAfterRender)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpAfterRender(PVRSRV_DEV_DATA *psDevData)
+{
+       PVR_UNREFERENCED_PARAMETER(psDevData);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpComment)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpComment(const PVRSRV_CONNECTION *psConnection,
+                                  const IMG_CHAR *pszComment,
+                                  IMG_BOOL bContinuous)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(pszComment);
+       PVR_UNREFERENCED_PARAMETER(bContinuous);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpCommentf)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpCommentf(const PVRSRV_CONNECTION *psConnection,
+                                       IMG_BOOL bContinuous,
+                                       const IMG_CHAR *pszFormat, ...)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(bContinuous);
+       PVR_UNREFERENCED_PARAMETER(pszFormat);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpCommentWithFlagsf)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpCommentWithFlagsf(const PVRSRV_CONNECTION *psConnection,
+                                                        IMG_UINT32 ui32Flags,
+                                                        const IMG_CHAR *pszFormat, ...)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(ui32Flags);
+       PVR_UNREFERENCED_PARAMETER(pszFormat);
+       return PVRSRV_OK;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpIsCapturing)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpIsCapturing(const PVRSRV_CONNECTION *psConnection,
+                                          IMG_BOOL *pbIsCapturing)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       *pbIsCapturing = IMG_FALSE;
+       return PVRSRV_OK;
+}                                                                                              
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpIsCapturingTest)
+#endif
+static INLINE IMG_BOOL
+PVRSRVPDumpIsCapturingTest(const PVRSRV_CONNECTION *psConnection)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpSetPidCapRange)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpSetDefaultCaptureParams(const PVRSRV_CONNECTION *psConnection,
+                                   IMG_UINT32 ui32Mode,
+                                   IMG_UINT32 ui32Start,
+                                   IMG_UINT32 ui32End,
+                                   IMG_UINT32 ui32Interval,
+                                   IMG_UINT32 ui32MaxParamFileSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(ui32Mode);
+       PVR_UNREFERENCED_PARAMETER(ui32Start);
+       PVR_UNREFERENCED_PARAMETER(ui32End);
+       PVR_UNREFERENCED_PARAMETER(ui32Interval);
+       PVR_UNREFERENCED_PARAMETER(ui32MaxParamFileSize);
+
+       return PVRSRV_OK;
+}
+
+
+#endif /* PDUMP */
+
+/**************************************************************************/ /*!
+@Function       PVRSRVLoadLibrary
+@Description    Load the named Dynamic-Link (Shared) Library. This will perform
+                               reference counting in association with PVRSRVUnloadLibrary,
+                               so for example if the same library is loaded twice and unloaded once,
+                               a reference to the library will remain.
+@Input          pszLibraryName      the name of the library to load
+@Return                             On success, the handle of the newly-loaded
+                                    library. Otherwise, zero.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_HANDLE  PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVUnloadLibrary
+@Description    Unload the Dynamic-Link (Shared) Library which had previously been
+                               loaded using PVRSRVLoadLibrary(). See PVRSRVLoadLibrary() for
+                               information regarding reference counting.
+@Input          hExtDrv             handle of the Dynamic-Link / Shared library
+                                    to unload, as returned by PVRSRVLoadLibrary().
+@Return                             PVRSRV_OK if successful. Otherwise,
+                                    PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED.
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR        PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetLibFuncAddr
+@Description    Returns the address of a function in a Dynamic-Link / Shared
+                Library.
+@Input          hExtDrv             handle of the Dynamic-Link / Shared Library
+                                    in which the function resides
+@Input          pszFunctionName     the name of the function
+@Output         ppvFuncAddr         on success, the address of the function
+                                    requested. Otherwise, NULL.
+@Return                             PVRSRV_OK if successful. Otherwise,
+                                    PVRSRV_ERROR_UNABLE_TO_GET_FUNC_ADDR.
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR        PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, 
+                                            const IMG_CHAR *pszFunctionName, 
+                                            IMG_VOID **ppvFuncAddr);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVClockus
+@Description    Returns the current system clock time, in microseconds.  Note 
+                that this does not necessarily guarantee microsecond accuracy.
+@Return                             the curent system clock time, in 
+                                    microseconds
+ */ /**************************************************************************/
+IMG_IMPORT IMG_UINT32 PVRSRVClockus (void);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVWaitus
+@Description    Waits for the specified number of microseconds
+@Input          ui32Timeus          the time to wait for, in microseconds 
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReleaseThreadQuanta
+@Description    Releases thread quanta
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetCurrentProcessID
+@Description    Returns handle for current process
+@Return         ID of current process
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PID  IMG_CALLCONV PVRSRVGetCurrentProcessID(void);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVSetLocale
+@Description    Thin wrapper on posix setlocale
+@Input          pszLocale
+@Return         IMG_NULL (currently)
+ */ /**************************************************************************/
+IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCreateAppHintState
+@Description    Create app hint state
+@Input          eModuleID       module id
+@Input          pszAppName      app name
+@Output         ppvState        state
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID,
+                                                                                                               const IMG_CHAR *pszAppName,
+                                                                                                               IMG_VOID **ppvState);
+/**************************************************************************/ /*!
+@Function       PVRSRVFreeAppHintState
+@Description    Free the app hint state, if it was created
+@Input          eModuleID       module id
+@Input          pvHintState     app hint state
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID,
+                                                                                IMG_VOID *pvHintState);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetAppHint
+@Description    Return the value of this hint from state or use default
+@Input          pvHintState     hint state
+@Input          pszHintName     hint name
+@Input          eDataType       data type
+@Input          pvDefault       default value
+@Output         pvReturn        hint value
+@Return                         True if hint read, False if used default
+ */ /**************************************************************************/
+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);
+
+/******************************************************************************
+ * Memory API(s)
+ *****************************************************************************/
+
+/* Exported APIs */
+/**************************************************************************/ /*!
+@Function       PVRSRVAllocUserModeMem
+@Description    Allocate a block of user-mode memory
+@Input          ui32Size    the amount of memory to allocate
+@Return                     On success, a pointer to the memory allocated.
+                            Otherwise, NULL.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCallocUserModeMem
+@Description    Allocate a block of user-mode memory
+@Input          ui32Size    the amount of memory to allocate
+@Return                     On success, a pointer to the memory allocated.
+                            Otherwise, NULL.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T ui32Size);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReallocUserModeMem
+@Description    Re-allocate a block of memory
+@Input          pvBase      the address of the existing memory, previously
+                            allocated with PVRSRVAllocUserModeMem
+@Input          uNewSize    the newly-desired size of the memory chunk
+@Return                     On success, a pointer to the memory block. If the
+                            size of the block could not be changed, the
+                            return value is NULL.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize);
+/**************************************************************************/ /*!
+@Function       PVRSRVFreeUserModeMem
+@Description    Free a block of memory previously allocated with
+                PVRSRVAllocUserModeMem
+@Input          pvMem       pointer to the block of memory to be freed
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID  IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVMemCopy
+@Description    Copy a block of memory
+                Safe implementation of memset for use with device memory.
+@Input          pvDst       Pointer to the destination
+@Input          pvSrc       Pointer to the source location
+@Input          uiSize      The amount of memory to copy in bytes
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCachedMemCopy
+@Description    Copy a block of memory between two cached memory allocations.
+                For use only when source and destination are both cached memory allocations.
+@Input          pvDst       Pointer to the destination
+@Input          pvSrc       Pointer to the source location
+@Input          uiSize      The amount of memory to copy in bytes
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT void PVRSRVCachedMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDeviceMemCopy
+@Description    Copy a block of memory to/from a device memory allocation.
+                For use when one or both of the allocations is a device memory allocation.
+@Input          pvDst       Pointer to the destination
+@Input          pvSrc       Pointer to the source location
+@Input          uiSize      The amount of memory to copy in bytes
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVDeviceMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVMemSet
+@Description    Set all bytes in a region of memory to the specified value.
+                Safe implementation of memset for use with device memory.
+@Input          pvDest      Pointer to the start of the memory region
+@Input          ui8Value    The value to be written
+@Input          uiSize      The number of bytes to be set to ui8Value
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCachedMemSet
+@Description    Set all bytes in a region of cached memory to the specified value.
+                For use only when the destination is a cached memory allocation.
+@Input          pvDest      Pointer to the start of the memory region
+@Input          ui8Value    The value to be written
+@Input          uiSize      The number of bytes to be set to ui8Value
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVCachedMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDeviceMemSet
+@Description    Set all bytes in a region of device memory to the specified value.
+                The destination pointer should be a device memory buffer.
+@Input          pvDest      Pointer to the start of the memory region
+@Input          ui8Value    The value to be written
+@Input          uiSize      The number of bytes to be set to ui8Value
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVDeviceMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uiSize);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVLockProcessGlobalMutex
+@Description    Locking function for non-recursive coarse-grained mutex shared
+                between all threads in a proccess.
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockProcessGlobalMutex(void);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVUnlockProcessGlobalMutex
+@Description    Unlocking function for non-recursive coarse-grained mutex shared
+                between all threads in a proccess.
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockProcessGlobalMutex(void);
+
+
+typedef        struct _OS_MUTEX_ *PVRSRV_MUTEX_HANDLE;
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCreateMutex
+@Description    creates a mutex
+@Output         phMutex             ptr to mutex handle
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+#if !defined(PVR_DEBUG_MUTEXES)
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex);
+#else
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex,
+                                                                                                          IMG_CHAR pszMutexName[],
+                                                                                                          IMG_CHAR pszFilename[],
+                                                                                                          IMG_INT iLine);
+#define PVRSRVCreateMutex(phMutex) \
+       PVRSRVCreateMutex(phMutex, #phMutex, __FILE__, __LINE__)
+#endif
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDestroyMutex
+@Description    Create a mutex.
+@Input          hMutex              On success, filled with the new Mutex
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**********************************************************************/
+#if !defined(PVR_DEBUG_MUTEXES)
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex);
+#else
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex,
+                                                                                                               IMG_CHAR pszMutexName[],
+                                                                                                               IMG_CHAR pszFilename[],
+                                                                                                               IMG_INT iLine);
+#define PVRSRVDestroyMutex(hMutex) \
+       PVRSRVDestroyMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#endif
+
+/**************************************************************************/ /*!
+@Function       PVRSRVLockMutex
+@Description    Lock the mutex passed
+@Input          hMutex              handle of the mutex to be locked
+@Return         None
+ */ /**********************************************************************/
+#if !defined(PVR_DEBUG_MUTEXES)
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+#else
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex,
+                                                                                                IMG_CHAR pszMutexName[],
+                                                                                                IMG_CHAR pszFilename[],
+                                                                                                IMG_INT iLine);
+#define PVRSRVLockMutex(hMutex) \
+       PVRSRVLockMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#endif
+
+/**************************************************************************/ /*!
+@Function       PVRSRVUnlockMutex
+@Description    Unlock the mutex passed
+@Input          hMutex              handle of the mutex to be unlocked
+@Return         None
+ */ /**********************************************************************/
+#if !defined(PVR_DEBUG_MUTEXES)
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex);
+#else
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex,
+                                                                                                  IMG_CHAR pszMutexName[],
+                                                                                                  IMG_CHAR pszFilename[],
+                                                                                                  IMG_INT iLine);
+#define PVRSRVUnlockMutex(hMutex) \
+       PVRSRVUnlockMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#endif
+
+struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_;
+typedef        struct  _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE; /*!< Convenience typedef */
+
+
+#if defined(_MSC_VER)
+    /*! 
+      Used when waiting for a semaphore to become unlocked. Indicates that 
+      the caller is willing to wait forever.
+     */
+    #define IMG_SEMAPHORE_WAIT_INFINITE       ((IMG_UINT64)0xFFFFFFFFFFFFFFFF)
+#else
+    /*! 
+      Used when waiting for a semaphore to become unlocked. Indicates that 
+      the caller is willing to wait forever.
+     */
+       #define IMG_SEMAPHORE_WAIT_INFINITE       ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull)
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCreateSemaphore)
+#endif
+/**************************************************************************/ /*!
+@Function       PVRSRVCreateSemaphore
+@Description    Create a semaphore with an initial count
+@Output         phSemaphore         on success, ptr to the handle of the new 
+                                    semaphore. Otherwise, zero.
+@Input          iInitialCount       initial count
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+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
+/**************************************************************************/ /*!
+@Function       PVRSRVDestroySemaphore
+@Description    destroy the semaphore passed
+@Input          hSemaphore          the semaphore to be destroyed
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore)
+{
+       PVR_UNREFERENCED_PARAMETER(hSemaphore);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVWaitSemaphore)
+#endif
+/**************************************************************************/ /*!
+@Function       PVRSRVWaitSemaphore
+@Description    wait on the specified semaphore
+@Input          hSemaphore          the semephore on which to wait
+@Input          ui64TimeoutMicroSeconds the time to wait for the semaphore to
+                                    become unlocked, if locked when the function
+                                    is called.
+@Return                             PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                    error code
+ */ /**************************************************************************/
+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
+/**************************************************************************/ /*!
+@Function       PVRSRVPostSemaphore
+@Description    post semphore
+@Input          hSemaphore      handle to semaphore
+@Input          iPostCount      post count
+@Return         None
+ */ /**************************************************************************/
+static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount)
+{
+       PVR_UNREFERENCED_PARAMETER(hSemaphore);
+       PVR_UNREFERENCED_PARAMETER(iPostCount);
+}
+
+/* Non-exported APIs */
+#if defined(DEBUG) && (defined(__linux__) || defined(_WIN32) || defined(__QNXNTO__))
+/**************************************************************************/ /*!
+@Function       PVRSRVAllocUserModeMemTracking
+@Description    Wrapper function for malloc, used for memory-leak detection
+@Input          ui32Size            number of bytes to be allocated
+@Input          pszFileName         filename of the calling code
+@Input          ui32LineNumber      line number of the calling code
+@Return                             On success, a ptr to the newly-allocated
+                                    memory. Otherwise, NULL.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, 
+                                                                 IMG_CHAR *pszFileName, 
+                                                                 IMG_UINT32 ui32LineNumber);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVCallocUserModeMemTracking
+@Description    Wrapper function for calloc, used for memory-leak detection
+@Input          ui32Size            number of bytes to be allocated
+@Input          pszFileName         filename of the calling code
+@Input          ui32LineNumber      line number of the calling code
+@Return                             On success, a ptr to the newly-allocated
+                                    memory. Otherwise, NULL.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, 
+                                                                  IMG_CHAR *pszFileName, 
+                                                                  IMG_UINT32 ui32LineNumber);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVFreeUserModeMemTracking
+@Description    Wrapper for free - see PVRSRVAllocUserModeMemTracking
+@Input          pvMem               pointer to the memory to be freed
+@Return         None
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID  IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReallocUserModeMemTracking
+@Description    Wrapper for realloc, used in memory-leak detection
+@Input          pvMem           pointer to the existing memory block
+@Input          ui32NewSize     the desired new size of the block
+@Input          pszFileName     the filename of the calling code
+@Input          ui32LineNumber  the line number of the calling code
+@Return                         on success, a pointer to the memory block.
+                                This may not necessarily be the same
+                                location as the block was at before the
+                                call. On failure, NULL is returned.
+ */ /**************************************************************************/
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, 
+                                                                IMG_SIZE_T ui32NewSize, 
+                                                                                                                   IMG_CHAR *pszFileName, 
+                                                                IMG_UINT32 ui32LineNumber);
+#endif /* defined(DEBUG) && (defined(__linux__) || defined(_WIN32)) */
+
+/**************************************************************************/ /*!
+@Function       PVRSRVDumpDebugInfo
+@Description    Dump debug information to kernel log
+@Input          psConnection    Services connection
+@Return         IMG_VOID
+ */ /**************************************************************************/
+IMG_IMPORT IMG_VOID
+PVRSRVDumpDebugInfo(const PVRSRV_CONNECTION *psConnection, IMG_UINT32 ui32VerbLevel);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVGetDevClockSpeed
+@Description    Gets the clock speed
+@Input          psConnection           Services connection
+@Input          psDevData                      Pointer to the PVRSRV_DEV_DATA context
+@Output         pui32ClockSpeed     Variable for storing clock speed
+@Return         IMG_BOOL                       True if the operation was successful
+ */ /**************************************************************************/
+IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetDevClockSpeed(const PVRSRV_CONNECTION *psConnection,
+                                                                                                               PVRSRV_DEV_DATA  *psDevData,
+                                                                                                               IMG_PUINT32 pui32ClockSpeed);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVResetHWRLogs
+@Description    Resets the HWR Logs buffer (the hardware recovery count is not reset)
+@Input          psConnection           Services connection
+@Input          psDevData                      Pointer to the PVRSRV_DEV_DATA context
+@Return         PVRSRV_ERROR           PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                       error code
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVResetHWRLogs(const PVRSRV_CONNECTION *psConnection, PVRSRV_DEV_DATA  *psDevData);
+
+
+/******************************************************************************
+ * PVR Global Event Object - Event APIs
+ *****************************************************************************/
+
+/*****************************************************************************
+@Function       PVRSRVAcquireGlobalEventHandle
+@Description    Gets a handle to an event that is opened on the global
+                event object.
+@Input          psConnection    Services connection
+@Output         phEvent         Global event handle
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVAcquireGlobalEventHandle(const PVRSRV_CONNECTION *psConnection,
+                               IMG_HANDLE *phEvent);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVReleaseGlobalEventHandle
+@Description    Destroys the event handle previously acquired.
+@Input          psConnection    Services connection
+@Input          phEvent         Global event handle
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVReleaseGlobalEventHandle(const PVRSRV_CONNECTION *psConnection,
+                               IMG_HANDLE hEvent);
+
+/**************************************************************************/ /*!
+@Function       PVRSRVEventObjectWait
+@Description    Wait (block) on the OS-specific event object passed
+@Input          psConnection    Services connection
+@Input          hEvent          Global event handle to wait on
+@Return                         PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                error code
+ */ /**************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
+                      IMG_HANDLE hEvent);
+
+/******************************************************************************
+ * PVR Global Event Object - Event APIs End
+ *****************************************************************************/
+
+
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVKickDevices(const PVRSRV_CONNECTION *psConnection);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVSoftReset
+@Description    Resets some modules of the device
+@Input          psConnection    Services connection
+@Input          psDevData              Pointer to the PVRSRV_DEV_DATA context
+@Input          ui64ResetValue1 A mask for which each bit set corresponds
+                                to a module to reset (via the SOFT_RESET
+                                register).
+@Input          ui64ResetValue2 A mask for which each bit set corresponds
+                                to a module to reset (via the SOFT_RESET2
+                                register).
+@Return         PVRSRV_ERROR
+*/ /***************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVSoftReset(const PVRSRV_CONNECTION *psConnection,
+                               PVRSRV_DEV_DATA  *psDevData,
+                               IMG_UINT64 ui64ResetValue1,
+                               IMG_UINT64 ui64ResetValue2);
+
+/*!
+ Time wrapping macro
+*/
+#define TIME_NOT_PASSED_UINT32(a,b,c)          (((a) - (b)) < (c))
+
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __SERVICES_H__ */
+
+/******************************************************************************
+ End of file (services.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/servicesext.h b/drivers/gpu/rogue_m/include/servicesext.h
new file mode 100644 (file)
index 0000000..f6fc8c1
--- /dev/null
@@ -0,0 +1,195 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services definitions required by external drivers
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Provides services data structures, defines and prototypes
+                required by external drivers
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__SERVICESEXT_H__)
+#define __SERVICESEXT_H__
+
+/* include/ */
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "img_3dtypes.h"
+#include "pvrsrv_device_types.h"
+
+
+/*
+ * Lock buffer read/write flags
+ */
+#define PVRSRV_LOCKFLG_READONLY        (1)             /*!< The locking process will only read the locked surface */
+
+/*!
+ *****************************************************************************
+ *     Services State
+ *****************************************************************************/
+typedef enum _PVRSRV_SERVICES_STATE_
+{
+       PVRSRV_SERVICES_STATE_OK = 0,
+       PVRSRV_SERVICES_STATE_BAD,
+} PVRSRV_SERVICES_STATE;
+
+
+/*!
+ *****************************************************************************
+ *     States for power management
+ *****************************************************************************/
+/*!
+  System Power State Enum
+ */
+typedef enum _PVRSRV_SYS_POWER_STATE_
+{
+       PVRSRV_SYS_POWER_STATE_Unspecified              = -1,   /*!< Unspecified : Uninitialised */
+       PVRSRV_SYS_POWER_STATE_OFF                              = 0,    /*!< Off */
+       PVRSRV_SYS_POWER_STATE_ON                               = 1,    /*!< On */
+
+       PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff   /*!< Force enum to be at least 32-bits wide */
+
+} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE; /*!< Typedef for ptr to PVRSRV_SYS_POWER_STATE */
+
+/*!
+  Device Power State Enum
+ */
+typedef enum _PVRSRV_DEV_POWER_STATE_
+{
+       PVRSRV_DEV_POWER_STATE_DEFAULT  = -1,   /*!< Default state for the device */
+       PVRSRV_DEV_POWER_STATE_OFF              = 0,    /*!< Unpowered */
+       PVRSRV_DEV_POWER_STATE_ON               = 1,    /*!< Running */
+
+       PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff   /*!< Force enum to be at least 32-bits wide */
+
+} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE;    /*!< Typedef for ptr to PVRSRV_DEV_POWER_STATE */ /* PRQA S 3205 */
+
+
+/* Power transition handler prototypes */
+
+/*! 
+  Typedef for a pointer to a Function that will be called before a transition
+  from one power state to another. See also PFN_POST_POWER.
+ */
+typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE                              hDevHandle,
+                                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState,
+                                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState,
+                                                                          IMG_BOOL                                     bForced);
+/*! 
+  Typedef for a pointer to a Function that will be called after a transition
+  from one power state to another. See also PFN_PRE_POWER.
+ */
+typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE                             hDevHandle,
+                                                                               PVRSRV_DEV_POWER_STATE  eNewPowerState,
+                                                                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState,
+                                                                               IMG_BOOL                                bForced);
+
+/* Clock speed handler prototypes */
+
+/*!
+  Typedef for a pointer to a Function that will be caled before a transition
+  from one clockspeed to another. See also PFN_POST_CLOCKSPEED_CHANGE.
+ */
+typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE                          hDevHandle,
+                                                                                                  PVRSRV_DEV_POWER_STATE       eCurrentPowerState);
+
+/*!
+  Typedef for a pointer to a Function that will be caled after a transition
+  from one clockspeed to another. See also PFN_PRE_CLOCKSPEED_CHANGE.
+ */
+typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE                         hDevHandle,
+                                                                                                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
+
+/*!
+  Typedef for a pointer to a function that will be called to transition the device
+  to a forced idle state. Used in unison with (forced) power requests, DVFS and cluster count changes.
+ */
+typedef PVRSRV_ERROR (*PFN_FORCED_IDLE_REQUEST) (IMG_HANDLE                            hDevHandle,
+                                                       IMG_BOOL                        bDeviceOffPermitted);
+
+/*!
+  Typedef for a pointer to a function that will be called to cancel a forced idle state
+  and return the firmware back to a state where the hardware can be scheduled.
+ */
+typedef PVRSRV_ERROR (*PFN_FORCED_IDLE_CANCEL_REQUEST) (IMG_HANDLE                     hDevHandle);
+
+typedef PVRSRV_ERROR (*PFN_DUST_COUNT_REQUEST) (IMG_HANDLE                     hDevHandle,
+                                               IMG_UINT32                      ui32DustCount);
+
+/*!
+ *****************************************************************************
+ * Enumeration of possible alpha types.
+ *****************************************************************************/
+typedef enum _PVRSRV_COLOURSPACE_FORMAT_ {
+       PVRSRV_COLOURSPACE_FORMAT_UNKNOWN               =  0x00000000,  /*!< Colourspace Format: Unknown */
+       PVRSRV_COLOURSPACE_FORMAT_LINEAR                =  0x00010000,  /*!< Colourspace Format: Linear */
+       PVRSRV_COLOURSPACE_FORMAT_NONLINEAR             =  0x00020000,  /*!< Colourspace Format: Non-Linear */
+       PVRSRV_COLOURSPACE_FORMAT_MASK                  =  0x000F0000,  /*!< Colourspace Format Mask */
+} PVRSRV_COLOURSPACE_FORMAT;
+
+
+/*!
+ * Drawable orientation (in degrees clockwise).
+ */
+typedef enum _IMG_ROTATION_ PVRSRV_ROTATION;
+
+#define PVRSRV_ROTATE_0 IMG_ROTATION_0DEG
+#define PVRSRV_ROTATE_90 IMG_ROTATION_90DEG
+#define PVRSRV_ROTATE_180 IMG_ROTATION_180DEG
+#define PVRSRV_ROTATE_270 IMG_ROTATION_270DEG
+#define PVRSRV_FLIP_Y IMG_ROTATION_FLIP_Y
+
+
+/*!
+ *****************************************************************************
+ * This structure is used for OS independent registry (profile) access
+ *****************************************************************************/
+
+typedef struct _PVRSRV_REGISTRY_INFO
+{
+       IMG_UINT32                      ui32DevCookie;
+       IMG_PCHAR                       pszKey;
+       IMG_PCHAR                       pszValue;
+       IMG_PCHAR                       pszBuf;
+       IMG_UINT32                      ui32BufSize;
+} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO;
+
+#endif /* __SERVICESEXT_H__ */
+/*****************************************************************************
+ End of file (servicesext.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/include/sync_external.h b/drivers/gpu/rogue_m/include/sync_external.h
new file mode 100644 (file)
index 0000000..7ee0945
--- /dev/null
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services external synchronisation interface header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines synchronisation structures that are visible internally
+                and externally
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+
+#ifndef _SYNC_EXTERNAL_
+#define _SYNC_EXTERNAL_
+
+#define SYNC_MAX_CLASS_NAME_LEN 32
+
+typedef IMG_HANDLE SYNC_BRIDGE_HANDLE;
+typedef struct SYNC_PRIM_CONTEXT *PSYNC_PRIM_CONTEXT;
+typedef struct _SYNC_OP_COOKIE_ *PSYNC_OP_COOKIE;
+
+typedef struct PVRSRV_CLIENT_SYNC_PRIM
+{
+       volatile IMG_UINT32     *pui32LinAddr;  /*!< User pointer to the primitive */
+} PVRSRV_CLIENT_SYNC_PRIM;
+
+typedef IMG_HANDLE PVRSRV_CLIENT_SYNC_PRIM_HANDLE;
+
+typedef struct PVRSRV_CLIENT_SYNC_PRIM_OP
+{
+       IMG_UINT32                                      ui32Flags;                              /*!< Operation flags */
+#define PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK       (1 << 0)
+#define PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE      (1 << 1)
+#define PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE (PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE | (1<<2))
+       PVRSRV_CLIENT_SYNC_PRIM         *psSync;                                /*!< Pointer to the client sync */
+       IMG_UINT32                                      ui32FenceValue;                 /*!< The Fence value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK is set) */
+       IMG_UINT32                                      ui32UpdateValue;                /*!< The Update value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE is set) */
+} PVRSRV_CLIENT_SYNC_PRIM_OP;
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+#endif /* _SYNC_EXTERNAL_ */
diff --git a/drivers/gpu/rogue_m/include/system/rgx_tc/apollo_regs.h b/drivers/gpu/rogue_m/include/system/rgx_tc/apollo_regs.h
new file mode 100644 (file)
index 0000000..66b0acd
--- /dev/null
@@ -0,0 +1,159 @@
+/*************************************************************************/ /*!
+@File          
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__APOLLO_REGS_H__)
+#define __APOLLO_REGS_H__
+
+/*
+ * The core clock speed is passed through a multiplier depending on the TC version.
+ *
+ * On TC_ES1: Multiplier = x3, final speed = 270MHz
+ * On TC_ES2: Multiplier = x6, final speed = 540MHz
+ * On TCF5:   Multiplier = 1x final speed = 45MHz
+ *
+ *
+ * The base (unmultiplied speed) can be adjusted using a module parameter called "sys_core_clk_speed",
+ * a number in Hz.
+ *
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_core_clk_speed=60000000" /etc/init.d/rc.pvr start
+ *
+ * would result in a core speed of 60MHz xMultiplier.
+ *
+ *
+ *
+ *
+ * The memory clock is unmultiplied and can be adjusted using a module parameter called 
+ * "sys_mem_clk_speed", this should be the number in Hz for the memory clock speed.
+ * 
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=100000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the memory clock speed set to 100MHz.
+ *
+ *
+ * Same applies to the system interface clock speed sys_sysif_clk_speed.
+ * Needed for TCF5 but not for TC_ES2/ES1.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=45000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the system clock speed set to 45MHz.
+ *
+ *
+ * All parameters can be specified at once, eg:
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=MEMORY_SPEED sys_core_clk_speed=CORE_SPEED sys_mem_clk_speed=SYSIF_SPEED" /etc/init.d/rc.pvr start
+ */
+
+ /* TC TCF5 */
+#define RGX_TC_SYS_CLOCK_SPEED         (45000000) /*< At the moment just used for TCF5 */
+
+#if defined(TC_APOLLO_TCF5)
+ #define RGX_TC_CORE_CLOCK_SPEED       (45000000)
+ #define RGX_TC_MEM_CLOCK_SPEED                (45000000)
+
+#elif defined(TC_APOLLO_BONNIE)
+ /* TC Bonnie */
+ #define RGX_TC_CORE_CLOCK_SPEED       (18000000)
+ #define RGX_TC_MEM_CLOCK_SPEED                (65000000)
+
+#elif defined(TC_APOLLO_ES2)
+ /* TC ES2 */
+ #define RGX_TC_CORE_CLOCK_SPEED       (90000000)
+ #define RGX_TC_MEM_CLOCK_SPEED                (104000000)
+ #define TCF_TEMP_SENSOR_SPI_OFFSET    0xe
+ #define TCF_TEMP_SENSOR_TO_C(raw)     (((raw) * 248 / 4096) - 54)
+
+#else
+ /* TC ES1 */
+ #define RGX_TC_CORE_CLOCK_SPEED       (90000000)
+ #define RGX_TC_MEM_CLOCK_SPEED                (65000000)
+#endif
+
+/* Number of bytes that are broken */
+#define SYS_DEV_MEM_BROKEN_BYTES       (1024 * 1024)
+#define SYS_DEV_MEM_REGION_SIZE                (0x40000000 - SYS_DEV_MEM_BROKEN_BYTES)
+
+/* Apollo reg on base register 0 */
+#define SYS_APOLLO_REG_PCI_BASENUM     (0)
+#define SYS_APOLLO_REG_REGION_SIZE     (0x00010000)
+
+#define SYS_APOLLO_REG_SYS_OFFSET      (0x0000)
+#define SYS_APOLLO_REG_SYS_SIZE                (0x0400)
+
+#define SYS_APOLLO_REG_PLL_OFFSET      (0x1000)
+#define SYS_APOLLO_REG_PLL_SIZE                (0x0400)
+
+#define SYS_APOLLO_REG_HOST_OFFSET     (0x4050)
+#define SYS_APOLLO_REG_HOST_SIZE       (0x0014)
+
+#define SYS_APOLLO_REG_PDP_OFFSET      (0xC000)
+#define SYS_APOLLO_REG_PDP_SIZE                (0x0400)
+
+/* Offsets for flashing Apollo PROMs from base 0 */
+#define APOLLO_FLASH_STAT_OFFSET       (0x4058)
+#define APOLLO_FLASH_DATA_WRITE_OFFSET (0x4050)
+#define APOLLO_FLASH_RESET_OFFSET      (0x4060)
+
+#define APOLLO_FLASH_FIFO_STATUS_MASK   (0xF)
+#define APOLLO_FLASH_FIFO_STATUS_SHIFT          (0)
+#define APOLLO_FLASH_PROGRAM_STATUS_MASK (0xF)
+#define APOLLO_FLASH_PROGAM_STATUS_SHIFT (16)
+
+#define APOLLO_FLASH_PROG_COMPLETE_BIT (0x1)
+#define APOLLO_FLASH_PROG_PROGRESS_BIT (0x2)
+#define APOLLO_FLASH_PROG_FAILED_BIT   (0x4)
+#define APOLLO_FLASH_INV_FILETYPE_BIT  (0x8)
+
+#define APOLLO_FLASH_FIFO_SIZE         (8)
+
+/* RGX reg on base register 1 */
+#define SYS_RGX_REG_PCI_BASENUM                (1)
+#define SYS_RGX_REG_REGION_SIZE                (0x00004000)
+
+/* Device memory (including HP mapping) on base register 2 */
+#define SYS_DEV_MEM_PCI_BASENUM                (2)
+
+#endif /* if !defined(__APOLLO_REGS_H__) */
diff --git a/drivers/gpu/rogue_m/include/system/rgx_tc/pdp_regs.h b/drivers/gpu/rogue_m/include/system/rgx_tc/pdp_regs.h
new file mode 100644 (file)
index 0000000..bd26b06
--- /dev/null
@@ -0,0 +1,75 @@
+/*************************************************************************/ /*!
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__PDP_REGS_H__)
+#define __PDP_REGS_H__
+
+/*************************************************************************/ /*!
+ PCI Device Information
+*/ /**************************************************************************/
+
+#define DCPDP_VENDOR_ID_POWERVR                        (0x1010)
+
+#define DCPDP_DEVICE_ID_PCI_APOLLO_FPGA                (0x1CF1)
+#define DCPDP_DEVICE_ID_PCIE_APOLLO_FPGA       (0x1CF2)
+
+/*************************************************************************/ /*!
+ PCI Device Base Address Information
+*/ /**************************************************************************/
+
+/* PLL and PDP registers on base address register 0 */
+#define DCPDP_REG_PCI_BASENUM                  (0)
+
+#define DCPDP_PCI_PLL_REG_OFFSET               (0x1000)
+#define DCPDP_PCI_PLL_REG_SIZE                 (0x0400)
+
+#define DCPDP_PCI_PDP_REG_OFFSET               (0xC000)
+#define DCPDP_PCI_PDP_REG_SIZE                 (0x2000)
+
+/*************************************************************************/ /*!
+ Misc register information
+*/ /**************************************************************************/
+
+/* This information isn't captured in tcf_rgbpdp_regs.h so define it here */
+#define DCPDP_STR1SURF_FORMAT_ARGB8888         (0xE)
+#define DCPDP_STR1ADDRCTRL_BASE_ADDR_SHIFT     (4)
+#define DCPDP_STR1POSN_STRIDE_SHIFT            (4)
+
+#endif /* !defined(__PDP_REGS_H__) */
diff --git a/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_clk_ctrl.h b/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_clk_ctrl.h
new file mode 100644 (file)
index 0000000..a42d23e
--- /dev/null
@@ -0,0 +1,808 @@
+/*************************************************************************/ /*!
+@Title          Test Chip Framework system control register definitions        
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Autogenerated C -- do not edit
+                Generated from: tcf_clk_ctrl.def
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_CLK_CTRL_H_)
+#define _TCF_CLK_CTRL_H_
+
+/*
+       Register FPGA_ID_REG
+*/
+#define TCF_CLK_CTRL_FPGA_ID_REG            0x0000
+#define FPGA_ID_REG_CORE_CFG_MASK           0x0000FFFFU
+#define FPGA_ID_REG_CORE_CFG_SHIFT          0
+#define FPGA_ID_REG_CORE_CFG_SIGNED         0
+
+#define FPGA_ID_REG_CORE_ID_MASK            0xFFFF0000U
+#define FPGA_ID_REG_CORE_ID_SHIFT           16
+#define FPGA_ID_REG_CORE_ID_SIGNED          0
+
+/*
+       Register FPGA_REV_REG
+*/
+#define TCF_CLK_CTRL_FPGA_REV_REG           0x0008
+#define FPGA_REV_REG_MAINT_MASK             0x000000FFU
+#define FPGA_REV_REG_MAINT_SHIFT            0
+#define FPGA_REV_REG_MAINT_SIGNED           0
+
+#define FPGA_REV_REG_MINOR_MASK             0x0000FF00U
+#define FPGA_REV_REG_MINOR_SHIFT            8
+#define FPGA_REV_REG_MINOR_SIGNED           0
+
+#define FPGA_REV_REG_MAJOR_MASK             0x00FF0000U
+#define FPGA_REV_REG_MAJOR_SHIFT            16
+#define FPGA_REV_REG_MAJOR_SIGNED           0
+
+#define FPGA_REV_REG_DESIGNER_MASK          0xFF000000U
+#define FPGA_REV_REG_DESIGNER_SHIFT         24
+#define FPGA_REV_REG_DESIGNER_SIGNED        0
+
+/*
+       Register FPGA_DES_REV_1
+*/
+#define TCF_CLK_CTRL_FPGA_DES_REV_1         0x0010
+#define FPGA_DES_REV_1_MASK                 0xFFFFFFFFU
+#define FPGA_DES_REV_1_SHIFT                0
+#define FPGA_DES_REV_1_SIGNED               0
+
+/*
+       Register FPGA_DES_REV_2
+*/
+#define TCF_CLK_CTRL_FPGA_DES_REV_2         0x0018
+#define FPGA_DES_REV_2_MASK                 0xFFFFFFFFU
+#define FPGA_DES_REV_2_SHIFT                0
+#define FPGA_DES_REV_2_SIGNED               0
+
+/*
+       Register TCF_CORE_ID_REG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_ID_REG        0x0020
+#define TCF_CORE_ID_REG_CORE_CFG_MASK       0x0000FFFFU
+#define TCF_CORE_ID_REG_CORE_CFG_SHIFT      0
+#define TCF_CORE_ID_REG_CORE_CFG_SIGNED     0
+
+#define TCF_CORE_ID_REG_CORE_ID_MASK        0xFFFF0000U
+#define TCF_CORE_ID_REG_CORE_ID_SHIFT       16
+#define TCF_CORE_ID_REG_CORE_ID_SIGNED      0
+
+/*
+       Register TCF_CORE_REV_REG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_REV_REG       0x0028
+#define TCF_CORE_REV_REG_MAINT_MASK         0x000000FFU
+#define TCF_CORE_REV_REG_MAINT_SHIFT        0
+#define TCF_CORE_REV_REG_MAINT_SIGNED       0
+
+#define TCF_CORE_REV_REG_MINOR_MASK         0x0000FF00U
+#define TCF_CORE_REV_REG_MINOR_SHIFT        8
+#define TCF_CORE_REV_REG_MINOR_SIGNED       0
+
+#define TCF_CORE_REV_REG_MAJOR_MASK         0x00FF0000U
+#define TCF_CORE_REV_REG_MAJOR_SHIFT        16
+#define TCF_CORE_REV_REG_MAJOR_SIGNED       0
+
+#define TCF_CORE_REV_REG_DESIGNER_MASK      0xFF000000U
+#define TCF_CORE_REV_REG_DESIGNER_SHIFT     24
+#define TCF_CORE_REV_REG_DESIGNER_SIGNED    0
+
+/*
+       Register TCF_CORE_DES_REV_1
+*/
+#define TCF_CLK_CTRL_TCF_CORE_DES_REV_1     0x0030
+#define TCF_CORE_DES_REV_1_MASK             0xFFFFFFFFU
+#define TCF_CORE_DES_REV_1_SHIFT            0
+#define TCF_CORE_DES_REV_1_SIGNED           0
+
+/*
+       Register TCF_CORE_DES_REV_2
+*/
+#define TCF_CLK_CTRL_TCF_CORE_DES_REV_2     0x0038
+#define TCF_CORE_DES_REV_2_MASK             0xFFFFFFFFU
+#define TCF_CORE_DES_REV_2_SHIFT            0
+#define TCF_CORE_DES_REV_2_SIGNED           0
+
+/*
+       Register SCB_GENERAL_CONTROL
+*/
+#define TCF_CLK_CTRL_SCB_GENERAL_CONTROL    0x0040
+#define SCB_GC_TRANS_HALT_MASK              0x00000200U
+#define SCB_GC_TRANS_HALT_SHIFT             9
+#define SCB_GC_TRANS_HALT_SIGNED            0
+
+#define SCB_GC_CKD_REGS_MASK                0x00000100U
+#define SCB_GC_CKD_REGS_SHIFT               8
+#define SCB_GC_CKD_REGS_SIGNED              0
+
+#define SCB_GC_CKD_SLAVE_MASK               0x00000080U
+#define SCB_GC_CKD_SLAVE_SHIFT              7
+#define SCB_GC_CKD_SLAVE_SIGNED             0
+
+#define SCB_GC_CKD_MASTER_MASK              0x00000040U
+#define SCB_GC_CKD_MASTER_SHIFT             6
+#define SCB_GC_CKD_MASTER_SIGNED            0
+
+#define SCB_GC_CKD_XDATA_MASK               0x00000020U
+#define SCB_GC_CKD_XDATA_SHIFT              5
+#define SCB_GC_CKD_XDATA_SIGNED             0
+
+#define SCB_GC_SFR_REG_MASK                 0x00000010U
+#define SCB_GC_SFR_REG_SHIFT                4
+#define SCB_GC_SFR_REG_SIGNED               0
+
+#define SCB_GC_SFR_SLAVE_MASK               0x00000008U
+#define SCB_GC_SFR_SLAVE_SHIFT              3
+#define SCB_GC_SFR_SLAVE_SIGNED             0
+
+#define SCB_GC_SFR_MASTER_MASK              0x00000004U
+#define SCB_GC_SFR_MASTER_SHIFT             2
+#define SCB_GC_SFR_MASTER_SIGNED            0
+
+#define SCB_GC_SFR_DET_DATA_MASK            0x00000002U
+#define SCB_GC_SFR_DET_DATA_SHIFT           1
+#define SCB_GC_SFR_DET_DATA_SIGNED          0
+
+#define SCB_GC_SFR_GEN_DATA_MASK            0x00000001U
+#define SCB_GC_SFR_GEN_DATA_SHIFT           0
+#define SCB_GC_SFR_GEN_DATA_SIGNED          0
+
+/*
+       Register SCB_MASTER_READ_COUNT
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_READ_COUNT  0x0048
+#define MASTER_READ_COUNT_MASK              0x0000FFFFU
+#define MASTER_READ_COUNT_SHIFT             0
+#define MASTER_READ_COUNT_SIGNED            0
+
+/*
+       Register SCB_MASTER_READ_DATA
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_READ_DATA   0x0050
+#define MASTER_READ_DATA_MASK               0x000000FFU
+#define MASTER_READ_DATA_SHIFT              0
+#define MASTER_READ_DATA_SIGNED             0
+
+/*
+       Register SCB_MASTER_ADDRESS
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_ADDRESS     0x0058
+#define SCB_MASTER_ADDRESS_MASK             0x000003FFU
+#define SCB_MASTER_ADDRESS_SHIFT            0
+#define SCB_MASTER_ADDRESS_SIGNED           0
+
+/*
+       Register SCB_MASTER_WRITE_DATA
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_WRITE_DATA  0x0060
+#define MASTER_WRITE_DATA_MASK              0x000000FFU
+#define MASTER_WRITE_DATA_SHIFT             0
+#define MASTER_WRITE_DATA_SIGNED            0
+
+/*
+       Register SCB_MASTER_WRITE_COUNT
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_WRITE_COUNT 0x0068
+#define MASTER_WRITE_COUNT_MASK             0x0000FFFFU
+#define MASTER_WRITE_COUNT_SHIFT            0
+#define MASTER_WRITE_COUNT_SIGNED           0
+
+/*
+       Register SCB_BUS_SELECT
+*/
+#define TCF_CLK_CTRL_SCB_BUS_SELECT         0x0070
+#define BUS_SELECT_MASK                     0x00000003U
+#define BUS_SELECT_SHIFT                    0
+#define BUS_SELECT_SIGNED                   0
+
+/*
+       Register SCB_MASTER_FILL_STATUS
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_FILL_STATUS 0x0078
+#define MASTER_WRITE_FIFO_EMPTY_MASK        0x00000008U
+#define MASTER_WRITE_FIFO_EMPTY_SHIFT       3
+#define MASTER_WRITE_FIFO_EMPTY_SIGNED      0
+
+#define MASTER_WRITE_FIFO_FULL_MASK         0x00000004U
+#define MASTER_WRITE_FIFO_FULL_SHIFT        2
+#define MASTER_WRITE_FIFO_FULL_SIGNED       0
+
+#define MASTER_READ_FIFO_EMPTY_MASK         0x00000002U
+#define MASTER_READ_FIFO_EMPTY_SHIFT        1
+#define MASTER_READ_FIFO_EMPTY_SIGNED       0
+
+#define MASTER_READ_FIFO_FULL_MASK          0x00000001U
+#define MASTER_READ_FIFO_FULL_SHIFT         0
+#define MASTER_READ_FIFO_FULL_SIGNED        0
+
+/*
+       Register CLK_AND_RST_CTRL
+*/
+#define TCF_CLK_CTRL_CLK_AND_RST_CTRL       0x0080
+#define GLB_CLKG_EN_MASK                    0x00020000U
+#define GLB_CLKG_EN_SHIFT                   17
+#define GLB_CLKG_EN_SIGNED                  0
+
+#define CLK_GATE_CNTL_MASK                  0x00010000U
+#define CLK_GATE_CNTL_SHIFT                 16
+#define CLK_GATE_CNTL_SIGNED                0
+
+#define DUT_DCM_RESETN_MASK                 0x00000400U
+#define DUT_DCM_RESETN_SHIFT                10
+#define DUT_DCM_RESETN_SIGNED               0
+
+#define MEM_RESYNC_BYPASS_MASK              0x00000200U
+#define MEM_RESYNC_BYPASS_SHIFT             9
+#define MEM_RESYNC_BYPASS_SIGNED            0
+
+#define SYS_RESYNC_BYPASS_MASK              0x00000100U
+#define SYS_RESYNC_BYPASS_SHIFT             8
+#define SYS_RESYNC_BYPASS_SIGNED            0
+
+#define SCB_RESETN_MASK                     0x00000010U
+#define SCB_RESETN_SHIFT                    4
+#define SCB_RESETN_SIGNED                   0
+
+#define PDP2_RESETN_MASK                    0x00000008U
+#define PDP2_RESETN_SHIFT                   3
+#define PDP2_RESETN_SIGNED                  0
+
+#define PDP1_RESETN_MASK                    0x00000004U
+#define PDP1_RESETN_SHIFT                   2
+#define PDP1_RESETN_SIGNED                  0
+
+#define DDR_RESETN_MASK                     0x00000002U
+#define DDR_RESETN_SHIFT                    1
+#define DDR_RESETN_SIGNED                   0
+
+#define DUT_RESETN_MASK                     0x00000001U
+#define DUT_RESETN_SHIFT                    0
+#define DUT_RESETN_SIGNED                   0
+
+/*
+       Register TEST_REG_OUT
+*/
+#define TCF_CLK_CTRL_TEST_REG_OUT           0x0088
+#define TEST_REG_OUT_MASK                   0xFFFFFFFFU
+#define TEST_REG_OUT_SHIFT                  0
+#define TEST_REG_OUT_SIGNED                 0
+
+/*
+       Register TEST_REG_IN
+*/
+#define TCF_CLK_CTRL_TEST_REG_IN            0x0090
+#define TEST_REG_IN_MASK                    0xFFFFFFFFU
+#define TEST_REG_IN_SHIFT                   0
+#define TEST_REG_IN_SIGNED                  0
+
+/*
+       Register TEST_CTRL
+*/
+#define TCF_CLK_CTRL_TEST_CTRL              0x0098
+#define PCI_TEST_OFFSET_MASK                0xF8000000U
+#define PCI_TEST_OFFSET_SHIFT               27
+#define PCI_TEST_OFFSET_SIGNED              0
+
+#define HOST_PHY_MODE_MASK                  0x00000100U
+#define HOST_PHY_MODE_SHIFT                 8
+#define HOST_PHY_MODE_SIGNED                0
+
+#define HOST_ONLY_MODE_MASK                 0x00000080U
+#define HOST_ONLY_MODE_SHIFT                7
+#define HOST_ONLY_MODE_SIGNED               0
+
+#define PCI_TEST_MODE_MASK                  0x00000040U
+#define PCI_TEST_MODE_SHIFT                 6
+#define PCI_TEST_MODE_SIGNED                0
+
+#define TURN_OFF_DDR_MASK                   0x00000020U
+#define TURN_OFF_DDR_SHIFT                  5
+#define TURN_OFF_DDR_SIGNED                 0
+
+#define SYS_RD_CLK_INV_MASK                 0x00000010U
+#define SYS_RD_CLK_INV_SHIFT                4
+#define SYS_RD_CLK_INV_SIGNED               0
+
+#define MEM_REQ_CLK_INV_MASK                0x00000008U
+#define MEM_REQ_CLK_INV_SHIFT               3
+#define MEM_REQ_CLK_INV_SIGNED              0
+
+#define BURST_SPLIT_MASK                    0x00000004U
+#define BURST_SPLIT_SHIFT                   2
+#define BURST_SPLIT_SIGNED                  0
+
+#define CLK_INVERSION_MASK                  0x00000002U
+#define CLK_INVERSION_SHIFT                 1
+#define CLK_INVERSION_SIGNED                0
+
+#define ADDRESS_FORCE_MASK                  0x00000001U
+#define ADDRESS_FORCE_SHIFT                 0
+#define ADDRESS_FORCE_SIGNED                0
+
+/*
+       Register CLEAR_HOST_MEM_SIG
+*/
+#define TCF_CLK_CTRL_CLEAR_HOST_MEM_SIG     0x00A0
+#define SIGNATURE_TAG_ID_MASK               0x00000F00U
+#define SIGNATURE_TAG_ID_SHIFT              8
+#define SIGNATURE_TAG_ID_SIGNED             0
+
+#define CLEAR_HOST_MEM_SIGNATURE_MASK       0x00000001U
+#define CLEAR_HOST_MEM_SIGNATURE_SHIFT      0
+#define CLEAR_HOST_MEM_SIGNATURE_SIGNED     0
+
+/*
+       Register HOST_MEM_SIGNATURE
+*/
+#define TCF_CLK_CTRL_HOST_MEM_SIGNATURE     0x00A8
+#define HOST_MEM_SIGNATURE_MASK             0xFFFFFFFFU
+#define HOST_MEM_SIGNATURE_SHIFT            0
+#define HOST_MEM_SIGNATURE_SIGNED           0
+
+/*
+       Register INTERRUPT_STATUS
+*/
+#define TCF_CLK_CTRL_INTERRUPT_STATUS       0x00C8
+#define INTERRUPT_MASTER_STATUS_MASK        0x80000000U
+#define INTERRUPT_MASTER_STATUS_SHIFT       31
+#define INTERRUPT_MASTER_STATUS_SIGNED      0
+
+#define OTHER_INTS_MASK                     0x7FFE0000U
+#define OTHER_INTS_SHIFT                    17
+#define OTHER_INTS_SIGNED                   0
+
+#define HOST_MST_NORESPONSE_MASK            0x00010000U
+#define HOST_MST_NORESPONSE_SHIFT           16
+#define HOST_MST_NORESPONSE_SIGNED          0
+
+#define PDP2_INT_MASK                       0x00008000U
+#define PDP2_INT_SHIFT                      15
+#define PDP2_INT_SIGNED                     0
+
+#define PDP1_INT_MASK                       0x00004000U
+#define PDP1_INT_SHIFT                      14
+#define PDP1_INT_SIGNED                     0
+
+#define EXT_INT_MASK                        0x00002000U
+#define EXT_INT_SHIFT                       13
+#define EXT_INT_SIGNED                      0
+
+#define SCB_MST_HLT_BIT_MASK                0x00001000U
+#define SCB_MST_HLT_BIT_SHIFT               12
+#define SCB_MST_HLT_BIT_SIGNED              0
+
+#define SCB_SLV_EVENT_MASK                  0x00000800U
+#define SCB_SLV_EVENT_SHIFT                 11
+#define SCB_SLV_EVENT_SIGNED                0
+
+#define SCB_TDONE_RX_MASK                   0x00000400U
+#define SCB_TDONE_RX_SHIFT                  10
+#define SCB_TDONE_RX_SIGNED                 0
+
+#define SCB_SLV_WT_RD_DAT_MASK              0x00000200U
+#define SCB_SLV_WT_RD_DAT_SHIFT             9
+#define SCB_SLV_WT_RD_DAT_SIGNED            0
+
+#define SCB_SLV_WT_PRV_RD_MASK              0x00000100U
+#define SCB_SLV_WT_PRV_RD_SHIFT             8
+#define SCB_SLV_WT_PRV_RD_SIGNED            0
+
+#define SCB_SLV_WT_WR_DAT_MASK              0x00000080U
+#define SCB_SLV_WT_WR_DAT_SHIFT             7
+#define SCB_SLV_WT_WR_DAT_SIGNED            0
+
+#define SCB_MST_WT_RD_DAT_MASK              0x00000040U
+#define SCB_MST_WT_RD_DAT_SHIFT             6
+#define SCB_MST_WT_RD_DAT_SIGNED            0
+
+#define SCB_ADD_ACK_ERR_MASK                0x00000020U
+#define SCB_ADD_ACK_ERR_SHIFT               5
+#define SCB_ADD_ACK_ERR_SIGNED              0
+
+#define SCB_WR_ACK_ERR_MASK                 0x00000010U
+#define SCB_WR_ACK_ERR_SHIFT                4
+#define SCB_WR_ACK_ERR_SIGNED               0
+
+#define SCB_SDAT_LO_TIM_MASK                0x00000008U
+#define SCB_SDAT_LO_TIM_SHIFT               3
+#define SCB_SDAT_LO_TIM_SIGNED              0
+
+#define SCB_SCLK_LO_TIM_MASK                0x00000004U
+#define SCB_SCLK_LO_TIM_SHIFT               2
+#define SCB_SCLK_LO_TIM_SIGNED              0
+
+#define SCB_UNEX_START_BIT_MASK             0x00000002U
+#define SCB_UNEX_START_BIT_SHIFT            1
+#define SCB_UNEX_START_BIT_SIGNED           0
+
+#define SCB_BUS_INACTIVE_MASK               0x00000001U
+#define SCB_BUS_INACTIVE_SHIFT              0
+#define SCB_BUS_INACTIVE_SIGNED             0
+
+/*
+       Register INTERRUPT_OP_CFG
+*/
+#define TCF_CLK_CTRL_INTERRUPT_OP_CFG       0x00D0
+#define PULSE_NLEVEL_MASK                   0x80000000U
+#define PULSE_NLEVEL_SHIFT                  31
+#define PULSE_NLEVEL_SIGNED                 0
+
+#define INT_SENSE_MASK                      0x40000000U
+#define INT_SENSE_SHIFT                     30
+#define INT_SENSE_SIGNED                    0
+
+#define INTERRUPT_DEST_MASK                 0x0000000FU
+#define INTERRUPT_DEST_SHIFT                0
+#define INTERRUPT_DEST_SIGNED               0
+
+/*
+       Register INTERRUPT_ENABLE
+*/
+#define TCF_CLK_CTRL_INTERRUPT_ENABLE       0x00D8
+#define INTERRUPT_MASTER_ENABLE_MASK        0x80000000U
+#define INTERRUPT_MASTER_ENABLE_SHIFT       31
+#define INTERRUPT_MASTER_ENABLE_SIGNED      0
+
+#define INTERRUPT_ENABLE_MASK               0x7FFFFFFFU
+#define INTERRUPT_ENABLE_SHIFT              0
+#define INTERRUPT_ENABLE_SIGNED             0
+
+/*
+       Register INTERRUPT_CLEAR
+*/
+#define TCF_CLK_CTRL_INTERRUPT_CLEAR        0x00E0
+#define INTERRUPT_MASTER_CLEAR_MASK         0x80000000U
+#define INTERRUPT_MASTER_CLEAR_SHIFT        31
+#define INTERRUPT_MASTER_CLEAR_SIGNED       0
+
+#define INTERRUPT_CLEAR_MASK                0x7FFFFFFFU
+#define INTERRUPT_CLEAR_SHIFT               0
+#define INTERRUPT_CLEAR_SIGNED              0
+
+/*
+       Register YCC_RGB_CTRL
+*/
+#define TCF_CLK_CTRL_YCC_RGB_CTRL           0x00E8
+#define RGB_CTRL1_MASK                      0x000001FFU
+#define RGB_CTRL1_SHIFT                     0
+#define RGB_CTRL1_SIGNED                    0
+
+#define RGB_CTRL2_MASK                      0x01FF0000U
+#define RGB_CTRL2_SHIFT                     16
+#define RGB_CTRL2_SIGNED                    0
+
+/*
+       Register EXP_BRD_CTRL
+*/
+#define TCF_CLK_CTRL_EXP_BRD_CTRL           0x00F8
+#define PDP1_DATA_EN_MASK                   0x00000003U
+#define PDP1_DATA_EN_SHIFT                  0
+#define PDP1_DATA_EN_SIGNED                 0
+
+#define PDP2_DATA_EN_MASK                   0x00000030U
+#define PDP2_DATA_EN_SHIFT                  4
+#define PDP2_DATA_EN_SIGNED                 0
+
+#define EXP_BRD_OUTPUT_MASK                 0xFFFFFF00U
+#define EXP_BRD_OUTPUT_SHIFT                8
+#define EXP_BRD_OUTPUT_SIGNED               0
+
+/*
+       Register HOSTIF_CONTROL
+*/
+#define TCF_CLK_CTRL_HOSTIF_CONTROL         0x0100
+#define HOSTIF_CTRL_MASK                    0x000000FFU
+#define HOSTIF_CTRL_SHIFT                   0
+#define HOSTIF_CTRL_SIGNED                  0
+
+/*
+       Register DUT_CONTROL_1
+*/
+#define TCF_CLK_CTRL_DUT_CONTROL_1          0x0108
+#define DUT_CTRL_1_MASK                     0xFFFFFFFFU
+#define DUT_CTRL_1_SHIFT                    0
+#define DUT_CTRL_1_SIGNED                   0
+
+/* TC ES2 additional needs those: */
+#define DUT_CTRL_TEST_MODE_SHIFT            0
+#define DUT_CTRL_TEST_MODE_MASK             0x3
+
+#define DUT_CTRL_VCC_0V9EN                  (1<<12)
+#define DUT_CTRL_VCC_1V8EN                  (1<<13)
+#define DUT_CTRL_VCC_IO_INH                 (1<<14)
+#define DUT_CTRL_VCC_CORE_INH               (1<<15)
+
+/*
+       Register DUT_STATUS_1
+*/
+#define TCF_CLK_CTRL_DUT_STATUS_1           0x0110
+#define DUT_STATUS_1_MASK                   0xFFFFFFFFU
+#define DUT_STATUS_1_SHIFT                  0
+#define DUT_STATUS_1_SIGNED                 0
+
+/*
+       Register DUT_CTRL_NOT_STAT_1
+*/
+#define TCF_CLK_CTRL_DUT_CTRL_NOT_STAT_1    0x0118
+#define DUT_STAT_NOT_CTRL_1_MASK            0xFFFFFFFFU
+#define DUT_STAT_NOT_CTRL_1_SHIFT           0
+#define DUT_STAT_NOT_CTRL_1_SIGNED          0
+
+/*
+       Register DUT_CONTROL_2
+*/
+#define TCF_CLK_CTRL_DUT_CONTROL_2          0x0120
+#define DUT_CTRL_2_MASK                     0xFFFFFFFFU
+#define DUT_CTRL_2_SHIFT                    0
+#define DUT_CTRL_2_SIGNED                   0
+
+/*
+       Register DUT_STATUS_2
+*/
+#define TCF_CLK_CTRL_DUT_STATUS_2           0x0128
+#define DUT_STATUS_2_MASK                   0xFFFFFFFFU
+#define DUT_STATUS_2_SHIFT                  0
+#define DUT_STATUS_2_SIGNED                 0
+
+/*
+       Register DUT_CTRL_NOT_STAT_2
+*/
+#define TCF_CLK_CTRL_DUT_CTRL_NOT_STAT_2    0x0130
+#define DUT_CTRL_NOT_STAT_2_MASK            0xFFFFFFFFU
+#define DUT_CTRL_NOT_STAT_2_SHIFT           0
+#define DUT_CTRL_NOT_STAT_2_SIGNED          0
+
+/*
+       Register BUS_CAP_BASE_ADDR
+*/
+#define TCF_CLK_CTRL_BUS_CAP_BASE_ADDR      0x0138
+#define BUS_CAP_BASE_ADDR_MASK              0xFFFFFFFFU
+#define BUS_CAP_BASE_ADDR_SHIFT             0
+#define BUS_CAP_BASE_ADDR_SIGNED            0
+
+/*
+       Register BUS_CAP_ENABLE
+*/
+#define TCF_CLK_CTRL_BUS_CAP_ENABLE         0x0140
+#define BUS_CAP_ENABLE_MASK                 0x00000001U
+#define BUS_CAP_ENABLE_SHIFT                0
+#define BUS_CAP_ENABLE_SIGNED               0
+
+/*
+       Register BUS_CAP_COUNT
+*/
+#define TCF_CLK_CTRL_BUS_CAP_COUNT          0x0148
+#define BUS_CAP_COUNT_MASK                  0xFFFFFFFFU
+#define BUS_CAP_COUNT_SHIFT                 0
+#define BUS_CAP_COUNT_SIGNED                0
+
+/*
+       Register DCM_LOCK_STATUS
+*/
+#define TCF_CLK_CTRL_DCM_LOCK_STATUS        0x0150
+#define DCM_LOCK_STATUS_MASK                0x00000007U
+#define DCM_LOCK_STATUS_SHIFT               0
+#define DCM_LOCK_STATUS_SIGNED              0
+
+/*
+       Register AUX_DUT_RESETNS
+*/
+#define TCF_CLK_CTRL_AUX_DUT_RESETNS        0x0158
+#define AUX_DUT_RESETNS_MASK                0x0000000FU
+#define AUX_DUT_RESETNS_SHIFT               0
+#define AUX_DUT_RESETNS_SIGNED              0
+
+/*
+       Register TCF_SPI_MST_ADDR_RDNWR
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_ADDR_RDNWR 0x0160
+#define TCF_SPI_MST_ADDR_MASK               0x00000FFFU
+#define TCF_SPI_MST_ADDR_SHIFT              0
+#define TCF_SPI_MST_ADDR_SIGNED             0
+
+#define TCF_SPI_MST_RDNWR_MASK              0x00001000U
+#define TCF_SPI_MST_RDNWR_SHIFT             12
+#define TCF_SPI_MST_RDNWR_SIGNED            0
+
+#define TCF_SPI_MST_SLAVE_ID_MASK           0x00010000U
+#define TCF_SPI_MST_SLAVE_ID_SHIFT          16
+#define TCF_SPI_MST_SLAVE_ID_SIGNED         0
+
+/*
+       Register TCF_SPI_MST_WDATA
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_WDATA      0x0168
+#define TCF_SPI_MST_WDATA_MASK              0xFFFFFFFFU
+#define TCF_SPI_MST_WDATA_SHIFT             0
+#define TCF_SPI_MST_WDATA_SIGNED            0
+
+/*
+       Register TCF_SPI_MST_RDATA
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_RDATA      0x0170
+#define TCF_SPI_MST_RDATA_MASK              0xFFFFFFFFU
+#define TCF_SPI_MST_RDATA_SHIFT             0
+#define TCF_SPI_MST_RDATA_SIGNED            0
+
+/*
+       Register TCF_SPI_MST_STATUS
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_STATUS     0x0178
+#define TCF_SPI_MST_STATUS_MASK             0x0000000FU
+#define TCF_SPI_MST_STATUS_SHIFT            0
+#define TCF_SPI_MST_STATUS_SIGNED           0
+
+/*
+       Register TCF_SPI_MST_GO
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_GO         0x0180
+#define TCF_SPI_MST_GO_MASK                 0x00000001U
+#define TCF_SPI_MST_GO_SHIFT                0
+#define TCF_SPI_MST_GO_SIGNED               0
+
+/*
+       Register EXT_SIG_CTRL
+*/
+#define TCF_CLK_CTRL_EXT_SIG_CTRL           0x0188
+#define EXT_SYS_REQ_SIG_START_MASK          0x00000001U
+#define EXT_SYS_REQ_SIG_START_SHIFT         0
+#define EXT_SYS_REQ_SIG_START_SIGNED        0
+
+#define EXT_SYS_RD_SIG_START_MASK           0x00000002U
+#define EXT_SYS_RD_SIG_START_SHIFT          1
+#define EXT_SYS_RD_SIG_START_SIGNED         0
+
+#define EXT_MEM_REQ_SIG_START_MASK          0x00000004U
+#define EXT_MEM_REQ_SIG_START_SHIFT         2
+#define EXT_MEM_REQ_SIG_START_SIGNED        0
+
+#define EXT_MEM_RD_SIG_START_MASK           0x00000008U
+#define EXT_MEM_RD_SIG_START_SHIFT          3
+#define EXT_MEM_RD_SIG_START_SIGNED         0
+
+/*
+       Register EXT_SYS_REQ_SIG
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_SIG        0x0190
+#define EXT_SYS_REQ_SIG_MASK                0xFFFFFFFFU
+#define EXT_SYS_REQ_SIG_SHIFT               0
+#define EXT_SYS_REQ_SIG_SIGNED              0
+
+/*
+       Register EXT_SYS_RD_SIG
+*/
+#define TCF_CLK_CTRL_EXT_SYS_RD_SIG         0x0198
+#define EXT_SYS_RD_SIG_MASK                 0xFFFFFFFFU
+#define EXT_SYS_RD_SIG_SHIFT                0
+#define EXT_SYS_RD_SIG_SIGNED               0
+
+/*
+       Register EXT_MEM_REQ_SIG
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_SIG        0x01A0
+#define EXT_MEM_REQ_SIG_MASK                0xFFFFFFFFU
+#define EXT_MEM_REQ_SIG_SHIFT               0
+#define EXT_MEM_REQ_SIG_SIGNED              0
+
+/*
+       Register EXT_MEM_RD_SIG
+*/
+#define TCF_CLK_CTRL_EXT_MEM_RD_SIG         0x01A8
+#define EXT_MEM_RD_SIG_MASK                 0xFFFFFFFFU
+#define EXT_MEM_RD_SIG_SHIFT                0
+#define EXT_MEM_RD_SIG_SIGNED               0
+
+/*
+       Register EXT_SYS_REQ_WR_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_WR_CNT     0x01B0
+#define EXT_SYS_REQ_WR_CNT_MASK             0xFFFFFFFFU
+#define EXT_SYS_REQ_WR_CNT_SHIFT            0
+#define EXT_SYS_REQ_WR_CNT_SIGNED           0
+
+/*
+       Register EXT_SYS_REQ_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_RD_CNT     0x01B8
+#define EXT_SYS_REQ_RD_CNT_MASK             0xFFFFFFFFU
+#define EXT_SYS_REQ_RD_CNT_SHIFT            0
+#define EXT_SYS_REQ_RD_CNT_SIGNED           0
+
+/*
+       Register EXT_SYS_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_RD_CNT         0x01C0
+#define EXT_SYS_RD_CNT_MASK                 0xFFFFFFFFU
+#define EXT_SYS_RD_CNT_SHIFT                0
+#define EXT_SYS_RD_CNT_SIGNED               0
+
+/*
+       Register EXT_MEM_REQ_WR_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_WR_CNT     0x01C8
+#define EXT_MEM_REQ_WR_CNT_MASK             0xFFFFFFFFU
+#define EXT_MEM_REQ_WR_CNT_SHIFT            0
+#define EXT_MEM_REQ_WR_CNT_SIGNED           0
+
+/*
+       Register EXT_MEM_REQ_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_RD_CNT     0x01D0
+#define EXT_MEM_REQ_RD_CNT_MASK             0xFFFFFFFFU
+#define EXT_MEM_REQ_RD_CNT_SHIFT            0
+#define EXT_MEM_REQ_RD_CNT_SIGNED           0
+
+/*
+       Register EXT_MEM_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_RD_CNT         0x01D8
+#define EXT_MEM_RD_CNT_MASK                 0xFFFFFFFFU
+#define EXT_MEM_RD_CNT_SHIFT                0
+#define EXT_MEM_RD_CNT_SIGNED               0
+
+/*
+       Register TCF_CORE_TARGET_BUILD_CFG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_TARGET_BUILD_CFG 0x01E0
+#define TCF_CORE_TARGET_BUILD_ID_MASK       0x000000FFU
+#define TCF_CORE_TARGET_BUILD_ID_SHIFT      0
+#define TCF_CORE_TARGET_BUILD_ID_SIGNED     0
+
+/*
+       Register MEM_THROUGH_SYS
+*/
+#define TCF_CLK_CTRL_MEM_THROUGH_SYS        0x01E8
+#define MEM_THROUGH_SYS_MASK                0x00000001U
+#define MEM_THROUGH_SYS_SHIFT               0
+#define MEM_THROUGH_SYS_SIGNED              0
+
+/*
+       Register HOST_PHY_OFFSET
+*/
+#define TCF_CLK_CTRL_HOST_PHY_OFFSET        0x01F0
+#define HOST_PHY_OFFSET_MASK                0xFFFFFFFFU
+#define HOST_PHY_OFFSET_SHIFT               0
+#define HOST_PHY_OFFSET_SIGNED              0
+
+#endif /* !defined(_TCF_CLK_CTRL_H_) */
+
+/*****************************************************************************
+ End of file (tcf_clk_ctrl.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_pll.h b/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_pll.h
new file mode 100644 (file)
index 0000000..fa0f823
--- /dev/null
@@ -0,0 +1,311 @@
+/*************************************************************************/ /*!
+@Title          Test Chip Framework PDP register definitions   
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Autogenerated C -- do not edit
+                Generated from tcf_pll.def
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_PLL_H_)
+#define _TCF_PLL_H_
+
+/*
+       Register PLL_DDR2_CLK0
+*/
+#define TCF_PLL_PLL_DDR2_CLK0               0x0000
+#define DDR2_PLL_CLK0_PHS_MASK              0x00300000U
+#define DDR2_PLL_CLK0_PHS_SHIFT             20
+#define DDR2_PLL_CLK0_PHS_SIGNED            0
+
+#define DDR2_PLL_CLK0_MS_MASK               0x00030000U
+#define DDR2_PLL_CLK0_MS_SHIFT              16
+#define DDR2_PLL_CLK0_MS_SIGNED             0
+
+#define DDR2_PLL_CLK0_FREQ_MASK             0x000001FFU
+#define DDR2_PLL_CLK0_FREQ_SHIFT            0
+#define DDR2_PLL_CLK0_FREQ_SIGNED           0
+
+/*
+       Register PLL_DDR2_CLK1TO5
+*/
+#define TCF_PLL_PLL_DDR2_CLK1TO5            0x0008
+#define DDR2_PLL_CLK1TO5_PHS_MASK           0x3FF00000U
+#define DDR2_PLL_CLK1TO5_PHS_SHIFT          20
+#define DDR2_PLL_CLK1TO5_PHS_SIGNED         0
+
+#define DDR2_PLL_CLK1TO5_MS_MASK            0x000FFC00U
+#define DDR2_PLL_CLK1TO5_MS_SHIFT           10
+#define DDR2_PLL_CLK1TO5_MS_SIGNED          0
+
+#define DDR2_PLL_CLK1TO5_FREQ_MASK          0x000003FFU
+#define DDR2_PLL_CLK1TO5_FREQ_SHIFT         0
+#define DDR2_PLL_CLK1TO5_FREQ_SIGNED        0
+
+/*
+       Register PLL_DDR2_DRP_GO
+*/
+#define TCF_PLL_PLL_DDR2_DRP_GO             0x0010
+#define PLL_DDR2_DRP_GO_MASK                0x00000001U
+#define PLL_DDR2_DRP_GO_SHIFT               0
+#define PLL_DDR2_DRP_GO_SIGNED              0
+
+/*
+       Register PLL_PDP_CLK0
+*/
+#define TCF_PLL_PLL_PDP_CLK0                0x0018
+#define PDP_PLL_CLK0_PHS_MASK               0x00300000U
+#define PDP_PLL_CLK0_PHS_SHIFT              20
+#define PDP_PLL_CLK0_PHS_SIGNED             0
+
+#define PDP_PLL_CLK0_MS_MASK                0x00030000U
+#define PDP_PLL_CLK0_MS_SHIFT               16
+#define PDP_PLL_CLK0_MS_SIGNED              0
+
+#define PDP_PLL_CLK0_FREQ_MASK              0x000001FFU
+#define PDP_PLL_CLK0_FREQ_SHIFT             0
+#define PDP_PLL_CLK0_FREQ_SIGNED            0
+
+/*
+       Register PLL_PDP_CLK1TO5
+*/
+#define TCF_PLL_PLL_PDP_CLK1TO5             0x0020
+#define PDP_PLL_CLK1TO5_PHS_MASK            0x3FF00000U
+#define PDP_PLL_CLK1TO5_PHS_SHIFT           20
+#define PDP_PLL_CLK1TO5_PHS_SIGNED          0
+
+#define PDP_PLL_CLK1TO5_MS_MASK             0x000FFC00U
+#define PDP_PLL_CLK1TO5_MS_SHIFT            10
+#define PDP_PLL_CLK1TO5_MS_SIGNED           0
+
+#define PDP_PLL_CLK1TO5_FREQ_MASK           0x000003FFU
+#define PDP_PLL_CLK1TO5_FREQ_SHIFT          0
+#define PDP_PLL_CLK1TO5_FREQ_SIGNED         0
+
+/*
+       Register PLL_PDP_DRP_GO
+*/
+#define TCF_PLL_PLL_PDP_DRP_GO              0x0028
+#define PLL_PDP_DRP_GO_MASK                 0x00000001U
+#define PLL_PDP_DRP_GO_SHIFT                0
+#define PLL_PDP_DRP_GO_SIGNED               0
+
+/*
+       Register PLL_PDP2_CLK0
+*/
+#define TCF_PLL_PLL_PDP2_CLK0               0x0030
+#define PDP2_PLL_CLK0_PHS_MASK              0x00300000U
+#define PDP2_PLL_CLK0_PHS_SHIFT             20
+#define PDP2_PLL_CLK0_PHS_SIGNED            0
+
+#define PDP2_PLL_CLK0_MS_MASK               0x00030000U
+#define PDP2_PLL_CLK0_MS_SHIFT              16
+#define PDP2_PLL_CLK0_MS_SIGNED             0
+
+#define PDP2_PLL_CLK0_FREQ_MASK             0x000001FFU
+#define PDP2_PLL_CLK0_FREQ_SHIFT            0
+#define PDP2_PLL_CLK0_FREQ_SIGNED           0
+
+/*
+       Register PLL_PDP2_CLK1TO5
+*/
+#define TCF_PLL_PLL_PDP2_CLK1TO5            0x0038
+#define PDP2_PLL_CLK1TO5_PHS_MASK           0x3FF00000U
+#define PDP2_PLL_CLK1TO5_PHS_SHIFT          20
+#define PDP2_PLL_CLK1TO5_PHS_SIGNED         0
+
+#define PDP2_PLL_CLK1TO5_MS_MASK            0x000FFC00U
+#define PDP2_PLL_CLK1TO5_MS_SHIFT           10
+#define PDP2_PLL_CLK1TO5_MS_SIGNED          0
+
+#define PDP2_PLL_CLK1TO5_FREQ_MASK          0x000003FFU
+#define PDP2_PLL_CLK1TO5_FREQ_SHIFT         0
+#define PDP2_PLL_CLK1TO5_FREQ_SIGNED        0
+
+/*
+       Register PLL_PDP2_DRP_GO
+*/
+#define TCF_PLL_PLL_PDP2_DRP_GO             0x0040
+#define PLL_PDP2_DRP_GO_MASK                0x00000001U
+#define PLL_PDP2_DRP_GO_SHIFT               0
+#define PLL_PDP2_DRP_GO_SIGNED              0
+
+/*
+       Register PLL_CORE_CLK0
+*/
+#define TCF_PLL_PLL_CORE_CLK0               0x0048
+#define CORE_PLL_CLK0_PHS_MASK              0x00300000U
+#define CORE_PLL_CLK0_PHS_SHIFT             20
+#define CORE_PLL_CLK0_PHS_SIGNED            0
+
+#define CORE_PLL_CLK0_MS_MASK               0x00030000U
+#define CORE_PLL_CLK0_MS_SHIFT              16
+#define CORE_PLL_CLK0_MS_SIGNED             0
+
+#define CORE_PLL_CLK0_FREQ_MASK             0x000001FFU
+#define CORE_PLL_CLK0_FREQ_SHIFT            0
+#define CORE_PLL_CLK0_FREQ_SIGNED           0
+
+/*
+       Register PLL_CORE_CLK1TO5
+*/
+#define TCF_PLL_PLL_CORE_CLK1TO5            0x0050
+#define CORE_PLL_CLK1TO5_PHS_MASK           0x3FF00000U
+#define CORE_PLL_CLK1TO5_PHS_SHIFT          20
+#define CORE_PLL_CLK1TO5_PHS_SIGNED         0
+
+#define CORE_PLL_CLK1TO5_MS_MASK            0x000FFC00U
+#define CORE_PLL_CLK1TO5_MS_SHIFT           10
+#define CORE_PLL_CLK1TO5_MS_SIGNED          0
+
+#define CORE_PLL_CLK1TO5_FREQ_MASK          0x000003FFU
+#define CORE_PLL_CLK1TO5_FREQ_SHIFT         0
+#define CORE_PLL_CLK1TO5_FREQ_SIGNED        0
+
+/*
+       Register PLL_CORE_DRP_GO
+*/
+#define TCF_PLL_PLL_CORE_DRP_GO             0x0058
+#define PLL_CORE_DRP_GO_MASK                0x00000001U
+#define PLL_CORE_DRP_GO_SHIFT               0
+#define PLL_CORE_DRP_GO_SIGNED              0
+
+/*
+       Register PLL_SYSIF_CLK0
+*/
+#define TCF_PLL_PLL_SYSIF_CLK0              0x0060
+#define SYSIF_PLL_CLK0_PHS_MASK             0x00300000U
+#define SYSIF_PLL_CLK0_PHS_SHIFT            20
+#define SYSIF_PLL_CLK0_PHS_SIGNED           0
+
+#define SYSIF_PLL_CLK0_MS_MASK              0x00030000U
+#define SYSIF_PLL_CLK0_MS_SHIFT             16
+#define SYSIF_PLL_CLK0_MS_SIGNED            0
+
+#define SYSIF_PLL_CLK0_FREQ_MASK            0x000001FFU
+#define SYSIF_PLL_CLK0_FREQ_SHIFT           0
+#define SYSIF_PLL_CLK0_FREQ_SIGNED          0
+
+/*
+       Register PLL_SYSIF_CLK1TO5
+*/
+#define TCF_PLL_PLL_SYSIF_CLK1TO5           0x0068
+#define SYSIF_PLL_CLK1TO5_PHS_MASK          0x3FF00000U
+#define SYSIF_PLL_CLK1TO5_PHS_SHIFT         20
+#define SYSIF_PLL_CLK1TO5_PHS_SIGNED        0
+
+#define SYSIF_PLL_CLK1TO5_MS_MASK           0x000FFC00U
+#define SYSIF_PLL_CLK1TO5_MS_SHIFT          10
+#define SYSIF_PLL_CLK1TO5_MS_SIGNED         0
+
+#define SYSIF_PLL_CLK1TO5_FREQ_MASK         0x000003FFU
+#define SYSIF_PLL_CLK1TO5_FREQ_SHIFT        0
+#define SYSIF_PLL_CLK1TO5_FREQ_SIGNED       0
+
+/*
+       Register PLL_SYS_DRP_GO
+*/
+#define TCF_PLL_PLL_SYS_DRP_GO              0x0070
+#define PLL_SYS_DRP_GO_MASK                 0x00000001U
+#define PLL_SYS_DRP_GO_SHIFT                0
+#define PLL_SYS_DRP_GO_SIGNED               0
+
+/*
+       Register PLL_MEMIF_CLK0
+*/
+#define TCF_PLL_PLL_MEMIF_CLK0              0x0078
+#define MEMIF_PLL_CLK0_PHS_MASK             0x00300000U
+#define MEMIF_PLL_CLK0_PHS_SHIFT            20
+#define MEMIF_PLL_CLK0_PHS_SIGNED           0
+
+#define MEMIF_PLL_CLK0_MS_MASK              0x00030000U
+#define MEMIF_PLL_CLK0_MS_SHIFT             16
+#define MEMIF_PLL_CLK0_MS_SIGNED            0
+
+#define MEMIF_PLL_CLK0_FREQ_MASK            0x000001FFU
+#define MEMIF_PLL_CLK0_FREQ_SHIFT           0
+#define MEMIF_PLL_CLK0_FREQ_SIGNED          0
+
+/*
+       Register PLL_MEMIF_CLK1TO5
+*/
+#define TCF_PLL_PLL_MEMIF_CLK1TO5           0x0080
+#define MEMIF_PLL_CLK1TO5_PHS_MASK          0x3FF00000U
+#define MEMIF_PLL_CLK1TO5_PHS_SHIFT         20
+#define MEMIF_PLL_CLK1TO5_PHS_SIGNED        0
+
+#define MEMIF_PLL_CLK1TO5_MS_MASK           0x000FFC00U
+#define MEMIF_PLL_CLK1TO5_MS_SHIFT          10
+#define MEMIF_PLL_CLK1TO5_MS_SIGNED         0
+
+#define MEMIF_PLL_CLK1TO5_FREQ_MASK         0x000003FFU
+#define MEMIF_PLL_CLK1TO5_FREQ_SHIFT        0
+#define MEMIF_PLL_CLK1TO5_FREQ_SIGNED       0
+
+/*
+       Register PLL_MEM_DRP_GO
+*/
+#define TCF_PLL_PLL_MEM_DRP_GO              0x0088
+#define PLL_MEM_DRP_GO_MASK                 0x00000001U
+#define PLL_MEM_DRP_GO_SHIFT                0
+#define PLL_MEM_DRP_GO_SIGNED               0
+
+/*
+       Register PLL_ALL_DRP_GO
+*/
+#define TCF_PLL_PLL_ALL_DRP_GO              0x0090
+#define PLL_ALL_DRP_GO_MASK                 0x00000001U
+#define PLL_ALL_DRP_GO_SHIFT                0
+#define PLL_ALL_DRP_GO_SIGNED               0
+
+/*
+       Register PLL_DRP_STATUS
+*/
+#define TCF_PLL_PLL_DRP_STATUS              0x0098
+#define PLL_LOCKS_MASK                      0x00003F00U
+#define PLL_LOCKS_SHIFT                     8
+#define PLL_LOCKS_SIGNED                    0
+
+#define PLL_DRP_GOOD_MASK                   0x0000003FU
+#define PLL_DRP_GOOD_SHIFT                  0
+#define PLL_DRP_GOOD_SIGNED                 0
+
+#endif /* !defined(_TCF_PLL_H_) */
+
+/*****************************************************************************
+ End of file (tcf_pll.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_rgbpdp_regs.h b/drivers/gpu/rogue_m/include/system/rgx_tc/tcf_rgbpdp_regs.h
new file mode 100644 (file)
index 0000000..f3e6d54
--- /dev/null
@@ -0,0 +1,559 @@
+/*************************************************************************/ /*!
+@Title          Test Chip Framework PDP register definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Autogenerated C -- do not edit
+                Generated from: tcf_rgbpdp_regs.def 
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_RGBPDP_REGS_H_)
+#define _TCF_RGBPDP_REGS_H_
+
+/*
+       Register PVR_TCF_RGBPDP_STR1SURF
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STR1SURF  0x0000
+#define STR1HEIGHT_MASK                     0x000007FFU
+#define STR1HEIGHT_SHIFT                    0
+#define STR1HEIGHT_SIGNED                   0
+
+#define STR1WIDTH_MASK                      0x003FF800U
+#define STR1WIDTH_SHIFT                     11
+#define STR1WIDTH_SIGNED                    0
+
+#define STR1PIXFMT_MASK                     0x0F000000U
+#define STR1PIXFMT_SHIFT                    24
+#define STR1PIXFMT_SIGNED                   0
+
+/*
+       Register PVR_TCF_RGBPDP_STR1ADDRCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL 0x0004
+#define STR1BASE_MASK                       0x03FFFFFFU
+#define STR1BASE_SHIFT                      0
+#define STR1BASE_SIGNED                     0
+
+#define STR1INTFIELD_MASK                   0x40000000U
+#define STR1INTFIELD_SHIFT                  30
+#define STR1INTFIELD_SIGNED                 0
+
+#define STR1STREN_MASK                      0x80000000U
+#define STR1STREN_SHIFT                     31
+#define STR1STREN_SIGNED                    0
+
+/*
+       Register PVR_PDP_STR1POSN
+*/
+#define TCF_RGBPDP_PVR_PDP_STR1POSN         0x0008
+#define STR1STRIDE_MASK                     0x000003FFU
+#define STR1STRIDE_SHIFT                    0
+#define STR1STRIDE_SIGNED                   0
+
+/*
+       Register PVR_TCF_RGBPDP_MEMCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_MEMCTRL   0x000C
+#define MEMREFRESH_MASK                     0xC0000000U
+#define MEMREFRESH_SHIFT                    30
+#define MEMREFRESH_SIGNED                   0
+
+/*
+       Register PVR_TCF_RGBPDP_STRCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STRCTRL   0x0010
+#define BURSTLEN_GFX_MASK                   0x000000FFU
+#define BURSTLEN_GFX_SHIFT                  0
+#define BURSTLEN_GFX_SIGNED                 0
+
+#define THRESHOLD_GFX_MASK                  0x0000FF00U
+#define THRESHOLD_GFX_SHIFT                 8
+#define THRESHOLD_GFX_SIGNED                0
+
+/*
+       Register PVR_TCF_RGBPDP_SYNCCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL  0x0014
+#define HSDIS_MASK                          0x00000001U
+#define HSDIS_SHIFT                         0
+#define HSDIS_SIGNED                        0
+
+#define HSPOL_MASK                          0x00000002U
+#define HSPOL_SHIFT                         1
+#define HSPOL_SIGNED                        0
+
+#define VSDIS_MASK                          0x00000004U
+#define VSDIS_SHIFT                         2
+#define VSDIS_SIGNED                        0
+
+#define VSPOL_MASK                          0x00000008U
+#define VSPOL_SHIFT                         3
+#define VSPOL_SIGNED                        0
+
+#define BLNKDIS_MASK                        0x00000010U
+#define BLNKDIS_SHIFT                       4
+#define BLNKDIS_SIGNED                      0
+
+#define BLNKPOL_MASK                        0x00000020U
+#define BLNKPOL_SHIFT                       5
+#define BLNKPOL_SIGNED                      0
+
+#define HS_SLAVE_MASK                       0x00000040U
+#define HS_SLAVE_SHIFT                      6
+#define HS_SLAVE_SIGNED                     0
+
+#define VS_SLAVE_MASK                       0x00000080U
+#define VS_SLAVE_SHIFT                      7
+#define VS_SLAVE_SIGNED                     0
+
+#define INTERLACE_MASK                      0x00000100U
+#define INTERLACE_SHIFT                     8
+#define INTERLACE_SIGNED                    0
+
+#define FIELDPOL_MASK                       0x00000200U
+#define FIELDPOL_SHIFT                      9
+#define FIELDPOL_SIGNED                     0
+
+#define CLKPOL_MASK                         0x00000800U
+#define CLKPOL_SHIFT                        11
+#define CLKPOL_SIGNED                       0
+
+#define CSYNC_EN_MASK                       0x00001000U
+#define CSYNC_EN_SHIFT                      12
+#define CSYNC_EN_SIGNED                     0
+
+#define FIELD_EN_MASK                       0x00002000U
+#define FIELD_EN_SHIFT                      13
+#define FIELD_EN_SIGNED                     0
+
+#define UPDWAIT_MASK                        0x000F0000U
+#define UPDWAIT_SHIFT                       16
+#define UPDWAIT_SIGNED                      0
+
+#define UPDCTRL_MASK                        0x01000000U
+#define UPDCTRL_SHIFT                       24
+#define UPDCTRL_SIGNED                      0
+
+#define UPDINTCTRL_MASK                     0x02000000U
+#define UPDINTCTRL_SHIFT                    25
+#define UPDINTCTRL_SIGNED                   0
+
+#define UPDSYNCTRL_MASK                     0x04000000U
+#define UPDSYNCTRL_SHIFT                    26
+#define UPDSYNCTRL_SIGNED                   0
+
+#define POWERDN_MASK                        0x10000000U
+#define POWERDN_SHIFT                       28
+#define POWERDN_SIGNED                      0
+
+#define DISP_RST_MASK                       0x20000000U
+#define DISP_RST_SHIFT                      29
+#define DISP_RST_SIGNED                     0
+
+#define SYNCACTIVE_MASK                     0x80000000U
+#define SYNCACTIVE_SHIFT                    31
+#define SYNCACTIVE_SIGNED                   0
+
+/*
+       Register PVR_TCF_RGBPDP_BORDCOL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_BORDCOL   0x0018
+#define BORDCOL_MASK                        0x00FFFFFFU
+#define BORDCOL_SHIFT                       0
+#define BORDCOL_SIGNED                      0
+
+/*
+       Register PVR_TCF_RGBPDP_UPDCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_UPDCTRL   0x001C
+#define UPDFIELD_MASK                       0x00000001U
+#define UPDFIELD_SHIFT                      0
+#define UPDFIELD_SIGNED                     0
+
+/*
+       Register PVR_TCF_RGBPDP_HSYNC1
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC1    0x0020
+#define HT_MASK                             0x00000FFFU
+#define HT_SHIFT                            0
+#define HT_SIGNED                           0
+
+#define HBPS_MASK                           0x0FFF0000U
+#define HBPS_SHIFT                          16
+#define HBPS_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_HSYNC2
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC2    0x0024
+#define HLBS_MASK                           0x00000FFFU
+#define HLBS_SHIFT                          0
+#define HLBS_SIGNED                         0
+
+#define HAS_MASK                            0x0FFF0000U
+#define HAS_SHIFT                           16
+#define HAS_SIGNED                          0
+
+/*
+       Register PVR_TCF_RGBPDP_HSYNC3
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC3    0x0028
+#define HRBS_MASK                           0x00000FFFU
+#define HRBS_SHIFT                          0
+#define HRBS_SIGNED                         0
+
+#define HFPS_MASK                           0x0FFF0000U
+#define HFPS_SHIFT                          16
+#define HFPS_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_VSYNC1
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC1    0x002C
+#define VT_MASK                             0x00000FFFU
+#define VT_SHIFT                            0
+#define VT_SIGNED                           0
+
+#define VBPS_MASK                           0x0FFF0000U
+#define VBPS_SHIFT                          16
+#define VBPS_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_VSYNC2
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC2    0x0030
+#define VTBS_MASK                           0x00000FFFU
+#define VTBS_SHIFT                          0
+#define VTBS_SIGNED                         0
+
+#define VAS_MASK                            0x0FFF0000U
+#define VAS_SHIFT                           16
+#define VAS_SIGNED                          0
+
+/*
+       Register PVR_TCF_RGBPDP_VSYNC3
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC3    0x0034
+#define VBBS_MASK                           0x00000FFFU
+#define VBBS_SHIFT                          0
+#define VBBS_SIGNED                         0
+
+#define VFPS_MASK                           0x0FFF0000U
+#define VFPS_SHIFT                          16
+#define VFPS_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_HDECTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HDECTRL   0x0038
+#define HDEF_MASK                           0x00000FFFU
+#define HDEF_SHIFT                          0
+#define HDEF_SIGNED                         0
+
+#define HDES_MASK                           0x0FFF0000U
+#define HDES_SHIFT                          16
+#define HDES_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_VDECTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VDECTRL   0x003C
+#define VDEF_MASK                           0x00000FFFU
+#define VDEF_SHIFT                          0
+#define VDEF_SIGNED                         0
+
+#define VDES_MASK                           0x0FFF0000U
+#define VDES_SHIFT                          16
+#define VDES_SIGNED                         0
+
+/*
+       Register PVR_TCF_RGBPDP_VEVENT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VEVENT    0x0040
+#define VFETCH_MASK                         0x00000FFFU
+#define VFETCH_SHIFT                        0
+#define VFETCH_SIGNED                       0
+
+#define VEVENT_MASK                         0x0FFF0000U
+#define VEVENT_SHIFT                        16
+#define VEVENT_SIGNED                       0
+
+/*
+       Register PVR_TCF_RGBPDP_OPMASK
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_OPMASK    0x0044
+#define MASKR_MASK                          0x000000FFU
+#define MASKR_SHIFT                         0
+#define MASKR_SIGNED                        0
+
+#define MASKG_MASK                          0x0000FF00U
+#define MASKG_SHIFT                         8
+#define MASKG_SIGNED                        0
+
+#define MASKB_MASK                          0x00FF0000U
+#define MASKB_SHIFT                         16
+#define MASKB_SIGNED                        0
+
+#define BLANKLEVEL_MASK                     0x40000000U
+#define BLANKLEVEL_SHIFT                    30
+#define BLANKLEVEL_SIGNED                   0
+
+#define MASKLEVEL_MASK                      0x80000000U
+#define MASKLEVEL_SHIFT                     31
+#define MASKLEVEL_SIGNED                    0
+
+/*
+       Register PVR_TCF_RGBPDP_INTSTAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTSTAT   0x0048
+#define INTS_HBLNK0_MASK                    0x00000001U
+#define INTS_HBLNK0_SHIFT                   0
+#define INTS_HBLNK0_SIGNED                  0
+
+#define INTS_HBLNK1_MASK                    0x00000002U
+#define INTS_HBLNK1_SHIFT                   1
+#define INTS_HBLNK1_SIGNED                  0
+
+#define INTS_VBLNK0_MASK                    0x00000004U
+#define INTS_VBLNK0_SHIFT                   2
+#define INTS_VBLNK0_SIGNED                  0
+
+#define INTS_VBLNK1_MASK                    0x00000008U
+#define INTS_VBLNK1_SHIFT                   3
+#define INTS_VBLNK1_SIGNED                  0
+
+#define INTS_STR1URUN_MASK                  0x00000010U
+#define INTS_STR1URUN_SHIFT                 4
+#define INTS_STR1URUN_SIGNED                0
+
+#define INTS_STR1ORUN_MASK                  0x00000020U
+#define INTS_STR1ORUN_SHIFT                 5
+#define INTS_STR1ORUN_SIGNED                0
+
+#define INTS_DISPURUN_MASK                  0x00000040U
+#define INTS_DISPURUN_SHIFT                 6
+#define INTS_DISPURUN_SIGNED                0
+
+/*
+       Register PVR_TCF_RGBPDP_INTENAB
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB   0x004C
+#define INTEN_HBLNK0_MASK                   0x00000001U
+#define INTEN_HBLNK0_SHIFT                  0
+#define INTEN_HBLNK0_SIGNED                 0
+
+#define INTEN_HBLNK1_MASK                   0x00000002U
+#define INTEN_HBLNK1_SHIFT                  1
+#define INTEN_HBLNK1_SIGNED                 0
+
+#define INTEN_VBLNK0_MASK                   0x00000004U
+#define INTEN_VBLNK0_SHIFT                  2
+#define INTEN_VBLNK0_SIGNED                 0
+
+#define INTEN_VBLNK1_MASK                   0x00000008U
+#define INTEN_VBLNK1_SHIFT                  3
+#define INTEN_VBLNK1_SIGNED                 0
+
+#define INTEN_STR1URUN_MASK                 0x00000010U
+#define INTEN_STR1URUN_SHIFT                4
+#define INTEN_STR1URUN_SIGNED               0
+
+#define INTEN_STR1ORUN_MASK                 0x00000020U
+#define INTEN_STR1ORUN_SHIFT                5
+#define INTEN_STR1ORUN_SIGNED               0
+
+#define INTEN_DISPURUN_MASK                 0x00000040U
+#define INTEN_DISPURUN_SHIFT                6
+#define INTEN_DISPURUN_SIGNED               0
+
+/*
+       Register PVR_TCF_RGBPDP_INTCLEAR
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTCLEAR  0x0050
+#define INTCLR_HBLNK0_MASK                  0x00000001U
+#define INTCLR_HBLNK0_SHIFT                 0
+#define INTCLR_HBLNK0_SIGNED                0
+
+#define INTCLR_HBLNK1_MASK                  0x00000002U
+#define INTCLR_HBLNK1_SHIFT                 1
+#define INTCLR_HBLNK1_SIGNED                0
+
+#define INTCLR_VBLNK0_MASK                  0x00000004U
+#define INTCLR_VBLNK0_SHIFT                 2
+#define INTCLR_VBLNK0_SIGNED                0
+
+#define INTCLR_VBLNK1_MASK                  0x00000008U
+#define INTCLR_VBLNK1_SHIFT                 3
+#define INTCLR_VBLNK1_SIGNED                0
+
+#define INTCLR_STR1URUN_MASK                0x00000010U
+#define INTCLR_STR1URUN_SHIFT               4
+#define INTCLR_STR1URUN_SIGNED              0
+
+#define INTCLR_STR1ORUN_MASK                0x00000020U
+#define INTCLR_STR1ORUN_SHIFT               5
+#define INTCLR_STR1ORUN_SIGNED              0
+
+#define INTCLR_DISPURUN_MASK                0x00000040U
+#define INTCLR_DISPURUN_SHIFT               6
+#define INTCLR_DISPURUN_SIGNED              0
+
+/*
+       Register PVR_TCF_RGBPDP_INTCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTCTRL   0x0054
+#define HBLNK_LINENO_MASK                   0x00000FFFU
+#define HBLNK_LINENO_SHIFT                  0
+#define HBLNK_LINENO_SIGNED                 0
+
+#define HBLNK_LINE_MASK                     0x00010000U
+#define HBLNK_LINE_SHIFT                    16
+#define HBLNK_LINE_SIGNED                   0
+
+/*
+       Register PVR_TCF_RGBPDP_SIGNAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_SIGNAT    0x0058
+#define SIGNATURE_MASK                      0xFFFFFFFFU
+#define SIGNATURE_SHIFT                     0
+#define SIGNATURE_SIGNED                    0
+
+/*
+       Register PVR_TCF_RGBPDP_LINESTAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_LINESTAT  0x005C
+#define LINENO_MASK                         0x00000FFFU
+#define LINENO_SHIFT                        0
+#define LINENO_SIGNED                       0
+
+/*
+       Register PVR_TCF_RGBPDP_DBGCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGCTRL   0x0060
+#define DBG_ENAB_MASK                       0x00000001U
+#define DBG_ENAB_SHIFT                      0
+#define DBG_ENAB_SIGNED                     0
+
+#define DBG_READ_MASK                       0x00000002U
+#define DBG_READ_SHIFT                      1
+#define DBG_READ_SIGNED                     0
+
+/*
+       Register PVR_TCF_RGBPDP_DBGDATA
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGDATA   0x0064
+#define DBG_DATA_MASK                       0x00FFFFFFU
+#define DBG_DATA_SHIFT                      0
+#define DBG_DATA_SIGNED                     0
+
+/*
+       Register PVR_TCF_RGBPDP_DBGSIDE
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGSIDE   0x0068
+#define DBG_SIDE_MASK                       0x00000007U
+#define DBG_SIDE_SHIFT                      0
+#define DBG_SIDE_SIGNED                     0
+
+#define DBG_VAL_MASK                        0x00000008U
+#define DBG_VAL_SHIFT                       3
+#define DBG_VAL_SIGNED                      0
+
+/*
+       Register PVR_TCF_RGBPDP_REGLD_STAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_REGLD_STAT 0x0070
+#define REGLD_ADDROUT_MASK                  0x00FFFFFFU
+#define REGLD_ADDROUT_SHIFT                 0
+#define REGLD_ADDROUT_SIGNED                0
+
+#define REGLD_ADDREN_MASK                   0x80000000U
+#define REGLD_ADDREN_SHIFT                  31
+#define REGLD_ADDREN_SIGNED                 0
+
+/*
+       Register PVR_TCF_RGBPDP_REGLD_CTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_REGLD_CTRL 0x0074
+#define REGLD_ADDRIN_MASK                   0x00FFFFFFU
+#define REGLD_ADDRIN_SHIFT                  0
+#define REGLD_ADDRIN_SIGNED                 0
+
+#define REGLD_VAL_MASK                      0x01000000U
+#define REGLD_VAL_SHIFT                     24
+#define REGLD_VAL_SIGNED                    0
+
+#define REGLD_ADDRLEN_MASK                  0xFE000000U
+#define REGLD_ADDRLEN_SHIFT                 25
+#define REGLD_ADDRLEN_SIGNED                0
+
+/*
+       Register PVR_TCF_RGBPDP_CORE_ID
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_CORE_ID   0x0078
+#define CONFIG_ID_MASK                      0x0000FFFFU
+#define CONFIG_ID_SHIFT                     0
+#define CONFIG_ID_SIGNED                    0
+
+#define CORE_ID_MASK                        0x00FF0000U
+#define CORE_ID_SHIFT                       16
+#define CORE_ID_SIGNED                      0
+
+#define GROUP_ID_MASK                       0xFF000000U
+#define GROUP_ID_SHIFT                      24
+#define GROUP_ID_SIGNED                     0
+
+/*
+       Register PVR_TCF_RGBPDP_CORE_REV
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_CORE_REV  0x007C
+#define MAINT_REV_MASK                      0x000000FFU
+#define MAINT_REV_SHIFT                     0
+#define MAINT_REV_SIGNED                    0
+
+#define MINOR_REV_MASK                      0x0000FF00U
+#define MINOR_REV_SHIFT                     8
+#define MINOR_REV_SIGNED                    0
+
+#define MAJOR_REV_MASK                      0x00FF0000U
+#define MAJOR_REV_SHIFT                     16
+#define MAJOR_REV_SIGNED                    0
+
+#endif /* !defined(_TCF_RGBPDP_REGS_H_) */
+
+/*****************************************************************************
+ End of file (tcf_rgbpdp_regs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Kbuild.mk b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Kbuild.mk
new file mode 100644 (file)
index 0000000..4c7f998
--- /dev/null
@@ -0,0 +1,84 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ccflags-y := \
+ -I$(TOP)/kernel/drivers/staging/imgtec \
+ -I$(TOP)/include/system/rgx_tc \
+ $(ccflags-y)
+
+# Avoid picking up the services version of 'sync.h'
+CFLAGS_adf_common.o := -Idrivers/staging/android
+CFLAGS_adf_fbdev.o := -Idrivers/staging/android
+CFLAGS_adf_pdp.o := -Idrivers/staging/android
+CFLAGS_adf_sunxi.o := -Idrivers/staging/android
+
+adf_fbdev-y += \
+ kernel/drivers/staging/imgtec/adf_fbdev.o \
+ kernel/drivers/staging/imgtec/adf_common.o
+
+adf_pdp-y += \
+ kernel/drivers/staging/imgtec/adf_pdp.o \
+ kernel/drivers/staging/imgtec/adf_common.o
+
+apollo-y += \
+ kernel/drivers/staging/imgtec/apollo.o
+
+ifeq ($(SUPPORT_ION),1)
+apollo-y += \
+ kernel/drivers/staging/imgtec/ion_lma_heap.o
+endif
+
+adf_sunxi-y += \
+ kernel/drivers/staging/imgtec/adf_sunxi.o \
+ kernel/drivers/staging/imgtec/adf_common.o
+
+drm_fbdev-y += \
+ kernel/drivers/staging/imgtec/drm_fbdev.o
+
+drm_nulldisp-y += \
+ kernel/drivers/staging/imgtec/drm_nulldisp.o
+
+drm_pdp-y += \
+ kernel/drivers/staging/imgtec/drm_pdp.o \
+ kernel/drivers/staging/imgtec/drm_pdp_mm.o \
+ kernel/drivers/staging/imgtec/drm_pdp_modeset.o \
+ kernel/drivers/staging/imgtec/drm_pdp_crtc.o \
+ kernel/drivers/staging/imgtec/drm_pdp_dvi.o \
+ kernel/drivers/staging/imgtec/drm_pdp_tmds.o
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Linux.mk b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/Linux.mk
new file mode 100644 (file)
index 0000000..826da4f
--- /dev/null
@@ -0,0 +1,69 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := adf_fbdev adf_pdp apollo adf_sunxi drm_fbdev drm_nulldisp drm_pdp
+
+adf_fbdev_type := kernel_module
+adf_fbdev_target := adf_fbdev.ko
+adf_fbdev_makefile := $(THIS_DIR)/Kbuild.mk
+
+adf_pdp_type := kernel_module
+adf_pdp_target := adf_pdp.ko
+adf_pdp_makefile := $(THIS_DIR)/Kbuild.mk
+
+apollo_type := kernel_module
+apollo_target := apollo.ko
+apollo_makefile := $(THIS_DIR)/Kbuild.mk
+
+adf_sunxi_type := kernel_module
+adf_sunxi_target := adf_sunxi.ko
+adf_sunxi_makefile := $(THIS_DIR)/Kbuild.mk
+
+drm_fbdev_type := kernel_module
+drm_fbdev_target := drm_fbdev.ko
+drm_fbdev_makefile := $(THIS_DIR)/Kbuild.mk
+
+drm_nulldisp_type := kernel_module
+drm_nulldisp_target := drm_nulldisp.ko
+drm_nulldisp_makefile := $(THIS_DIR)/Kbuild.mk
+
+drm_pdp_type := kernel_module
+drm_pdp_target := drm_pdp.ko
+drm_pdp_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.c
new file mode 100644 (file)
index 0000000..a32f8ff
--- /dev/null
@@ -0,0 +1,564 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#include "adf_common.h"
+
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/dma-buf.h>
+#include <linux/compat.h>
+#include <linux/bug.h>
+
+#include <video/adf_client.h>
+
+#ifdef DEBUG_VALIDATE
+#define val_dbg(dev, fmt, x...) dev_dbg(dev, fmt, x)
+#else
+#define val_dbg(dev, fmt, x...) do { } while (0)
+#endif
+
+static long validate(struct adf_device *dev,
+       struct adf_validate_config_ext __user *arg)
+{
+       struct adf_interface **intfs = NULL;
+       struct adf_buffer *bufs = NULL;
+       struct adf_post post_cfg;
+       u32 post_ext_size;
+       void *driver_state;
+       int err = 0;
+       size_t i, j;
+
+       if (arg->n_interfaces > ADF_MAX_INTERFACES) {
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       if (arg->n_bufs > ADF_MAX_BUFFERS) {
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       post_ext_size = sizeof(struct adf_post_ext) +
+               arg->n_bufs * sizeof(struct adf_buffer_config_ext);
+
+       if (!access_ok(VERIFY_READ, arg->bufs,
+                      sizeof(struct adf_buffer_config) * arg->n_bufs)) {
+               err = -EFAULT;
+               goto err_out;
+       }
+
+       if (!access_ok(VERIFY_READ, arg->post_ext,
+                      post_ext_size)) {
+               err = -EFAULT;
+               goto err_out;
+       }
+
+       if (arg->n_interfaces) {
+               if (!access_ok(VERIFY_READ, arg->interfaces,
+                    sizeof(*arg->interfaces) * arg->n_interfaces)) {
+                       err = -EFAULT;
+                       goto err_out;
+               }
+               intfs = kmalloc_array(arg->n_interfaces, sizeof(intfs[0]),
+                                     GFP_KERNEL);
+               if (!intfs) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+       }
+
+       for (i = 0; i < arg->n_interfaces; i++) {
+               intfs[i] = idr_find(&dev->interfaces, arg->interfaces[i]);
+               if (!intfs[i]) {
+                       err = -EINVAL;
+                       goto err_out;
+               }
+       }
+
+       if (arg->n_bufs) {
+               bufs = kcalloc(arg->n_bufs, sizeof(bufs[0]), GFP_KERNEL);
+               if (!bufs) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+       }
+
+       for (i = 0; i < arg->n_bufs; i++) {
+               struct adf_buffer_config *config = &arg->bufs[i];
+
+               memset(&bufs[i], 0, sizeof(bufs[i]));
+
+               if (config->n_planes > ADF_MAX_PLANES) {
+                       err = -EINVAL;
+                       goto err_import;
+               }
+
+               bufs[i].overlay_engine = idr_find(&dev->overlay_engines,
+                                                 config->overlay_engine);
+               if (!bufs[i].overlay_engine) {
+                       err = -ENOENT;
+                       goto err_import;
+               }
+
+               bufs[i].w = config->w;
+               bufs[i].h = config->h;
+               bufs[i].format = config->format;
+
+               for (j = 0; j < config->n_planes; j++) {
+                       bufs[i].dma_bufs[j] = dma_buf_get(config->fd[j]);
+                       if (IS_ERR_OR_NULL(bufs[i].dma_bufs[j])) {
+                               err = PTR_ERR(bufs[i].dma_bufs[j]);
+                               bufs[i].dma_bufs[j] = NULL;
+                               goto err_import;
+                       }
+                       bufs[i].offset[j] = config->offset[j];
+                       bufs[i].pitch[j] = config->pitch[j];
+               }
+               bufs[i].n_planes = config->n_planes;
+
+               bufs[i].acquire_fence = NULL;
+       }
+
+       /* Fake up a post configuration to validate */
+       post_cfg.custom_data_size = post_ext_size;
+       post_cfg.custom_data = arg->post_ext;
+       post_cfg.n_bufs = arg->n_bufs;
+       post_cfg.bufs = bufs;
+
+       /* Mapping dma bufs is too expensive for validate, and we don't
+        * need to do it at the moment.
+        */
+       post_cfg.mappings = NULL;
+
+       err = dev->ops->validate(dev, &post_cfg, &driver_state);
+       if (err)
+               goto err_import;
+
+       /* For the validate ioctl, we don't need the driver state. If it
+        * was allocated, free it immediately.
+        */
+       if (dev->ops->state_free)
+               dev->ops->state_free(dev, driver_state);
+
+err_import:
+       for (i = 0; i < arg->n_bufs; i++)
+               for (j = 0; j < ARRAY_SIZE(bufs[i].dma_bufs); j++)
+                       if (bufs[i].dma_bufs[j])
+                               dma_buf_put(bufs[i].dma_bufs[j]);
+err_out:
+       kfree(intfs);
+       kfree(bufs);
+       return err;
+}
+
+static long adf_img_ioctl_validate(struct adf_device *dev,
+struct adf_validate_config_ext __user *arg)
+{
+       int err;
+
+       if (!access_ok(VERIFY_READ, arg,
+            sizeof(struct adf_validate_config_ext))) {
+               err = -EFAULT;
+               goto err_out;
+       }
+       err = validate(dev, arg);
+err_out:
+       return err;
+}
+
+#ifdef CONFIG_COMPAT
+
+#define ADF_VALIDATE_CONFIG_EXT32 \
+       _IOW(ADF_IOCTL_TYPE, ADF_IOCTL_NR_VALIDATE_IMG, \
+               struct adf_validate_config_ext32)
+
+struct adf_validate_config_ext32 {
+       __u32           n_interfaces;
+       compat_uptr_t   interfaces;
+
+       __u32           n_bufs;
+
+       compat_uptr_t   bufs;
+       compat_uptr_t   post_ext;
+} __packed;
+
+/* adf_validate_config_ext32 must map to the adf_validate_config_ext struct.
+ * Changes to struct adf_validate_config_ext will likely be needed to be
+ * mirrored in adf_validate_config_ext32, so put a sanity check here to try
+ * to notice if the size has changed from what's expected.
+ */
+
+static long adf_img_ioctl_validate_compat(struct adf_device *dev,
+                 struct adf_validate_config_ext32 __user *arg_compat)
+{
+       struct adf_validate_config_ext arg;
+       int err = 0;
+
+       BUILD_BUG_ON_MSG(sizeof(struct adf_validate_config_ext) != 32,
+               "adf_validate_config_ext has unexpected size");
+
+       if (!access_ok(VERIFY_READ, arg_compat,
+               sizeof(struct adf_validate_config_ext32))) {
+               err = -EFAULT;
+               goto err_out;
+       }
+
+       arg.n_interfaces = arg_compat->n_interfaces;
+       arg.interfaces = compat_ptr(arg_compat->interfaces);
+       arg.n_bufs = arg_compat->n_bufs;
+       arg.bufs = compat_ptr(arg_compat->bufs);
+       arg.post_ext = compat_ptr(arg_compat->post_ext);
+
+       err = validate(dev, &arg);
+err_out:
+       return err;
+}
+
+#endif /* CONFIG_COMPAT */
+
+long adf_img_ioctl(struct adf_obj *obj, unsigned int cmd, unsigned long arg)
+{
+       struct adf_device *dev =
+               (struct adf_device *)obj->parent;
+
+       switch (cmd) {
+       case ADF_VALIDATE_CONFIG_EXT:
+               return adf_img_ioctl_validate(dev,
+                       (struct adf_validate_config_ext __user *)arg);
+#ifdef CONFIG_COMPAT
+       case ADF_VALIDATE_CONFIG_EXT32:
+               return adf_img_ioctl_validate_compat(dev,
+                       (struct adf_validate_config_ext32 __user *)
+                                                       compat_ptr(arg));
+#endif
+       }
+
+       return -ENOTTY;
+}
+
+/* Callers of this function should have taken the dev->client_lock */
+
+static struct adf_interface *
+get_interface_attached_to_overlay(struct adf_device *dev,
+                                 struct adf_overlay_engine *overlay)
+{
+       struct adf_interface *interface = NULL;
+       struct adf_attachment_list *entry;
+
+       /* We are open-coding adf_attachment_list_to_array. We can't use the
+        * adf_device_attachments helper because it takes the client lock,
+        * which is already held for calls to validate.
+        */
+       list_for_each_entry(entry, &dev->attached, head) {
+               /* If there are multiple interfaces attached to an overlay,
+                * this will return the last.
+                */
+               if (entry->attachment.overlay_engine == overlay)
+                       interface = entry->attachment.interface;
+       }
+
+       return interface;
+}
+
+int adf_img_validate_simple(struct adf_device *dev, struct adf_post *cfg,
+                           void **driver_state)
+{
+       struct adf_post_ext *post_ext = cfg->custom_data;
+       struct adf_overlay_engine *overlay;
+       struct adf_interface *interface;
+       struct adf_buffer *buffer;
+       int i = 0;
+       struct device *device = dev->dev;
+       size_t expected_custom_data_size;
+
+       /* "Null" flip handling */
+       if (cfg->n_bufs == 0)
+               return 0;
+
+       expected_custom_data_size = sizeof(struct adf_post_ext)
+               + cfg->n_bufs * sizeof(struct adf_buffer_config_ext);
+       if (cfg->custom_data_size != expected_custom_data_size) {
+               val_dbg(device, "Custom data size %zu not expected size %zu",
+                        cfg->custom_data_size,
+                        sizeof(struct adf_buffer_config_ext));
+               return -EINVAL;
+       }
+
+       if (cfg->n_bufs != 1) {
+               val_dbg(device, "Got %zu buffers in post. Should be 1.\n",
+                       cfg->n_bufs);
+               return -EINVAL;
+       }
+
+       buffer = &cfg->bufs[0];
+       overlay = buffer->overlay_engine;
+       if (!overlay) {
+               dev_err(device, "Buffer without an overlay engine.\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < overlay->ops->n_supported_formats; i++) {
+               if (buffer->format == overlay->ops->supported_formats[i])
+                       break;
+       }
+
+       if (i == overlay->ops->n_supported_formats) {
+               char req_format_str[ADF_FORMAT_STR_SIZE];
+
+               adf_format_str(buffer->format, req_format_str);
+
+               val_dbg(device, "Unsupported buffer format %s.\n",
+                       req_format_str);
+               return -EINVAL;
+       }
+
+       interface = get_interface_attached_to_overlay(dev, overlay);
+       if (!interface) {
+               dev_err(device, "No interface attached to overlay\n");
+               return -EINVAL;
+       }
+
+       if (buffer->w != interface->current_mode.hdisplay) {
+               val_dbg(device, "Buffer width %u is not expected %u.\n",
+                        buffer->w, interface->current_mode.hdisplay);
+               return -EINVAL;
+       }
+
+       if (buffer->h != interface->current_mode.vdisplay) {
+               val_dbg(device, "Buffer height %u is not expected %u.\n",
+                        buffer->h, interface->current_mode.vdisplay);
+               return -EINVAL;
+       }
+
+       if (buffer->n_planes != 1) {
+               val_dbg(device, "Buffer n_planes %u is not 1.\n",
+                       buffer->n_planes);
+               return -EINVAL;
+       }
+
+       if (buffer->offset[0] != 0) {
+               val_dbg(device, "Buffer offset %u is not 0.\n",
+                       buffer->offset[0]);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < cfg->n_bufs; i++) {
+               struct adf_buffer_config_ext *buf_ext = &post_ext->bufs_ext[i];
+               u16 hdisplay = interface->current_mode.hdisplay;
+               u16 vdisplay = interface->current_mode.vdisplay;
+
+               if (buf_ext->crop.x1 != 0 ||
+                   buf_ext->crop.y1 != 0 ||
+                   buf_ext->crop.x2 != hdisplay ||
+                   buf_ext->crop.y2 != vdisplay) {
+                       val_dbg(device, "Buffer crop {%u,%u,%u,%u} not expected {%u,%u,%u,%u}.\n",
+                               buf_ext->crop.x1, buf_ext->crop.y1,
+                               buf_ext->crop.x2, buf_ext->crop.y2,
+                               0, 0, hdisplay, vdisplay);
+
+                       /* Userspace might be emulating a lower resolution */
+                       if (buf_ext->crop.x2 > hdisplay ||
+                           buf_ext->crop.y2 > vdisplay)
+                               return -EINVAL;
+               }
+
+               if (buf_ext->display.x1 != 0 ||
+                   buf_ext->display.y1 != 0 ||
+                   buf_ext->display.x2 != hdisplay ||
+                   buf_ext->display.y2 != vdisplay) {
+                       val_dbg(device, "Buffer display {%u,%u,%u,%u} not expected {%u,%u,%u,%u}.\n",
+                               buf_ext->display.x1, buf_ext->display.y1,
+                               buf_ext->display.x2, buf_ext->display.y2,
+                               0, 0, hdisplay, vdisplay);
+
+                       /* Userspace might be emulating a lower resolution */
+                       if (buf_ext->display.x2 > hdisplay ||
+                           buf_ext->display.y2 > vdisplay)
+                               return -EINVAL;
+               }
+
+               if (buf_ext->transform != ADF_BUFFER_TRANSFORM_NONE_EXT) {
+                       val_dbg(device, "Buffer transform 0x%x not expected transform 0x%x.\n",
+                               buf_ext->transform,
+                               ADF_BUFFER_TRANSFORM_NONE_EXT);
+                       return -EINVAL;
+               }
+
+               if (buf_ext->blend_type != ADF_BUFFER_BLENDING_PREMULT_EXT &&
+                   buf_ext->blend_type != ADF_BUFFER_BLENDING_NONE_EXT) {
+                       val_dbg(device, "Buffer blend type %u not supported.\n",
+                               buf_ext->blend_type);
+                       return -EINVAL;
+               }
+
+               if (buf_ext->plane_alpha != 0xff) {
+                       val_dbg(device, "Buffer plane alpha %u not expected plane alpha %u.\n",
+                               buf_ext->plane_alpha, 0xff);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+bool adf_img_buffer_sanity_check(const struct adf_interface *intf,
+       const struct adf_buffer *buf,
+       const struct adf_buffer_config_ext *buf_ext)
+{
+       struct device *dev = intf->base.parent->dev;
+       int plane;
+
+       if (buf->w == 0) {
+               dev_err(dev, "Buffer sanity failed: Zero width\n");
+               return false;
+       }
+       if (buf->h == 0) {
+               dev_err(dev, "Buffer sanity failed: Zero height\n");
+               return false;
+       }
+       if (buf->format == 0) {
+               dev_err(dev, "Buffer sanity failed: Zero format\n");
+               return false;
+       }
+       if (buf->pitch == 0) {
+               dev_err(dev, "Buffer sanity failed: Zero pitch\n");
+               return false;
+       }
+       if (buf->n_planes == 0) {
+               dev_err(dev, "Buffer sanity failed: Zero plane count\n");
+               return false;
+       }
+       if (buf->overlay_engine == NULL) {
+               dev_err(dev, "Buffer sanity failed: NULL assigned overlay\n");
+               return false;
+       }
+
+       for (plane = 0; plane < buf->n_planes; plane++) {
+               if (buf->dma_bufs[plane] == NULL) {
+                       dev_err(dev, "Buffer sanity failed: NULL dma buf for plane %d\n",
+                               plane);
+                       return false;
+               }
+               if (buf->pitch[plane] == 0) {
+                       dev_err(dev, "Buffer sanity failed: Zero pitch for plane %d\n",
+                               plane);
+                       return false;
+               }
+               /* The offset may be zero, so we can't check that here */
+       }
+
+       if (buf_ext->crop.x1 >= buf_ext->crop.x2 ||
+           buf_ext->crop.y1 >= buf_ext->crop.y2) {
+               dev_err(dev, "Buffer sanity failed: Invalid crop rect (%d,%d)(%d,%d)\n",
+                       buf_ext->crop.x1, buf_ext->crop.y1,
+                       buf_ext->crop.x2, buf_ext->crop.y2);
+               return false;
+       }
+
+       if (buf_ext->crop.x1 > buf->w ||
+           buf_ext->crop.x2 > buf->w ||
+           buf_ext->crop.y1 > buf->h ||
+           buf_ext->crop.y2 > buf->h) {
+               dev_err(dev, "Buffer sanity failed: Crop rect (%d,%d)(%d,%d) outside of %dx%d source buffer\n",
+                       buf_ext->crop.x1, buf_ext->crop.y1,
+                       buf_ext->crop.x2, buf_ext->crop.y2,
+                       buf->w, buf->h);
+               return false;
+       }
+
+       if (buf_ext->display.x1 >= buf_ext->display.x2 ||
+           buf_ext->display.y1 >= buf_ext->display.y2) {
+               dev_err(dev, "Buffer sanity failed: Invalid display rect (%d,%d)(%d,%d)\n",
+                       buf_ext->display.x1, buf_ext->display.y1,
+                       buf_ext->display.x2, buf_ext->display.y2);
+               return false;
+       }
+
+       if (buf_ext->crop.x1 > buf->w ||
+           buf_ext->crop.x2 > buf->w ||
+           buf_ext->crop.y1 > buf->h ||
+           buf_ext->crop.y2 > buf->h) {
+               dev_err(dev, "Buffer sanity failed: Display rect (%d,%d)(%d,%d) outside of %dx%d current interface mode\n",
+                       buf_ext->crop.x1, buf_ext->crop.y1,
+                       buf_ext->crop.x2, buf_ext->crop.y2,
+                       intf->current_mode.hdisplay,
+                       intf->current_mode.vdisplay);
+           return false;
+       }
+
+       switch (buf_ext->transform) {
+       case ADF_BUFFER_TRANSFORM_NONE_EXT:
+       case ADF_BUFFER_TRANSFORM_FLIP_H_EXT:
+       case ADF_BUFFER_TRANSFORM_FLIP_V_EXT:
+       case ADF_BUFFER_TRANSFORM_ROT_90_EXT:
+       case ADF_BUFFER_TRANSFORM_ROT_180_EXT:
+       case ADF_BUFFER_TRANSFORM_ROT_270_EXT:
+               break;
+       default:
+               dev_err(dev, "Invalid transform 0x%x\n", buf_ext->transform);
+               return false;
+       }
+
+       switch (buf_ext->blend_type) {
+       case ADF_BUFFER_BLENDING_NONE_EXT:
+       case ADF_BUFFER_BLENDING_PREMULT_EXT:
+       case ADF_BUFFER_BLENDING_COVERAGE_EXT:
+               break;
+       default:
+               dev_err(dev, "Invalid blend type 0x%x\n", buf_ext->blend_type);
+               return false;
+       }
+       return true;
+}
+
+bool adf_img_rects_intersect(const struct drm_clip_rect *rect1,
+       const struct drm_clip_rect *rect2)
+{
+       if (rect1->x1 < rect2->x2 &&
+           rect1->x2 > rect2->x1 &&
+           rect1->y1 < rect2->y2 &&
+           rect1->y2 > rect2->y1)
+               return true;
+       return false;
+}
+
+
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_common.h
new file mode 100644 (file)
index 0000000..5fddbc8
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#include <video/adf.h>
+#include <adf/adf_ext.h>
+
+long
+adf_img_ioctl(struct adf_obj *obj, unsigned int cmd, unsigned long arg);
+
+/* This validates a post config with a set of assumptions for simple display
+ * engines:
+ * - The config custom data is a struct adf_buffer_config_ext
+ * - There is a single interface with a single overlay attached
+ * - There is a single non-blended layer
+ * - There is a single full-screen buffer
+ * - The buffer is of a format supported by the overlay
+ */
+int
+adf_img_validate_simple(struct adf_device *dev, struct adf_post *cfg,
+       void **driver_state);
+
+/* This does a quick sanity check of the supplied buffer, returns true if it
+ * passes the sanity checks.
+ * The calling driver must still do any device-specific validation
+ * of the buffer arguments.
+ */
+bool
+adf_img_buffer_sanity_check(const struct adf_interface *intf,
+       const struct adf_buffer *buf,
+       const struct adf_buffer_config_ext *buf_ext);
+
+
+/* Returns true if the two clip rects intersect
+ */
+bool
+adf_img_rects_intersect(const struct drm_clip_rect *rect1,
+       const struct drm_clip_rect *rect2);
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_fbdev.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_fbdev.c
new file mode 100644 (file)
index 0000000..f81bb59
--- /dev/null
@@ -0,0 +1,882 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#include <linux/version.h>
+#include <linux/console.h>
+#include <linux/dma-buf.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+
+#include <drm/drm_fourcc.h>
+
+#include <video/adf.h>
+#include <video/adf_fbdev.h>
+#include <video/adf_client.h>
+
+#include <adf/adf_ext.h>
+
+/* for sync_fence_put */
+#include PVR_ANDROID_SYNC_HEADER
+
+#include "adf_common.h"
+
+#ifndef CONFIG_FB
+#error adf_fbdev needs Linux framebuffer support. Enable it in your kernel.
+#endif
+
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("Dual MIT/GPL");
+
+/* NOTE: This is just an example of how to use adf. You should NOT use this
+ *       module in a production environment. It is meaningless to layer adf
+ *       on top of fbdev, as adf is more flexible than fbdev and adf itself
+ *       provides fbdev emulation. Do not use this implementation generally!
+ */
+
+#define DRVNAME "adf_fbdev"
+
+#define FALLBACK_REFRESH_RATE  60
+#define FALLBACK_DPI           160
+
+#if defined(ADF_FBDEV_NUM_PREFERRED_BUFFERS)
+#define NUM_PREFERRED_BUFFERS  ADF_FBDEV_NUM_PREFERRED_BUFFERS
+#else
+#define NUM_PREFERRED_BUFFERS  3
+#endif
+
+struct adf_fbdev_dmabuf {
+       struct sg_table sg_table;
+       unsigned long paddr;
+       size_t offset;
+       size_t length;
+       void *vaddr;
+
+       /* Used for cleanup of dmabuf private data */
+       spinlock_t *alloc_lock;
+       u8 *alloc_mask;
+       u8 id;
+};
+
+struct adf_fbdev_device {
+       struct adf_device base;
+       struct fb_info *fb_info;
+       atomic_t refcount;
+};
+
+struct adf_fbdev_interface {
+       struct adf_interface base;
+       struct drm_mode_modeinfo fb_mode;
+       u16 width_mm, height_mm;
+       struct fb_info *fb_info;
+       spinlock_t alloc_lock;
+       u8 alloc_mask;
+};
+
+/* SIMPLE BUFFER MANAGER *****************************************************/
+
+/* Handle alloc/free from the fbdev carveout (fix.smem_start -> fix.smem_size)
+ * region. This simple allocator sets a bit in the alloc_mask when a buffer is
+ * owned by dmabuf. When the dmabuf ->release() is called, the alloc_mask bit
+ * is cleared and the adf_fbdev_dmabuf object is freed.
+ *
+ * Since dmabuf relies on sg_table/scatterlists, and hence struct page*, this
+ * code may have problems if your framebuffer uses memory that is not in the
+ * kernel's page tables.
+ */
+
+static struct adf_fbdev_dmabuf *
+adf_fbdev_alloc_buffer(struct adf_fbdev_interface *interface)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf;
+       struct scatterlist *sg;
+       size_t unitary_size;
+       int i, err;
+       u32 id = 0;
+
+       spin_lock(&interface->alloc_lock);
+
+       for (id = 0; id < NUM_PREFERRED_BUFFERS; id++) {
+               if (!(interface->alloc_mask & (1UL << id))) {
+                       interface->alloc_mask |= (1UL << id);
+                       break;
+               }
+       }
+
+       spin_unlock(&interface->alloc_lock);
+
+       if (id == NUM_PREFERRED_BUFFERS)
+               return ERR_PTR(-ENOMEM);
+
+       unitary_size = interface->fb_info->fix.line_length *
+                      interface->fb_info->var.yres;
+
+       /* PAGE_SIZE alignment has been checked already, do NOT allow it
+        * through here. We are about to allocate an sg_list.
+        */
+       BUG_ON((unitary_size % PAGE_SIZE) != 0);
+
+       fbdev_dmabuf = kmalloc(sizeof(struct adf_fbdev_dmabuf), GFP_KERNEL);
+       if (!fbdev_dmabuf)
+               return ERR_PTR(-ENOMEM);
+
+       /* We only need one scatterlist entry per buffer because fbdev memory
+        * is always physically contiguous.
+        */
+       err = sg_alloc_table(&fbdev_dmabuf->sg_table, 1, GFP_KERNEL);
+       if (err) {
+               kfree(fbdev_dmabuf);
+               return ERR_PTR(err);
+       }
+
+       /* Increment the reference count of this module as long as the
+        * adb_fbdev_dmabuf object exists. This prevents this module from
+        * being unloaded if the buffer is passed around by dmabuf.
+        */
+       if (!try_module_get(THIS_MODULE)) {
+               pr_err("try_module_get(THIS_MODULE) failed");
+               kfree(fbdev_dmabuf);
+               return ERR_PTR(-EFAULT);
+       }
+
+       fbdev_dmabuf->offset = id * unitary_size;
+       fbdev_dmabuf->length = unitary_size;
+       fbdev_dmabuf->vaddr  = interface->fb_info->screen_base +
+                              fbdev_dmabuf->offset;
+       fbdev_dmabuf->paddr  = interface->fb_info->fix.smem_start +
+                              fbdev_dmabuf->offset;
+
+       sg_set_page(fbdev_dmabuf->sg_table.sgl,
+                   pfn_to_page(PFN_DOWN(fbdev_dmabuf->paddr)),
+                   fbdev_dmabuf->length, 0);
+
+       /* Shadow what ion is doing currently to ensure sg_dma_address() is
+        * valid. This is not strictly correct as the dma address should
+        * only be valid after mapping (ownership changed), and we haven't
+        * mapped the scatter list yet.
+        */
+       for_each_sg(fbdev_dmabuf->sg_table.sgl, sg,
+                   fbdev_dmabuf->sg_table.nents, i) {
+               sg_dma_address(sg) = sg_phys(sg);
+       }
+
+       fbdev_dmabuf->alloc_mask = &interface->alloc_mask;
+       fbdev_dmabuf->alloc_lock = &interface->alloc_lock;
+       fbdev_dmabuf->id         = id;
+
+       return fbdev_dmabuf;
+}
+
+static void adf_fbdev_free_buffer(struct adf_fbdev_dmabuf *fbdev_dmabuf)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(fbdev_dmabuf->alloc_lock, flags);
+       (*fbdev_dmabuf->alloc_mask) &= ~(1UL << fbdev_dmabuf->id);
+       spin_unlock_irqrestore(fbdev_dmabuf->alloc_lock, flags);
+
+       sg_free_table(&fbdev_dmabuf->sg_table);
+       kfree(fbdev_dmabuf);
+
+       module_put(THIS_MODULE);
+}
+
+/* DMA BUF LAYER *************************************************************/
+
+static struct sg_table *
+adf_fbdev_d_map_dma_buf(struct dma_buf_attachment *attachment,
+                       enum dma_data_direction direction)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf = attachment->dmabuf->priv;
+
+       return &fbdev_dmabuf->sg_table;
+}
+
+static void adf_fbdev_d_unmap_dma_buf(struct dma_buf_attachment *attachment,
+                                     struct sg_table *table,
+                                     enum dma_data_direction direction)
+{
+       /* No-op */
+}
+
+static int adf_fbdev_d_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf = dmabuf->priv;
+
+       return remap_pfn_range(vma, vma->vm_start,
+                              PFN_DOWN(fbdev_dmabuf->paddr),
+                              vma->vm_end - vma->vm_start,
+                              vma->vm_page_prot);
+}
+
+static void adf_fbdev_d_release(struct dma_buf *dmabuf)
+{
+       adf_fbdev_free_buffer(dmabuf->priv);
+}
+
+static int
+adf_fbdev_d_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len,
+                            enum dma_data_direction dir)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf = dmabuf->priv;
+
+       if (start + len > fbdev_dmabuf->length)
+               return -EINVAL;
+       return 0;
+}
+
+static void adf_fbdev_d_end_cpu_access(struct dma_buf *dmabuf, size_t start,
+                                      size_t len, enum dma_data_direction dir)
+{
+       /* Framebuffer memory is cache coherent. No-op. */
+}
+
+static void *
+adf_fbdev_d_kmap(struct dma_buf *dmabuf, unsigned long page_offset)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf = dmabuf->priv;
+       void *vaddr;
+
+       if (page_offset * PAGE_SIZE >= fbdev_dmabuf->length)
+               return ERR_PTR(-EINVAL);
+       vaddr = fbdev_dmabuf->vaddr + page_offset * PAGE_SIZE;
+       return vaddr;
+}
+
+static void
+adf_fbdev_d_kunmap(struct dma_buf *dmabuf, unsigned long page_offset,
+                  void *ptr)
+{
+       /* No-op */
+}
+
+static void *adf_fbdev_d_vmap(struct dma_buf *dmabuf)
+{
+       struct adf_fbdev_dmabuf *fbdev_dmabuf = dmabuf->priv;
+
+       return fbdev_dmabuf->vaddr;
+}
+
+static void adf_fbdev_d_vunmap(struct dma_buf *dmabuf, void *vaddr)
+{
+       /* No-op */
+}
+
+static const struct dma_buf_ops adf_fbdev_dma_buf_ops = {
+       .map_dma_buf            = adf_fbdev_d_map_dma_buf,
+       .unmap_dma_buf          = adf_fbdev_d_unmap_dma_buf,
+       .mmap                   = adf_fbdev_d_mmap,
+       .release                = adf_fbdev_d_release,
+       .begin_cpu_access       = adf_fbdev_d_begin_cpu_access,
+       .end_cpu_access         = adf_fbdev_d_end_cpu_access,
+       .kmap_atomic            = adf_fbdev_d_kmap,
+       .kunmap_atomic          = adf_fbdev_d_kunmap,
+       .kmap                   = adf_fbdev_d_kmap,
+       .kunmap                 = adf_fbdev_d_kunmap,
+       .vmap                   = adf_fbdev_d_vmap,
+       .vunmap                 = adf_fbdev_d_vunmap,
+};
+
+/* ADF LAYER *****************************************************************/
+
+static u32 adf_fbdev_supported_format;
+
+static int adf_fbdev_validate(struct adf_device *dev, struct adf_post *cfg,
+                             void **driver_state)
+{
+       int err = adf_img_validate_simple(dev, cfg, driver_state);
+
+       if (cfg->n_bufs == 0 || err != 0)
+               return err;
+
+       /* Everything checked out in the generic validation, but we
+        * additionally want to check that the dmabuf came from the
+        * adf_fbdev module, which the generic code can't check.
+        */
+       if (cfg->bufs[0].dma_bufs[0]->ops != &adf_fbdev_dma_buf_ops)
+               return -EINVAL;
+
+       return 0;
+}
+
+static void adf_fbdev_post(struct adf_device *dev, struct adf_post *cfg,
+                          void *driver_state)
+{
+       struct adf_fbdev_device *device = (struct adf_fbdev_device *)dev;
+       struct fb_var_screeninfo new_var = device->fb_info->var;
+       struct adf_fbdev_dmabuf *fbdev_dmabuf;
+       struct adf_buffer *buffer;
+       int err;
+
+       /* "Null" flip handling */
+       if (cfg->n_bufs == 0)
+               return;
+
+       if (!lock_fb_info(device->fb_info)) {
+               pr_err("Failed to lock fb_info structure.\n");
+               return;
+       }
+
+       console_lock();
+
+       buffer = &cfg->bufs[0];
+       fbdev_dmabuf = buffer->dma_bufs[0]->priv;
+       new_var.yoffset = new_var.yres * fbdev_dmabuf->id;
+
+       /* If we're supposed to be able to flip, but the yres_virtual has been
+        * changed to an unsupported (smaller) value, we need to change it back
+        * (this is a workaround for some Linux fbdev drivers that seem to lose
+        * any modifications to yres_virtual after a blank.)
+        */
+       if (new_var.yres_virtual < new_var.yres * NUM_PREFERRED_BUFFERS) {
+               new_var.activate = FB_ACTIVATE_NOW;
+               new_var.yres_virtual = new_var.yres * NUM_PREFERRED_BUFFERS;
+
+               err = fb_set_var(device->fb_info, &new_var);
+               if (err)
+                       pr_err("fb_set_var failed (err=%d)\n", err);
+       } else {
+               err = fb_pan_display(device->fb_info, &new_var);
+               if (err)
+                       pr_err("fb_pan_display failed (err=%d)\n", err);
+       }
+
+       console_unlock();
+
+       unlock_fb_info(device->fb_info);
+}
+
+static int
+adf_fbdev_open2(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       struct adf_fbdev_device *dev =
+               (struct adf_fbdev_device *)obj->parent;
+       atomic_inc(&dev->refcount);
+       return 0;
+}
+
+static void
+adf_fbdev_release2(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       struct adf_fbdev_device *dev =
+               (struct adf_fbdev_device *)obj->parent;
+       struct sync_fence *release_fence;
+
+       if (atomic_dec_return(&dev->refcount))
+               return;
+
+       /* This special "null" flip works around a problem with ADF
+        * which leaves buffers pinned by the display engine even
+        * after all ADF clients have closed.
+        *
+        * The "null" flip is pipelined like any other. The user won't
+        * be able to unload this module until it has been posted.
+        */
+       release_fence = adf_device_post(&dev->base, NULL, 0, NULL, 0, NULL, 0);
+       if (IS_ERR_OR_NULL(release_fence)) {
+               pr_err("Failed to queue null flip command (err=%d).\n",
+                      (int)PTR_ERR(release_fence));
+               return;
+       }
+
+       sync_fence_put(release_fence);
+}
+
+static const struct adf_device_ops adf_fbdev_device_ops = {
+       .owner                  = THIS_MODULE,
+       .base = {
+               .open           = adf_fbdev_open2,
+               .release        = adf_fbdev_release2,
+               .ioctl          = adf_img_ioctl,
+       },
+       .validate               = adf_fbdev_validate,
+       .post                   = adf_fbdev_post,
+};
+
+static bool
+adf_fbdev_supports_event(struct adf_obj *obj, enum adf_event_type type)
+{
+       switch (type) {
+       case ADF_EVENT_VSYNC:
+       case ADF_EVENT_HOTPLUG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static void
+adf_fbdev_set_event(struct adf_obj *obj, enum adf_event_type type,
+                   bool enabled)
+{
+       switch (type) {
+       case ADF_EVENT_VSYNC:
+       case ADF_EVENT_HOTPLUG:
+               break;
+       default:
+               BUG();
+       }
+}
+
+static int adf_fbdev_blank2(struct adf_interface *intf, u8 state)
+{
+       struct adf_fbdev_interface *interface =
+               (struct adf_fbdev_interface *)intf;
+       struct fb_info *fb_info = interface->fb_info;
+
+       if (!fb_info->fbops->fb_blank)
+               return -EOPNOTSUPP;
+
+       return fb_info->fbops->fb_blank(state, fb_info);
+}
+
+static int
+adf_fbdev_alloc_simple_buffer(struct adf_interface *intf, u16 w, u16 h,
+                             u32 format, struct dma_buf **dma_buf,
+                             u32 *offset, u32 *pitch)
+{
+       struct adf_fbdev_interface *interface =
+               (struct adf_fbdev_interface *)intf;
+       struct fb_var_screeninfo *var = &interface->fb_info->var;
+       struct adf_fbdev_dmabuf *fbdev_dmabuf;
+
+       if (w != var->xres) {
+               pr_err("Simple alloc request w=%u does not match w=%u.\n",
+                      w, var->xres);
+               return -EINVAL;
+       }
+
+       if (h != var->yres) {
+               pr_err("Simple alloc request h=%u does not match h=%u.\n",
+                      h, var->yres);
+               return -EINVAL;
+       }
+
+       if (format != adf_fbdev_supported_format) {
+               pr_err("Simple alloc request f=0x%x does not match f=0x%x.\n",
+                      format, adf_fbdev_supported_format);
+               return -EINVAL;
+       }
+
+       fbdev_dmabuf = adf_fbdev_alloc_buffer(interface);
+       if (IS_ERR_OR_NULL(fbdev_dmabuf))
+               return PTR_ERR(fbdev_dmabuf);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+       {
+               DEFINE_DMA_BUF_EXPORT_INFO(export_info);
+
+               export_info.ops = &adf_fbdev_dma_buf_ops;
+               export_info.size = fbdev_dmabuf->length;
+               export_info.flags = O_RDWR;
+               export_info.priv = fbdev_dmabuf;
+
+               *dma_buf = dma_buf_export(&export_info);
+       }
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
+      defined(CONFIG_ARCH_MT8173)
+       *dma_buf = dma_buf_export(fbdev_dmabuf, &adf_fbdev_dma_buf_ops,
+                                 fbdev_dmabuf->length, O_RDWR, NULL);
+#else
+       *dma_buf = dma_buf_export(fbdev_dmabuf, &adf_fbdev_dma_buf_ops,
+                                 fbdev_dmabuf->length, O_RDWR);
+#endif
+       if (IS_ERR(*dma_buf)) {
+               adf_fbdev_free_buffer(fbdev_dmabuf);
+               return PTR_ERR(*dma_buf);
+       }
+
+       *pitch = interface->fb_info->fix.line_length;
+       *offset = 0;
+       return 0;
+}
+
+static int
+adf_fbdev_screen_size(struct adf_interface *intf, u16 *width_mm,
+                     u16 *height_mm)
+{
+       struct adf_fbdev_interface *interface =
+               (struct adf_fbdev_interface *)intf;
+       *width_mm  = interface->width_mm;
+       *height_mm = interface->height_mm;
+       return 0;
+}
+
+static int adf_fbdev_modeset(struct adf_interface *intf,
+                            struct drm_mode_modeinfo *mode)
+{
+       struct adf_fbdev_interface *interface =
+               (struct adf_fbdev_interface *)intf;
+       return mode == &interface->fb_mode ? 0 : -EINVAL;
+}
+
+static const struct adf_interface_ops adf_fbdev_interface_ops = {
+       .base = {
+               .supports_event = adf_fbdev_supports_event,
+               .set_event      = adf_fbdev_set_event,
+       },
+       .blank                  = adf_fbdev_blank2,
+       .alloc_simple_buffer    = adf_fbdev_alloc_simple_buffer,
+       .screen_size            = adf_fbdev_screen_size,
+       .modeset                = adf_fbdev_modeset,
+};
+
+struct adf_overlay_engine_ops adf_fbdev_overlay_engine_ops = {
+       .supported_formats      = &adf_fbdev_supported_format,
+       .n_supported_formats    = 1,
+};
+
+/* If we can flip, we need to make sure we have the memory to do so.
+ *
+ * We'll assume that the fbdev device provides extra space in
+ * yres_virtual for panning; xres_virtual is theoretically supported,
+ * but it involves more work.
+ *
+ * If the fbdev device doesn't have yres_virtual > yres, we'll try
+ * requesting it before bailing. Userspace applications commonly do
+ * this with an FBIOPUT_VSCREENINFO ioctl().
+ *
+ * Another problem is with a limitation in PowerVR services -- it
+ * needs framebuffers to be page aligned (this is a SW limitation,
+ * the HW can support non-page-aligned buffers). So we have to
+ * check that stride * height for a single buffer is page aligned.
+ */
+static bool adf_fbdev_flip_possible(struct fb_info *fb_info)
+{
+       struct fb_var_screeninfo var = fb_info->var;
+       int err;
+
+       if (!fb_info->fix.xpanstep && !fb_info->fix.ypanstep &&
+           !fb_info->fix.ywrapstep) {
+               pr_err("The fbdev device detected does not support ypan/ywrap.\n");
+               return false;
+       }
+
+       if ((fb_info->fix.line_length * var.yres) % PAGE_SIZE != 0) {
+               pr_err("Line length (in bytes) x yres is not a multiple of page size.\n");
+               return false;
+       }
+
+       /* We might already have enough space */
+       if (var.yres * NUM_PREFERRED_BUFFERS <= var.yres_virtual)
+               return true;
+
+       pr_err("No buffer space for flipping; asking for more.\n");
+
+       var.activate = FB_ACTIVATE_NOW;
+       var.yres_virtual = var.yres * NUM_PREFERRED_BUFFERS;
+
+       err = fb_set_var(fb_info, &var);
+       if (err) {
+               pr_err("fb_set_var failed (err=%d).\n", err);
+               return false;
+       }
+
+       if (var.yres * NUM_PREFERRED_BUFFERS > var.yres_virtual) {
+               pr_err("Failed to obtain additional buffer space.\n");
+               return false;
+       }
+
+       /* Some fbdev drivers allow the yres_virtual modification through,
+        * but don't actually update the fix. We need the fix to be updated
+        * and more memory allocated, so we can actually take advantage of
+        * the increased yres_virtual.
+        */
+       if (fb_info->fix.smem_len < fb_info->fix.line_length *
+                                   var.yres_virtual) {
+               pr_err("'fix' not re-allocated with sufficient buffer space.\n");
+               pr_err("Check NUM_PREFERRED_BUFFERS (%u) is as intended.\n",
+                      NUM_PREFERRED_BUFFERS);
+               return false;
+       }
+
+       return true;
+}
+
+/* Could use devres here? */
+static struct {
+       struct adf_fbdev_device         device;
+       struct adf_fbdev_interface      interface;
+       struct adf_overlay_engine       engine;
+} dev_data;
+
+static int __init init_adf_fbdev(void)
+{
+       struct drm_mode_modeinfo *mode = &dev_data.interface.fb_mode;
+       char format_str[ADF_FORMAT_STR_SIZE];
+       struct fb_info *fb_info;
+       int err = -ENODEV;
+
+       fb_info = registered_fb[0];
+       if (!fb_info) {
+               pr_err("No Linux framebuffer (fbdev) device is registered!\n");
+               pr_err("Check you have a framebuffer driver compiled into your kernel\n");
+               pr_err("and that it is enabled on the cmdline.\n");
+               goto err_out;
+       }
+
+       if (!lock_fb_info(fb_info))
+               goto err_out;
+
+       console_lock();
+
+       /* Filter out broken FB devices */
+       if (!fb_info->fix.smem_len || !fb_info->fix.line_length) {
+               pr_err("The fbdev device detected had a zero smem_len or line_length,\n");
+               pr_err("which suggests it is a broken driver.\n");
+               goto err_unlock;
+       }
+
+       if (fb_info->fix.type != FB_TYPE_PACKED_PIXELS ||
+           fb_info->fix.visual != FB_VISUAL_TRUECOLOR) {
+               pr_err("The fbdev device detected is not truecolor with packed pixels.\n");
+               goto err_unlock;
+       }
+
+       if (fb_info->var.bits_per_pixel == 32) {
+               if (fb_info->var.red.length   != 8  ||
+                   fb_info->var.green.length != 8  ||
+                   fb_info->var.blue.length  != 8  ||
+                   fb_info->var.red.offset   != 16 ||
+                   fb_info->var.green.offset != 8  ||
+                   fb_info->var.blue.offset  != 0) {
+                       pr_err("The fbdev device detected uses an unrecognized 32bit pixel format (%u/%u/%u, %u/%u/%u)\n",
+                              fb_info->var.red.length,
+                              fb_info->var.green.length,
+                              fb_info->var.blue.length,
+                              fb_info->var.red.offset,
+                              fb_info->var.green.offset,
+                              fb_info->var.blue.offset);
+                       goto err_unlock;
+               }
+#if defined(ADF_FBDEV_FORCE_XRGB8888)
+               adf_fbdev_supported_format = DRM_FORMAT_BGRX8888;
+#else
+               adf_fbdev_supported_format = DRM_FORMAT_BGRA8888;
+#endif
+       } else if (fb_info->var.bits_per_pixel == 16) {
+               if (fb_info->var.red.length   != 5  ||
+                   fb_info->var.green.length != 6  ||
+                   fb_info->var.blue.length  != 5  ||
+                   fb_info->var.red.offset   != 11 ||
+                   fb_info->var.green.offset != 5  ||
+                   fb_info->var.blue.offset  != 0) {
+                       pr_err("The fbdev device detected uses an unrecognized 16bit pixel format (%u/%u/%u, %u/%u/%u)\n",
+                              fb_info->var.red.length,
+                              fb_info->var.green.length,
+                              fb_info->var.blue.length,
+                              fb_info->var.red.offset,
+                              fb_info->var.green.offset,
+                              fb_info->var.blue.offset);
+                       goto err_unlock;
+               }
+               adf_fbdev_supported_format = DRM_FORMAT_BGR565;
+       } else {
+               pr_err("The fbdev device detected uses an unsupported bpp (%u).\n",
+                      fb_info->var.bits_per_pixel);
+               goto err_unlock;
+       }
+
+       if (!try_module_get(fb_info->fbops->owner)) {
+               pr_err("try_module_get() failed");
+               goto err_unlock;
+       }
+
+       if (fb_info->fbops->fb_open &&
+           fb_info->fbops->fb_open(fb_info, 0) != 0) {
+               pr_err("fb_open() failed");
+               goto err_module_put;
+       }
+
+       if (!adf_fbdev_flip_possible(fb_info)) {
+               pr_err("Flipping must be supported for ADF. Aborting.\n");
+               goto err_fb_release;
+       }
+
+       err = adf_device_init(&dev_data.device.base, fb_info->dev,
+                             &adf_fbdev_device_ops, "fbdev");
+       if (err) {
+               pr_err("adf_device_init failed (%d)", err);
+               goto err_fb_release;
+       }
+
+       dev_data.device.fb_info = fb_info;
+
+       err = adf_interface_init(&dev_data.interface.base,
+                                &dev_data.device.base,
+                                ADF_INTF_DVI, 0, ADF_INTF_FLAG_PRIMARY,
+                                &adf_fbdev_interface_ops, "fbdev_interface");
+       if (err) {
+               pr_err("adf_interface_init failed (%d)", err);
+               goto err_device_destroy;
+       }
+
+       spin_lock_init(&dev_data.interface.alloc_lock);
+       dev_data.interface.fb_info = fb_info;
+
+       /* If the fbdev mode looks viable, try to inherit from it */
+       if (fb_info->mode)
+               adf_modeinfo_from_fb_videomode(fb_info->mode, mode);
+
+       /* Framebuffer drivers aren't always very good at filling out their
+        * mode information, so fake up anything that's missing so we don't
+        * need to accommodate it in userspace.
+        */
+
+       if (!mode->hdisplay)
+               mode->hdisplay = fb_info->var.xres;
+       if (!mode->vdisplay)
+               mode->vdisplay = fb_info->var.yres;
+       if (!mode->vrefresh)
+               mode->vrefresh = FALLBACK_REFRESH_RATE;
+
+       if (fb_info->var.width > 0 && fb_info->var.width < 1000) {
+               dev_data.interface.width_mm = fb_info->var.width;
+       } else {
+               dev_data.interface.width_mm = (fb_info->var.xres * 25400) /
+                                             (FALLBACK_DPI * 1000);
+       }
+
+       if (fb_info->var.height > 0 && fb_info->var.height < 1000) {
+               dev_data.interface.height_mm = fb_info->var.height;
+       } else {
+               dev_data.interface.height_mm = (fb_info->var.yres * 25400) /
+                                              (FALLBACK_DPI * 1000);
+       }
+
+       err = adf_hotplug_notify_connected(&dev_data.interface.base, mode, 1);
+       if (err) {
+               pr_err("adf_hotplug_notify_connected failed (%d)", err);
+               goto err_interface_destroy;
+       }
+
+       /* This doesn't really set the mode, it just updates current_mode */
+       err = adf_interface_set_mode(&dev_data.interface.base, mode);
+       if (err) {
+               pr_err("adf_interface_set_mode failed (%d)", err);
+               goto err_interface_destroy;
+       }
+
+       err = adf_overlay_engine_init(&dev_data.engine, &dev_data.device.base,
+                                     &adf_fbdev_overlay_engine_ops,
+                                     "fbdev_overlay_engine");
+       if (err) {
+               pr_err("adf_overlay_engine_init failed (%d)", err);
+               goto err_interface_destroy;
+       }
+
+       err = adf_attachment_allow(&dev_data.device.base,
+                                  &dev_data.engine,
+                                  &dev_data.interface.base);
+
+       if (err) {
+               pr_err("adf_attachment_allow failed (%d)", err);
+               goto err_overlay_engine_destroy;
+       }
+
+       adf_format_str(adf_fbdev_supported_format, format_str);
+       pr_info("Found usable fbdev device (%s):\n"
+               "range (physical) = 0x%lx-0x%lx\n"
+               "range (virtual)  = %p-%p\n"
+               "size (bytes)     = 0x%x\n"
+               "xres x yres      = %ux%u\n"
+               "xres x yres (v)  = %ux%u\n"
+               "physical (mm)    = %ux%u\n"
+               "refresh (Hz)     = %u\n"
+               "drm fourcc       = %s (0x%x)\n",
+               fb_info->fix.id,
+               fb_info->fix.smem_start,
+               fb_info->fix.smem_start + fb_info->fix.smem_len,
+               fb_info->screen_base,
+               fb_info->screen_base + fb_info->screen_size,
+               fb_info->fix.smem_len,
+               mode->hdisplay, mode->vdisplay,
+               fb_info->var.xres_virtual, fb_info->var.yres_virtual,
+               dev_data.interface.width_mm, dev_data.interface.height_mm,
+               mode->vrefresh,
+               format_str, adf_fbdev_supported_format);
+       err = 0;
+err_unlock:
+       console_unlock();
+       unlock_fb_info(fb_info);
+err_out:
+       return err;
+err_overlay_engine_destroy:
+       adf_overlay_engine_destroy(&dev_data.engine);
+err_interface_destroy:
+       adf_interface_destroy(&dev_data.interface.base);
+err_device_destroy:
+       adf_device_destroy(&dev_data.device.base);
+err_fb_release:
+       if (fb_info->fbops->fb_release)
+               fb_info->fbops->fb_release(fb_info, 0);
+err_module_put:
+       module_put(fb_info->fbops->owner);
+       goto err_unlock;
+}
+
+static void __exit exit_adf_fbdev(void)
+{
+       struct fb_info *fb_info = dev_data.device.fb_info;
+
+       if (!lock_fb_info(fb_info)) {
+               pr_err("Failed to lock fb_info.\n");
+               return;
+       }
+
+       console_lock();
+
+       adf_overlay_engine_destroy(&dev_data.engine);
+       adf_interface_destroy(&dev_data.interface.base);
+       adf_device_destroy(&dev_data.device.base);
+
+       if (fb_info->fbops->fb_release)
+               fb_info->fbops->fb_release(fb_info, 0);
+
+       module_put(fb_info->fbops->owner);
+
+       console_unlock();
+       unlock_fb_info(fb_info);
+}
+
+module_init(init_adf_fbdev);
+module_exit(exit_adf_fbdev);
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_pdp.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_pdp.c
new file mode 100644 (file)
index 0000000..7fe1646
--- /dev/null
@@ -0,0 +1,1192 @@
+/*************************************************************************/ /*!
+@File           adf_pdp.c
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+/*
+ * This is an example ADF display driver for the testchip's PDP output
+ */
+
+/* #define SUPPORT_ADF_PDP_FBDEV */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+
+#include <drm/drm_fourcc.h>
+
+#include <video/adf.h>
+#include <video/adf_client.h>
+
+#ifdef SUPPORT_ADF_PDP_FBDEV
+#include <video/adf_fbdev.h>
+#endif
+
+#include PVR_ANDROID_ION_HEADER
+
+/* for sync_fence_put */
+#include PVR_ANDROID_SYNC_HEADER
+
+#include "apollo_drv.h"
+#include "adf_common.h"
+
+#include "pdp_regs.h"
+#include "tcf_rgbpdp_regs.h"
+#include "tcf_pll.h"
+
+#include "pvrmodule.h"
+
+#define DRV_NAME APOLLO_DEVICE_NAME_PDP
+
+MODULE_DESCRIPTION("APOLLO PDP display driver");
+
+static int pdp_display_width = ADF_PDP_WIDTH;
+static int pdp_display_height = ADF_PDP_HEIGHT;
+module_param(pdp_display_width, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(pdp_display_width, "PDP display width");
+module_param(pdp_display_height, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(pdp_display_height, "PDP display height");
+
+static DEFINE_SPINLOCK(gFlipLock);
+
+struct pdp_timing_data {
+       u32 h_display;
+       u32 h_back_porch;
+       u32 h_total;
+       u32 h_active_start;
+       u32 h_left_border;
+       u32 h_right_border;
+       u32 h_front_porch;
+
+       u32 v_display;
+       u32 v_back_porch;
+       u32 v_total;
+       u32 v_active_start;
+       u32 v_top_border;
+       u32 v_bottom_border;
+       u32 v_front_porch;
+       u32 v_refresh;
+       u32 clock_freq;
+};
+
+static const struct pdp_timing_data pdp_supported_modes[] = {
+       {
+               .h_display              =       640,
+               .h_back_porch           =       64,
+               .h_total                =       800,
+               .h_active_start         =       144,
+               .h_left_border          =       144,
+               .h_right_border         =       784,
+               .h_front_porch          =       784,
+
+               .v_display              =       480,
+               .v_back_porch           =       7,
+               .v_total                =       497,
+               .v_active_start         =       16,
+               .v_top_border           =       16,
+               .v_bottom_border        =       496,
+               .v_front_porch          =       496,
+
+               .v_refresh              =       60,
+               .clock_freq             =       23856000,
+       },
+       {
+               .h_display              =       800,
+               .h_back_porch           =       80,
+               .h_total                =       1024,
+               .h_active_start         =       192,
+               .h_left_border          =       192,
+               .h_right_border         =       992,
+               .h_front_porch          =       992,
+
+               .v_display              =       600,
+               .v_back_porch           =       7,
+               .v_total                =       621,
+               .v_active_start         =       20,
+               .v_top_border           =       20,
+               .v_bottom_border        =       620,
+               .v_front_porch          =       620,
+
+               .v_refresh              =       60,
+               .clock_freq             =       38154000,
+       },
+       {
+               .h_display              =       1024,
+               .h_back_porch           =       104,
+               .h_total                =       1344,
+               .h_active_start         =       264,
+               .h_left_border          =       264,
+               .h_right_border         =       1288,
+               .h_front_porch          =       1288,
+
+               .v_display              =       768,
+               .v_back_porch           =       7,
+               .v_total                =       795,
+               .v_active_start         =       26,
+               .v_top_border           =       26,
+               .v_bottom_border        =       794,
+               .v_front_porch          =       794,
+
+               .v_refresh              =       59,
+               .clock_freq             =       64108000,
+       },
+       {
+               .h_display              =       1280,
+               .h_back_porch           =       136,
+               .h_total                =       1664,
+               .h_active_start         =       328,
+               .h_left_border          =       328,
+               .h_right_border         =       1608,
+               .h_front_porch          =       1608,
+
+               .v_display              =       720,
+               .v_back_porch           =       7,
+               .v_total                =       745,
+               .v_active_start         =       24,
+               .v_top_border           =       24,
+               .v_bottom_border        =       744,
+               .v_front_porch          =       744,
+
+               .v_refresh              =       59,
+               .clock_freq             =       74380000,
+       },
+       {
+               .h_display              =       1280,
+               .h_back_porch           =       136,
+               .h_total                =       1680,
+               .h_active_start         =       336,
+               .h_left_border          =       336,
+               .h_right_border         =       1616,
+               .h_front_porch          =       1616,
+
+               .v_display              =       768,
+               .v_back_porch           =       7,
+               .v_total                =       795,
+               .v_active_start         =       26,
+               .v_top_border           =       26,
+               .v_bottom_border        =       794,
+               .v_front_porch          =       794,
+
+               .v_refresh              =       59,
+               .clock_freq             =       80136000,
+       },
+       {
+               .h_display              =       1280,
+               .h_back_porch           =       136,
+               .h_total                =       1680,
+               .h_active_start         =       336,
+               .h_left_border          =       336,
+               .h_right_border         =       1616,
+               .h_front_porch          =       1616,
+
+               .v_display              =       800,
+               .v_back_porch           =       7,
+               .v_total                =       828,
+               .v_active_start         =       27,
+               .v_top_border           =       27,
+               .v_bottom_border        =       827,
+               .v_front_porch          =       827,
+
+               .v_refresh              =       59,
+               .clock_freq             =       83462000,
+       },
+       {
+               .h_display              =       1280,
+               .h_back_porch           =       136,
+               .h_total                =       1712,
+               .h_active_start         =       352,
+               .h_left_border          =       352,
+               .h_right_border         =       1632,
+               .h_front_porch          =       1632,
+
+               .v_display              =       1024,
+               .v_back_porch           =       7,
+               .v_total                =       1059,
+               .v_active_start         =       34,
+               .v_top_border           =       34,
+               .v_bottom_border        =       1058,
+               .v_front_porch          =       1058,
+
+               .v_refresh              =       60,
+               .clock_freq             =       108780000,
+       },
+       {}
+};
+
+
+struct adf_pdp_device {
+       struct ion_client *ion_client;
+
+       struct adf_device adf_device;
+       struct adf_interface adf_interface;
+       struct adf_overlay_engine adf_overlay;
+#ifdef SUPPORT_ADF_PDP_FBDEV
+       struct adf_fbdev adf_fbdev;
+#endif
+
+       struct platform_device *pdev;
+
+       struct apollo_pdp_platform_data *pdata;
+
+       void __iomem *regs;
+       resource_size_t regs_size;
+       resource_size_t regs_start;
+
+       void __iomem *pll_regs;
+       resource_size_t pll_regs_size;
+       resource_size_t pll_regs_start;
+
+       struct drm_mode_modeinfo *supported_modes;
+       int num_supported_modes;
+
+       const struct pdp_timing_data *current_timings;
+
+       atomic_t refcount;
+
+       atomic_t num_validates;
+       int num_posts;
+
+       atomic_t vsync_triggered;
+       wait_queue_head_t vsync_wait_queue;
+       atomic_t requested_vsync_state;
+       atomic_t vsync_state;
+
+       struct {
+               u32 str1surf;
+               u32 str1posn;
+               u32 str1addrctrl;
+       } flip_registers;
+};
+
+static const u32 pdp_supported_formats[] = {
+       DRM_FORMAT_BGRA8888,
+};
+#define NUM_SUPPORTED_FORMATS 1
+
+static const struct {
+       u32 drm_format;
+       u32 bytes_per_pixel;
+       u32 pixfmt_word;
+} pdp_format_table[] = {
+       { DRM_FORMAT_BGRA8888, 4, DCPDP_STR1SURF_FORMAT_ARGB8888 },
+       {},
+};
+
+static int pdp_mode_count(struct adf_pdp_device *pdp)
+{
+       int i = 0;
+       while (pdp_supported_modes[i].h_display)
+               i++;
+       return i;
+}
+
+static int pdp_mode_id(struct adf_pdp_device *pdp, u32 height, u32 width)
+{
+       int i;
+       for (i = 0; pdp_supported_modes[i].h_display; i++) {
+               const struct pdp_timing_data *tdata = &pdp_supported_modes[i];
+               if (tdata->h_display == width && tdata->v_display == height)
+                       return i;
+       }
+       dev_err(&pdp->pdev->dev, "Failed to find matching mode for %dx%d\n",
+               width, height);
+       return -1;
+}
+
+static const struct pdp_timing_data *pdp_timing_data(
+       struct adf_pdp_device *pdp, int mode_id)
+{
+       if (mode_id >= pdp_mode_count(pdp) || mode_id < 0)
+               return NULL;
+       return &pdp_supported_modes[mode_id];
+}
+
+static void pdp_mode_to_drm_mode(struct adf_pdp_device *pdp, int mode_id,
+       struct drm_mode_modeinfo *drm_mode)
+{
+       const struct pdp_timing_data *pdp_mode = pdp_timing_data(pdp, mode_id);
+
+       BUG_ON(pdp_mode == NULL);
+       memset(drm_mode, 0, sizeof(*drm_mode));
+
+       drm_mode->hdisplay = pdp_mode->h_display;
+       drm_mode->vdisplay = pdp_mode->v_display;
+       drm_mode->vrefresh = pdp_mode->v_refresh;
+
+       adf_modeinfo_set_name(drm_mode);
+}
+
+static u32 pdp_read_reg(struct adf_pdp_device *pdp, resource_size_t reg_offset)
+{
+       BUG_ON(reg_offset > pdp->regs_size-4);
+       return ioread32(pdp->regs + reg_offset);
+}
+
+static void pdp_write_reg(struct adf_pdp_device *pdp,
+       resource_size_t reg_offset, u32 reg_value)
+{
+       BUG_ON(reg_offset > pdp->regs_size-4);
+       iowrite32(reg_value, pdp->regs + reg_offset);
+}
+
+static void pll_write_reg(struct adf_pdp_device *pdp,
+       resource_size_t reg_offset, u32 reg_value)
+{
+       BUG_ON(reg_offset > pdp->pll_regs_size-4);
+       iowrite32(reg_value, pdp->pll_regs + reg_offset);
+}
+
+static void pdp_devres_release(struct device *dev, void *res)
+{
+       /* No extra cleanup needed */
+}
+
+static int request_pci_io_addr(struct pci_dev *dev, u32 index,
+       resource_size_t offset, resource_size_t length)
+{
+       resource_size_t start, end;
+       start = pci_resource_start(dev, index);
+       end = pci_resource_end(dev, index);
+
+       if ((start + offset + length - 1) > end)
+               return -EIO;
+       if (pci_resource_flags(dev, index) & IORESOURCE_IO) {
+               if (request_region(start + offset, length, DRV_NAME) == NULL)
+                       return -EIO;
+       } else {
+               if (request_mem_region(start + offset, length, DRV_NAME)
+                       == NULL)
+                       return -EIO;
+       }
+       return 0;
+}
+
+static void release_pci_io_addr(struct pci_dev *dev, u32 index,
+       resource_size_t start, resource_size_t length)
+{
+       if (pci_resource_flags(dev, index) & IORESOURCE_IO)
+               release_region(start, length);
+       else
+               release_mem_region(start, length);
+}
+
+
+#ifdef SUPPORT_ADF_PDP_FBDEV
+static u32 pdp_format_bpp(u32 drm_format)
+{
+       int i;
+       for (i = 0; pdp_format_table[i].drm_format != 0; i++) {
+               if (pdp_format_table[i].drm_format == drm_format)
+                       return pdp_format_table[i].bytes_per_pixel;
+       }
+       WARN(1, "Unsupported drm format");
+       return 0;
+}
+#endif /* SUPPORT_ADF_PDP_FBDDEV */
+
+static u32 pdp_format(u32 drm_format)
+{
+       int i;
+       for (i = 0; pdp_format_table[i].drm_format != 0; i++) {
+               if (pdp_format_table[i].drm_format == drm_format)
+                       return pdp_format_table[i].pixfmt_word;
+       }
+       WARN(1, "Unsupported drm format");
+       return 0;
+}
+
+static void pdp_enable_scanout(struct adf_pdp_device *pdp)
+{
+       u32 reg_value;
+       /* Turn on scanout */
+       reg_value = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL);
+       reg_value &= ~(STR1STREN_MASK);
+       reg_value |= 0x1 << STR1STREN_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL, reg_value);
+}
+
+static void pdp_disable_scanout(struct adf_pdp_device *pdp)
+{
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL, 0);
+}
+
+static bool pdp_vsync_triggered(struct adf_pdp_device *pdp)
+{
+       return atomic_read(&pdp->vsync_triggered) == 1;
+}
+
+static void pdp_enable_vsync(struct adf_pdp_device *pdp)
+{
+       int err = 0;
+       u32 reg_value = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB);
+       reg_value |= (0x1 << INTEN_VBLNK1_SHIFT);
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB, reg_value);
+
+       err = apollo_enable_interrupt(&pdp->pdata->pdev->dev,
+               APOLLO_INTERRUPT_PDP);
+       if (err) {
+               dev_err(&pdp->pdev->dev,
+                       "apollo_enable_interrupt failed (%d)\n", err);
+       }
+}
+
+static void pdp_disable_vsync(struct adf_pdp_device *pdp)
+{
+       int err = 0;
+       u32 reg_value = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB);
+       reg_value &= ~(0x1 << INTEN_VBLNK1_SHIFT);
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB, reg_value);
+
+       err = apollo_disable_interrupt(&pdp->pdata->pdev->dev,
+               APOLLO_INTERRUPT_PDP);
+       if (err) {
+               dev_err(&pdp->pdev->dev,
+                       "apollo_disable_interrupt failed (%d)\n", err);
+       }
+}
+
+static void pdp_post(struct adf_device *adf_dev, struct adf_post *cfg,
+       void *driver_state)
+{
+       int num_validates_snapshot = *(int *)driver_state;
+       dma_addr_t buf_addr;
+       u32 reg_value = 0;
+       unsigned long flags;
+
+       /* Set vsync wait timeout to 4x expected vsync */
+       struct adf_pdp_device *pdp = devres_find(adf_dev->dev,
+               pdp_devres_release, NULL, NULL);
+       long timeout =
+               msecs_to_jiffies((1000 / pdp->current_timings->v_refresh) * 4);
+
+       /* Null-flip handling, used to push buffers off screen during an error
+        * state to stop them blocking subsequent rendering */
+       if (cfg->n_bufs == 0) {
+               pdp_disable_scanout(pdp);
+               return;
+       }
+
+       WARN_ON(cfg->n_bufs != 1);
+       WARN_ON(cfg->mappings->sg_tables[0]->nents != 1);
+
+       spin_lock_irqsave(&gFlipLock, flags);
+
+       buf_addr = sg_phys(cfg->mappings->sg_tables[0]->sgl);
+       /* Convert the cpu address to a device address */
+       buf_addr -= pdp->pdata->apollo_memory_base;
+
+       /* Set surface register w/height, width & format */
+       reg_value  = (cfg->bufs[0].w-1) << STR1WIDTH_SHIFT;
+       reg_value |= (cfg->bufs[0].h-1) << STR1HEIGHT_SHIFT;
+       reg_value |= pdp_format(cfg->bufs[0].format) << STR1PIXFMT_SHIFT;
+       pdp->flip_registers.str1surf = reg_value;
+
+       /* Set stride register */
+       reg_value = (cfg->bufs[0].pitch[0] >> DCPDP_STR1POSN_STRIDE_SHIFT)-1;
+       pdp->flip_registers.str1posn = reg_value;
+
+       /* Set surface address without resetting any other bits in the
+        * register */
+       reg_value  = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL);
+       reg_value &= ~(STR1BASE_MASK);
+       reg_value |= (buf_addr >> DCPDP_STR1ADDRCTRL_BASE_ADDR_SHIFT)
+               & STR1BASE_MASK;
+
+       pdp->flip_registers.str1addrctrl = reg_value;
+       atomic_set(&pdp->vsync_triggered, 0);
+
+       spin_unlock_irqrestore(&gFlipLock, flags);
+
+       /* Wait until the buffer is on-screen, so we know the previous buffer
+        * has been retired and off-screen.
+        *
+        * If vsync was already off when this post was serviced, we need to
+        * enable the vsync again briefly so the register updates we shadowed
+        * above get applied and we don't signal the fence prematurely. One
+        * vsync afterwards, we'll disable the vsync again.
+        */
+       if (!atomic_xchg(&pdp->vsync_state, 1))
+               pdp_enable_vsync(pdp);
+
+       if (wait_event_timeout(pdp->vsync_wait_queue,
+               pdp_vsync_triggered(pdp), timeout) == 0) {
+               dev_err(&pdp->pdev->dev, "Post VSync wait timeout");
+               /* Undefined behaviour if this times out */
+       }
+
+       pdp->num_posts = num_validates_snapshot;
+}
+
+static bool pdp_supports_event(struct adf_obj *obj, enum adf_event_type type)
+{
+       switch (obj->type) {
+       case ADF_OBJ_INTERFACE:
+       {
+               switch (type) {
+               case ADF_EVENT_VSYNC:
+                       return true;
+               default:
+                       return false;
+               }
+       }
+       default:
+               return false;
+       }
+}
+
+static void pdp_irq_handler(void *data)
+{
+       struct adf_pdp_device *pdp = data;
+       unsigned long flags;
+       u32 int_status = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTSTAT);
+
+       if (int_status & INTS_VBLNK1_MASK)
+               pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_INTCLEAR,
+                       (0x1 << INTCLR_VBLNK1_SHIFT));
+
+       spin_lock_irqsave(&gFlipLock, flags);
+
+       /* If we're idle, and a vsync disable was requested, do it now.
+        * This code assumes that the HWC will always re-enable vsync
+        * explicitly before posting new configurations.
+        */
+       if (atomic_read(&pdp->num_validates) == pdp->num_posts) {
+               if (!atomic_read(&pdp->requested_vsync_state)) {
+                       pdp_disable_vsync(pdp);
+                       atomic_set(&pdp->vsync_state, 0);
+               }
+       }
+
+       if (int_status & INTS_VBLNK1_MASK) {
+               /* Write the registers for the next buffer to display */
+               pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1SURF,
+                                         pdp->flip_registers.str1surf);
+               pdp_write_reg(pdp, TCF_RGBPDP_PVR_PDP_STR1POSN,
+                                         pdp->flip_registers.str1posn);
+               pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL,
+                                         pdp->flip_registers.str1addrctrl);
+               pdp_enable_scanout(pdp);
+
+               adf_vsync_notify(&pdp->adf_interface, ktime_get());
+               atomic_set(&pdp->vsync_triggered, 1);
+               wake_up(&pdp->vsync_wait_queue);
+       }
+
+       spin_unlock_irqrestore(&gFlipLock, flags);
+}
+
+static void pdp_set_event(struct adf_obj *obj, enum adf_event_type type,
+       bool enabled)
+{
+       struct adf_pdp_device *pdp;
+       bool old;
+
+       switch (type) {
+       case ADF_EVENT_VSYNC:
+       {
+               pdp = devres_find(obj->parent->dev, pdp_devres_release,
+                                 NULL, NULL);
+               atomic_set(&pdp->requested_vsync_state, enabled);
+               if (enabled) {
+                       old = atomic_xchg(&pdp->vsync_state, enabled);
+                       if (!old)
+                               pdp_enable_vsync(pdp);
+               }
+               break;
+       }
+       default:
+               BUG();
+       }
+}
+
+static void pdp_set_clocks(struct adf_pdp_device *pdp, u32 clock_freq_hz)
+{
+       u32 clock_freq_mhz = (clock_freq_hz + 500000) / 1000000;
+
+       pll_write_reg(pdp, TCF_PLL_PLL_PDP_CLK0, clock_freq_mhz);
+       if (clock_freq_mhz >= 50)
+               pll_write_reg(pdp, TCF_PLL_PLL_PDP_CLK1TO5, 0);
+       else
+               pll_write_reg(pdp, TCF_PLL_PLL_PDP_CLK1TO5, 0x3);
+
+       pll_write_reg(pdp, TCF_PLL_PLL_PDP_DRP_GO, 1);
+       udelay(1000);
+       pll_write_reg(pdp, TCF_PLL_PLL_PDP_DRP_GO, 0);
+}
+
+static int pdp_modeset(struct adf_interface *intf,
+       struct drm_mode_modeinfo *mode)
+{
+       u32 reg_value = 0;
+       int err = 0;
+       struct adf_pdp_device *pdp = devres_find(intf->base.parent->dev,
+               pdp_devres_release, NULL, NULL);
+       int mode_id = pdp_mode_id(pdp, mode->vdisplay, mode->hdisplay);
+       const struct pdp_timing_data *tdata = pdp_timing_data(pdp, mode_id);
+
+
+       if (!tdata) {
+               dev_err(&pdp->pdev->dev, "Failed to find mode for %ux%u\n",
+                       mode->hdisplay, mode->vdisplay);
+               err = -ENXIO;
+               goto err_out;
+       }
+       /* Disable scanout */
+       pdp_disable_scanout(pdp);
+       /* Disable sync gen */
+       reg_value = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL);
+       reg_value &= ~(SYNCACTIVE_MASK);
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL, reg_value);
+
+       pdp_set_clocks(pdp, tdata->clock_freq);
+
+       if (pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STRCTRL)
+               != 0x0000C010) {
+               /* Buffer request threshold */
+               pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STRCTRL,
+                       0x00001C10);
+       }
+
+       /* Border colour */
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_BORDCOL, 0x00005544);
+
+       /* Update control */
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_UPDCTRL, 0);
+
+       /* Set hsync */
+       reg_value  = tdata->h_back_porch << HBPS_SHIFT;
+       reg_value |= tdata->h_total << HT_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC1, reg_value);
+
+       reg_value  = tdata->h_active_start << HAS_SHIFT;
+       reg_value |= tdata->h_left_border << HLBS_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC2, reg_value);
+
+       reg_value  = tdata->h_front_porch << HFPS_SHIFT;
+       reg_value |= tdata->h_right_border << HRBS_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC3, reg_value);
+
+       /* Set vsync */
+       reg_value  = tdata->v_back_porch << VBPS_SHIFT;
+       reg_value |= tdata->v_total << VT_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC1, reg_value);
+
+       reg_value  = tdata->v_active_start << VAS_SHIFT;
+       reg_value |= tdata->v_top_border << VTBS_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC2, reg_value);
+
+       reg_value  = tdata->v_front_porch << VFPS_SHIFT;
+       reg_value |= tdata->v_bottom_border << VBBS_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC3, reg_value);
+
+       /* Horizontal data enable */
+       reg_value  = tdata->h_active_start << HDES_SHIFT;
+       reg_value |= tdata->h_front_porch << HDEF_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_HDECTRL, reg_value);
+
+       /* Vertical data enable */
+       reg_value  = tdata->v_active_start << VDES_SHIFT;
+       reg_value |= tdata->v_front_porch << VDEF_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_VDECTRL, reg_value);
+
+       /* Vertical event start and vertical fetch start */
+       reg_value  = tdata->v_back_porch << VFETCH_SHIFT;
+       reg_value |= tdata->v_front_porch << VEVENT_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_VEVENT, reg_value);
+
+       /* Enable sync gen last and set up polarities of sync/blank */
+       reg_value  = 0x1 << SYNCACTIVE_SHIFT;
+       reg_value |= 0x1 << FIELDPOL_SHIFT;
+       reg_value |= 0x1 << BLNKPOL_SHIFT;
+       reg_value |= 0x1 << VSPOL_SHIFT;
+       reg_value |= 0x1 << HSPOL_SHIFT;
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL, reg_value);
+
+       intf->current_mode = *mode;
+       pdp->current_timings = tdata;
+
+err_out:
+       return err;
+}
+
+static int pdp_blank(struct adf_interface *intf,
+       u8 state)
+{
+       u32 reg_value;
+       struct adf_pdp_device *pdp = devres_find(intf->base.parent->dev,
+               pdp_devres_release, NULL, NULL);
+
+       if (state != DRM_MODE_DPMS_OFF &&
+               state != DRM_MODE_DPMS_ON)
+               return -EINVAL;
+
+       reg_value = pdp_read_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL);
+       switch (state) {
+       case DRM_MODE_DPMS_OFF:
+               reg_value |= 0x1 << POWERDN_SHIFT;
+               break;
+       case DRM_MODE_DPMS_ON:
+               reg_value &= ~(POWERDN_MASK);
+               break;
+       }
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL, reg_value);
+
+       return 0;
+}
+
+#ifdef SUPPORT_ADF_PDP_FBDEV
+
+static int pdp_alloc_simple_buffer(struct adf_interface *intf, u16 w, u16 h,
+       u32 format, struct dma_buf **dma_buf, u32 *offset, u32 *pitch)
+{
+       struct adf_pdp_device *pdp = devres_find(intf->base.parent->dev,
+               pdp_devres_release, NULL, NULL);
+       int err = 0;
+       u32 size = w * h * pdp_format_bpp(format);
+       struct ion_handle *hdl = ion_alloc(pdp->ion_client, size, 0,
+               (1 << pdp->pdata->ion_heap_id), 0);
+       if (IS_ERR(hdl)) {
+               err = PTR_ERR(hdl);
+               dev_err(&pdp->pdev->dev, "ion_alloc failed (%d)\n", err);
+               goto err_out;
+       }
+       *dma_buf = ion_share_dma_buf(pdp->ion_client, hdl);
+       if (IS_ERR(*dma_buf)) {
+               err = PTR_ERR(hdl);
+               dev_err(&pdp->pdev->dev,
+                       "ion_share_dma_buf failed (%d)\n", err);
+               goto err_free_buffer;
+       }
+       *pitch = w * pdp_format_bpp(format);
+       *offset = 0;
+err_free_buffer:
+       ion_free(pdp->ion_client, hdl);
+err_out:
+       return err;
+}
+
+static int pdp_describe_simple_post(struct adf_interface *intf,
+       struct adf_buffer *fb, void *data, size_t *size)
+{
+       /* No data required for simple post? */
+       *size = 0;
+       return 0;
+}
+
+#endif /* SUPPORT_ADF_PDP_FBDEV */
+
+static int
+adf_pdp_open(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       struct adf_device *dev =
+               (struct adf_device *)obj->parent;
+       struct adf_pdp_device *pdp = devres_find(dev->dev,
+               pdp_devres_release, NULL, NULL);
+       atomic_inc(&pdp->refcount);
+       return 0;
+}
+
+static void
+adf_pdp_release(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       struct adf_device *dev =
+               (struct adf_device *)obj->parent;
+       struct adf_pdp_device *pdp = devres_find(dev->dev,
+               pdp_devres_release, NULL, NULL);
+       struct sync_fence *release_fence;
+
+       if (atomic_dec_return(&pdp->refcount))
+               return;
+
+       /* Make sure we have no outstanding posts waiting */
+       atomic_set(&pdp->vsync_triggered, 1);
+       wake_up_all(&pdp->vsync_wait_queue);
+       /* This special "null" flip works around a problem with ADF
+        * which leaves buffers pinned by the display engine even
+        * after all ADF clients have closed.
+        *
+        * The "null" flip is pipelined like any other. The user won't
+        * be able to unload this module until it has been posted.
+        */
+       release_fence = adf_device_post(dev, NULL, 0, NULL, 0, NULL, 0);
+       if (IS_ERR_OR_NULL(release_fence)) {
+               dev_err(dev->dev,
+                       "Failed to queue null flip command (err=%d).\n",
+                       (int)PTR_ERR(release_fence));
+               return;
+       }
+
+       sync_fence_put(release_fence);
+}
+
+static int pdp_validate(struct adf_device *dev, struct adf_post *cfg,
+       void **driver_state)
+{
+       struct adf_pdp_device *pdp = devres_find(dev->dev,
+               pdp_devres_release, NULL, NULL);
+       int err = adf_img_validate_simple(dev, cfg, driver_state);
+       if (err == 0 && cfg->mappings) {
+               /* We store a snapshot of num_validates in driver_state at the
+                * time validate was called, which will be passed to the post
+                * function. This snapshot is copied into (i.e. overwrites)
+                * num_posts, rather then simply incrementing num_posts, to
+                * handle cases e.g. during fence timeouts where validates
+                * are called without corresponding posts.
+                */
+               int *validates = kmalloc(sizeof(int), GFP_KERNEL);
+               *validates = atomic_inc_return(&pdp->num_validates);
+               *driver_state = validates;
+       } else {
+               *driver_state = NULL;
+       }
+       return err;
+}
+
+static void pdp_state_free(struct adf_device *dev, void *driver_state)
+{
+       kfree(driver_state);
+}
+
+static struct adf_device_ops adf_pdp_device_ops = {
+       .owner = THIS_MODULE,
+       .base = {
+               .open = adf_pdp_open,
+               .release = adf_pdp_release,
+               .ioctl = adf_img_ioctl,
+       },
+       .state_free = pdp_state_free,
+       .validate = pdp_validate,
+       .post = pdp_post,
+};
+
+static struct adf_interface_ops adf_pdp_interface_ops = {
+       .base = {
+               .supports_event = pdp_supports_event,
+               .set_event = pdp_set_event,
+       },
+       .modeset = pdp_modeset,
+       .blank = pdp_blank,
+#ifdef SUPPORT_ADF_PDP_FBDEV
+       .alloc_simple_buffer = pdp_alloc_simple_buffer,
+       .describe_simple_post = pdp_describe_simple_post,
+#endif
+};
+
+static struct adf_overlay_engine_ops adf_pdp_overlay_ops = {
+       .supported_formats = &pdp_supported_formats[0],
+       .n_supported_formats = NUM_SUPPORTED_FORMATS,
+};
+
+#ifdef SUPPORT_ADF_PDP_FBDEV
+static struct fb_ops adf_pdp_fb_ops = {
+       .owner = THIS_MODULE,
+       .fb_open = adf_fbdev_open,
+       .fb_release = adf_fbdev_release,
+       .fb_check_var = adf_fbdev_check_var,
+       .fb_set_par = adf_fbdev_set_par,
+       .fb_blank = adf_fbdev_blank,
+       .fb_pan_display = adf_fbdev_pan_display,
+       .fb_fillrect = cfb_fillrect,
+       .fb_copyarea = cfb_copyarea,
+       .fb_imageblit = cfb_imageblit,
+       .fb_mmap = adf_fbdev_mmap,
+};
+#endif
+
+static int adf_pdp_probe_device(struct platform_device *pdev)
+{
+       struct adf_pdp_device *pdp;
+       int err = 0;
+       int i, default_mode_id;
+       struct apollo_pdp_platform_data *pdata = pdev->dev.platform_data;
+       pdp = devres_alloc(pdp_devres_release, sizeof(struct adf_pdp_device),
+               GFP_KERNEL);
+       if (!pdp) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       devres_add(&pdev->dev, pdp);
+
+       pdp->pdata = pdata;
+       pdp->pdev = pdev;
+
+       err = pci_enable_device(pdata->pdev);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "Failed to enable PDP pci device (%d)\n", err);
+               goto err_out;
+       }
+
+       atomic_set(&pdp->refcount, 0);
+       atomic_set(&pdp->num_validates, 0);
+       pdp->num_posts = 0;
+
+       pdp->ion_client = ion_client_create(pdata->ion_device, "adf_pdp");
+       if (IS_ERR(pdp->ion_client)) {
+               err = PTR_ERR(pdp->ion_client);
+               dev_err(&pdev->dev,
+                       "Failed to create PDP ION client (%d)\n", err);
+               goto err_disable_pci;
+       }
+
+       err = request_pci_io_addr(pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               DCPDP_PCI_PDP_REG_OFFSET, DCPDP_PCI_PDP_REG_SIZE);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "Failed to request PDP registers (%d)\n", err);
+               goto err_destroy_ion_client;
+       }
+
+       pdp->regs_size = DCPDP_PCI_PDP_REG_SIZE;
+       pdp->regs_start =
+               pci_resource_start(pdata->pdev, DCPDP_REG_PCI_BASENUM)
+               + DCPDP_PCI_PDP_REG_OFFSET;
+
+       pdp->regs = ioremap_nocache(pdp->regs_start, pdp->regs_size);
+       if (!pdp->regs) {
+               dev_err(&pdev->dev, "Failed to map PDP registers\n");
+               err = -EIO;
+               goto err_release_registers;
+       }
+
+       err = request_pci_io_addr(pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               DCPDP_PCI_PLL_REG_OFFSET, DCPDP_PCI_PLL_REG_SIZE);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "Failed to request PLL registers (%d)\n", err);
+               goto err_unmap_registers;
+       }
+       pdp->pll_regs_size = DCPDP_PCI_PLL_REG_SIZE;
+       pdp->pll_regs_start =
+               pci_resource_start(pdata->pdev, DCPDP_REG_PCI_BASENUM)
+               + DCPDP_PCI_PLL_REG_OFFSET;
+
+       pdp->pll_regs = ioremap_nocache(pdp->pll_regs_start,
+               pdp->pll_regs_size);
+       if (!pdp->pll_regs) {
+               dev_err(&pdev->dev, "Failed to map PLL registers\n");
+               err = -EIO;
+               goto err_release_pll_registers;
+       }
+
+       err = adf_device_init(&pdp->adf_device, &pdp->pdev->dev,
+               &adf_pdp_device_ops, "pdp_device");
+       if (err) {
+               dev_err(&pdev->dev, "Failed to init ADF device (%d)\n", err);
+               goto err_unmap_pll_registers;
+       }
+
+       err = adf_interface_init(&pdp->adf_interface, &pdp->adf_device,
+               ADF_INTF_DVI, 0, ADF_INTF_FLAG_PRIMARY, &adf_pdp_interface_ops,
+               "pdp_interface");
+       if (err) {
+               dev_err(&pdev->dev, "Failed to init ADF interface (%d)\n", err);
+               goto err_destroy_adf_device;
+       }
+
+       err = adf_overlay_engine_init(&pdp->adf_overlay, &pdp->adf_device,
+               &adf_pdp_overlay_ops, "pdp_overlay");
+       if (err) {
+               dev_err(&pdev->dev, "Failed to init ADF overlay (%d)\n", err);
+               goto err_destroy_adf_interface;
+       }
+
+       err = adf_attachment_allow(&pdp->adf_device, &pdp->adf_overlay,
+               &pdp->adf_interface);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to attach overlay (%d)\n", err);
+               goto err_destroy_adf_overlay;
+       }
+
+       pdp->num_supported_modes = pdp_mode_count(pdp);
+       pdp->supported_modes = kzalloc(sizeof(struct drm_mode_modeinfo)
+               * pdp->num_supported_modes, GFP_KERNEL);
+
+       if (!pdp->supported_modes) {
+               dev_err(&pdev->dev, "Failed to allocate supported modeinfo structs\n");
+               err = -ENOMEM;
+               goto err_destroy_adf_overlay;
+       }
+
+       for (i = 0; i < pdp->num_supported_modes; i++)
+               pdp_mode_to_drm_mode(pdp, i, &pdp->supported_modes[i]);
+
+       default_mode_id = pdp_mode_id(pdp, pdp_display_height,
+               pdp_display_width);
+       if (default_mode_id == -1) {
+               default_mode_id = 0;
+               dev_err(&pdev->dev, "No modeline found for requested display size (%dx%d)\n",
+                       pdp_display_width, pdp_display_height);
+       }
+
+       /* Initial modeset... */
+       err = pdp_modeset(&pdp->adf_interface,
+               &pdp->supported_modes[default_mode_id]);
+       if (err) {
+               dev_err(&pdev->dev, "Initial modeset failed (%d)\n", err);
+               goto err_destroy_modelist;
+       }
+
+       err = adf_hotplug_notify_connected(&pdp->adf_interface,
+               pdp->supported_modes, pdp->num_supported_modes);
+       if (err) {
+               dev_err(&pdev->dev, "Initial hotplug notify failed (%d)\n",
+                       err);
+               goto err_destroy_modelist;
+       }
+       err = apollo_set_interrupt_handler(&pdp->pdata->pdev->dev,
+                                          APOLLO_INTERRUPT_PDP,
+                                          pdp_irq_handler, pdp);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to set interrupt handler (%d)\n",
+                       err);
+               goto err_destroy_modelist;
+       }
+#ifdef SUPPORT_ADF_PDP_FBDEV
+       err = adf_fbdev_init(&pdp->adf_fbdev, &pdp->adf_interface,
+               &pdp->adf_overlay, pdp_display_width,
+               pdp_display_height, DRM_FORMAT_BGRA8888,
+               &adf_pdp_fb_ops, "adf_pdp_fb");
+       if (err) {
+               dev_err(&pdev->dev, "Failed to init ADF fbdev (%d)\n", err);
+               goto err_destroy_modelist;
+       }
+#endif
+
+       init_waitqueue_head(&pdp->vsync_wait_queue);
+       atomic_set(&pdp->requested_vsync_state, 0);
+       atomic_set(&pdp->vsync_state, 0);
+
+       return err;
+err_destroy_modelist:
+       kfree(pdp->supported_modes);
+err_destroy_adf_overlay:
+       adf_overlay_engine_destroy(&pdp->adf_overlay);
+err_destroy_adf_interface:
+       adf_interface_destroy(&pdp->adf_interface);
+err_destroy_adf_device:
+       adf_device_destroy(&pdp->adf_device);
+err_unmap_pll_registers:
+       iounmap(pdp->pll_regs);
+err_release_pll_registers:
+       release_pci_io_addr(pdp->pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               pdp->pll_regs_start, pdp->pll_regs_size);
+err_unmap_registers:
+       iounmap(pdp->regs);
+err_release_registers:
+       release_pci_io_addr(pdp->pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               pdp->regs_start, pdp->regs_size);
+err_destroy_ion_client:
+       ion_client_destroy(pdp->ion_client);
+err_disable_pci:
+       pci_disable_device(pdata->pdev);
+err_out:
+       dev_err(&pdev->dev, "Failed to initialise PDP device\n");
+       return err;
+}
+
+static int adf_pdp_remove_device(struct platform_device *pdev)
+{
+       int err = 0;
+       struct adf_pdp_device *pdp = devres_find(&pdev->dev, pdp_devres_release,
+               NULL, NULL);
+
+       pdp_disable_scanout(pdp);
+
+       pdp_disable_vsync(pdp);
+       apollo_set_interrupt_handler(&pdp->pdata->pdev->dev,
+                                    APOLLO_INTERRUPT_PDP,
+                                    NULL, NULL);
+       /* Disable scanout */
+       pdp_write_reg(pdp, TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL, 0);
+       kfree(pdp->supported_modes);
+#ifdef SUPPORT_ADF_PDP_FBDEV
+       adf_fbdev_destroy(&pdp->adf_fbdev);
+#endif
+       adf_overlay_engine_destroy(&pdp->adf_overlay);
+       adf_interface_destroy(&pdp->adf_interface);
+       adf_device_destroy(&pdp->adf_device);
+       iounmap(pdp->pll_regs);
+       release_pci_io_addr(pdp->pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               pdp->pll_regs_start, pdp->pll_regs_size);
+       iounmap(pdp->regs);
+       release_pci_io_addr(pdp->pdata->pdev, DCPDP_REG_PCI_BASENUM,
+               pdp->regs_start, pdp->regs_size);
+       ion_client_destroy(pdp->ion_client);
+       pci_disable_device(pdp->pdata->pdev);
+       return err;
+}
+
+static void adf_pdp_shutdown_device(struct platform_device *pdev)
+{
+       /* No cleanup needed, all done in remove_device */
+}
+
+static struct platform_device_id pdp_platform_device_id_table[] = {
+       { .name = APOLLO_DEVICE_NAME_PDP, .driver_data = 0 },
+       { },
+};
+
+static struct platform_driver pdp_platform_driver = {
+       .probe = adf_pdp_probe_device,
+       .remove = adf_pdp_remove_device,
+       .shutdown = adf_pdp_shutdown_device,
+       .driver = {
+               .name = DRV_NAME,
+       },
+       .id_table = pdp_platform_device_id_table,
+};
+
+static int __init adf_pdp_init(void)
+{
+       return platform_driver_register(&pdp_platform_driver);
+}
+
+static void __exit adf_pdp_exit(void)
+{
+       platform_driver_unregister(&pdp_platform_driver);
+}
+
+module_init(adf_pdp_init);
+module_exit(adf_pdp_exit);
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.c
new file mode 100644 (file)
index 0000000..31adac9
--- /dev/null
@@ -0,0 +1,1612 @@
+/*************************************************************************/ /*!
+@File           adf_sunxi.c
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+
+#include <video/adf.h>
+#include <video/adf_client.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+#include <video/adf_fbdev.h>
+#endif
+
+#include PVR_ANDROID_ION_HEADER
+#include PVR_ANDROID_SYNC_HEADER
+
+#include <linux/sw_sync.h>
+
+#include "adf_common.h"
+#include "adf_sunxi.h"
+
+#include "pvrmodule.h"
+
+#define MAX_DISPLAYS 2
+/* This is the maximum number of overlays per display
+ * Any global limitation validation must be done in either adf_sunxi_attach()
+ * or adf_sunxi_validate() */
+#define NUM_OVERLAYS 4
+#define NUM_BLENDER_PIPES 2
+#define MAX_BUFFERS (MAX_DISPLAYS * NUM_OVERLAYS)
+
+#define DEBUG_POST_DUMP_COUNT 4
+#define VALIDATE_LOG_LINES 50
+#define VALIDATE_LOG_LINE_SIZE 50
+
+#ifdef ADF_VERBOSE_DEBUG
+#define sunxi_dbg(x...) dev_dbg(x)
+#else
+#define sunxi_dbg(...)
+#endif
+
+struct sunxi_interface {
+       struct adf_interface interface;
+       enum adf_interface_type adf_type;
+       const char *name;
+
+       int num_supported_modes;
+       struct drm_mode_modeinfo *supported_modes;
+
+       bool connected;
+
+       int display_id;
+       disp_output_type disp_type;
+};
+
+
+struct sunxi_overlay {
+       struct adf_overlay_engine overlay;
+       /* <0 means not attached, otherwise offset in sunxi.interfaces */
+       struct sunxi_interface *interface;
+};
+
+struct {
+       struct adf_device device;
+       struct device *dev;
+       struct sunxi_interface interfaces[MAX_DISPLAYS];
+       struct sunxi_overlay overlays[MAX_DISPLAYS][NUM_OVERLAYS];
+       struct ion_client *ion_client;
+       u32 ion_heap_id;
+       atomic_t refcount;
+
+       struct disp_composer_ops disp_ops;
+
+       /* Used to dump the last config to debugfs file */
+       struct setup_dispc_data last_config[DEBUG_POST_DUMP_COUNT];
+       u32 last_config_id[DEBUG_POST_DUMP_COUNT];
+       int last_config_pos;
+
+       char validate_log[VALIDATE_LOG_LINES][VALIDATE_LOG_LINE_SIZE];
+       int validate_log_position;
+
+       struct dentry *debugfs_config_file;
+       struct dentry *debugfs_val_log;
+
+       atomic_t postcount;
+       atomic_t callbackcount;
+
+       wait_queue_head_t post_wait_queue;
+
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+       struct adf_fbdev fbdev;
+#endif
+} sunxi;
+
+static const u32 sunxi_supported_formats[] = {
+       DRM_FORMAT_BGRA8888,
+       DRM_FORMAT_BGRX8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_YVU420,
+};
+#define NUM_SUPPORTED_FORMATS ARRAY_SIZE(sunxi_supported_formats)
+
+static void val_log(u32 post_id, const char *fmt, ...)
+{
+       va_list args;
+       char *str;
+       int offset;
+
+       sunxi.validate_log_position = (sunxi.validate_log_position + 1)
+               % VALIDATE_LOG_LINES;
+
+       str = sunxi.validate_log[sunxi.validate_log_position];
+
+       offset = snprintf(str, VALIDATE_LOG_LINE_SIZE, "id %u:",
+               post_id);
+
+       va_start(args, fmt);
+       vsnprintf(str+offset, VALIDATE_LOG_LINE_SIZE-offset, fmt, args);
+       va_end(args);
+}
+
+static bool
+is_supported_format(u32 drm_format)
+{
+       int i;
+
+       for (i = 0; i < NUM_SUPPORTED_FORMATS; i++) {
+               if (sunxi_supported_formats[i] == drm_format)
+                       return true;
+       }
+       return false;
+}
+
+static disp_pixel_format
+sunxi_format_to_disp(u32 format)
+{
+       switch (format) {
+       case DRM_FORMAT_BGRA8888:
+               return DISP_FORMAT_ARGB_8888;
+       case DRM_FORMAT_ARGB8888:
+               return DISP_FORMAT_BGRA_8888;
+       case DRM_FORMAT_BGRX8888:
+               return DISP_FORMAT_XRGB_8888;
+       case DRM_FORMAT_XRGB8888:
+               return DISP_FORMAT_BGRX_8888;
+       case DRM_FORMAT_YVU420:
+               return DISP_FORMAT_YUV420_P;
+       default:
+               BUG();
+               return -1;
+       }
+}
+
+static bool
+sunxi_format_has_alpha(u32 format)
+{
+       switch (format) {
+       case DRM_FORMAT_BGRA8888:
+       case DRM_FORMAT_ARGB8888:
+               return true;
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_YVU420:
+               return false;
+       default:
+               BUG();
+               return false;
+       }
+}
+
+static u32
+sunxi_format_bpp(u32 format)
+{
+       switch (format) {
+       case DRM_FORMAT_BGRA8888:
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XRGB8888:
+               return 4;
+       case DRM_FORMAT_YVU420:
+               return 1;
+       default:
+               BUG();
+               return 0;
+       }
+}
+
+static bool
+sunxi_format_uv_is_swapped(u32 format)
+{
+       switch (format) {
+       case DRM_FORMAT_BGRA8888:
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XRGB8888:
+               return false;
+       case DRM_FORMAT_YVU420:
+               return true;
+       default:
+               BUG();
+               return false;
+       }
+}
+
+static bool
+buffer_is_scaled(const struct adf_buffer_config_ext *ext_config_data)
+{
+       int srcWidth = ext_config_data->crop.x2 - ext_config_data->crop.x1;
+       int srcHeight = ext_config_data->crop.y2 - ext_config_data->crop.y1;
+       int dstWidth = ext_config_data->display.x2
+               - ext_config_data->display.x1;
+       int dstHeight = ext_config_data->display.y2
+               - ext_config_data->display.y1;
+       if (srcWidth != dstWidth ||
+           srcHeight != dstHeight)
+               return true;
+       else
+               return false;
+}
+
+static int
+sunxi_buffer_to_layer_info(const struct adf_buffer *buf,
+       const struct adf_buffer_config_ext *ext_config_data,
+       const struct adf_buffer_mapping *mappings, disp_layer_info *layer)
+{
+       int plane;
+
+       if (buffer_is_scaled(ext_config_data))
+               layer->mode = DISP_LAYER_WORK_MODE_SCALER;
+       else
+               layer->mode = DISP_LAYER_WORK_MODE_NORMAL;
+
+       /* Pipe/z are set in the parent function */
+       layer->pipe = 0;
+       layer->zorder = 0;
+       /*  0 = per-pixel alpha, 1 = global alpha */
+       switch (ext_config_data->blend_type) {
+       case ADF_BUFFER_BLENDING_NONE_EXT:
+               layer->alpha_mode = 1;
+               layer->alpha_value = 255;
+               break;
+       case ADF_BUFFER_BLENDING_PREMULT_EXT:
+               if (sunxi_format_has_alpha(buf->format))
+                       layer->alpha_mode = 0;
+               else
+                       layer->alpha_mode = 1;
+               layer->alpha_value = ext_config_data->plane_alpha;
+               layer->fb.pre_multiply = true;
+               break;
+       case ADF_BUFFER_BLENDING_COVERAGE_EXT:
+               dev_err(sunxi.dev, "Coverage blending not implemented\n");
+               return -1;
+       default:
+               dev_err(sunxi.dev, "Unknown blending type %d\n",
+                       ext_config_data->blend_type);
+               return -1;
+
+       }
+       layer->ck_enable = false;
+       layer->screen_win.x = ext_config_data->display.x1;
+       layer->screen_win.y = ext_config_data->display.y1;
+       layer->screen_win.width = ext_config_data->display.x2 -
+               ext_config_data->display.x1;
+       layer->screen_win.height = ext_config_data->display.y2 -
+               ext_config_data->display.y1;
+
+       if (mappings) {
+               for (plane = 0; plane < buf->n_planes; plane++) {
+                       layer->fb.addr[plane] =
+                               sg_phys(mappings->sg_tables[plane]->sgl) +
+                               buf->offset[plane];
+               }
+
+               /* Fix up planar formats with VU plane ordering. For some
+                * reason this is not properly handled by the sunxi disp
+                * driver for sun9i.
+                */
+               if (sunxi_format_uv_is_swapped(buf->format)) {
+                       unsigned int tmp = layer->fb.addr[1];
+                       layer->fb.addr[1] = layer->fb.addr[2];
+                       layer->fb.addr[2] = tmp;
+               }
+       }
+
+       layer->fb.size.width = buf->pitch[0] / sunxi_format_bpp(buf->format);
+       layer->fb.size.height = buf->h;
+       layer->fb.format = sunxi_format_to_disp(buf->format);
+       layer->fb.src_win.x = ext_config_data->crop.x1;
+       layer->fb.src_win.y = ext_config_data->crop.y1;
+       /*  fb.src_win.width/height is only used for scaled layers */
+       layer->fb.src_win.width = ext_config_data->crop.x2 -
+               ext_config_data->crop.x1;
+       layer->fb.src_win.height = ext_config_data->crop.y2 -
+               ext_config_data->crop.y1;
+
+       return 0;
+}
+
+static int
+adf_sunxi_open(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       atomic_inc(&sunxi.refcount);
+       return 0;
+}
+
+static void adf_sunxi_set_hotplug_state(struct sunxi_interface *intf,
+       bool enable);
+
+static void
+adf_sunxi_release(struct adf_obj *obj, struct inode *inode, struct file *file)
+{
+       struct sync_fence *release_fence;
+       int dpy;
+
+       if (atomic_dec_return(&sunxi.refcount))
+               return;
+
+       /* NULL flip to push buffer off screen */
+       release_fence = adf_device_post(obj->parent, NULL, 0, NULL, 0, NULL, 0);
+
+       if (IS_ERR_OR_NULL(release_fence)) {
+               dev_err(obj->parent->dev, "Failed to queue null flip command (err=%d)\n",
+                       (int)PTR_ERR(release_fence));
+               return;
+       }
+
+       /* Disable any hotplug events */
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_HDMI)
+                       adf_sunxi_set_hotplug_state(&sunxi.interfaces[dpy],
+                               false);
+       }
+
+       sync_fence_put(release_fence);
+}
+
+struct pipe_assignments {
+       int pipe[MAX_BUFFERS];
+};
+static void adf_sunxi_state_free(struct adf_device *dev, void *driver_state)
+{
+       struct pipe_assignments *pipe_assignments =
+               driver_state;
+
+       kfree(pipe_assignments);
+}
+
+static int get_buf_display(struct adf_buffer *buf)
+{
+       int dpy, ovl;
+
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               for (ovl = 0; ovl < NUM_OVERLAYS; ovl++) {
+                       if (&sunxi.overlays[dpy][ovl].overlay ==
+                               buf->overlay_engine) {
+                               goto found_ovl;
+                       }
+               }
+       }
+       return -1;
+found_ovl:
+       return dpy;
+}
+
+struct pipe_assignment_state {
+       int current_pipe[MAX_DISPLAYS];
+       int max_pipe[MAX_DISPLAYS];
+       int current_pipe_layers[MAX_DISPLAYS];
+
+       struct drm_clip_rect current_pipe_rects[MAX_DISPLAYS][NUM_OVERLAYS];
+};
+
+static int
+assign_pipe(struct pipe_assignment_state *state, int dpy, bool blended,
+       struct drm_clip_rect *display_rect)
+{
+       struct drm_clip_rect *current_pipe_rects =
+               &state->current_pipe_rects[dpy][0];
+       int rect;
+
+       /* The sunxi display block appears to support a single blender
+       * taking multiple input rects, so long as the blended
+       * rects do not overlap */
+       if (blended) {
+               for (rect = 0; rect < state->current_pipe_layers[dpy]; rect++) {
+                       const struct drm_clip_rect *layer_rect = &
+                               current_pipe_rects[rect];
+                       if (!adf_img_rects_intersect(layer_rect,
+                               display_rect)) {
+                               continue;
+                       }
+                       /* We need to assign a new pipe */
+                       state->current_pipe[dpy]++;
+                       state->current_pipe_layers[dpy] = 0;
+                       if (state->current_pipe[dpy] >=
+                               state->max_pipe[dpy]) {
+                               return -1;
+                       }
+               }
+       }
+       current_pipe_rects[state->current_pipe_layers[dpy]] =
+               *display_rect;
+       state->current_pipe_layers[dpy]++;
+
+       return state->current_pipe[dpy];
+}
+
+static int adf_sunxi_validate(struct adf_device *dev, struct adf_post *cfg,
+       void **driver_state)
+{
+       int i, dpy, pipe;
+       struct adf_post_ext *post_ext = cfg->custom_data;
+       struct adf_buffer_config_ext *bufs_ext;
+       size_t expected_custom_data_size;
+
+       struct pipe_assignment_state pipe_state;
+       struct pipe_assignments *pipe_assignments;
+       bool scaler_in_use[MAX_DISPLAYS];
+       int err = 0;
+       u32 post_id;
+
+       bool is_post = cfg->n_bufs && cfg->bufs[0].acquire_fence != NULL;
+
+       if (cfg->n_bufs == 0) {
+               val_log(0, "NULL flip\n");
+               return 0;
+       }
+
+       if (!post_ext) {
+               dev_err(dev->dev, "Invalid custom data pointer\n");
+               return -EINVAL;
+       }
+       post_id = post_ext->post_id;
+
+       expected_custom_data_size = sizeof(struct adf_post_ext)
+               + cfg->n_bufs * sizeof(struct adf_buffer_config_ext);
+       if (cfg->custom_data_size != expected_custom_data_size) {
+               dev_err(dev->dev, "Invalid custom data size - expected %u for %u buffers, got %u\n",
+                       expected_custom_data_size, cfg->n_bufs,
+                       cfg->custom_data_size);
+               return -EINVAL;
+       }
+
+       bufs_ext = &post_ext->bufs_ext[0];
+
+       /* Reset blend pipe state */
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               scaler_in_use[dpy] = false;
+               pipe_state.current_pipe[dpy] = 0;
+               pipe_state.current_pipe_layers[dpy] = 0;
+       }
+
+       /* NOTE: The current method of assigning pipes over multiple displays
+        * is unknown and needs experimentation/documentation to correct.
+        * The current assumption is that there are 2 blend sources (pipe 0
+        * and 1) on the internal display, and only 1 (pipe 0) on hdmi */
+       if (sunxi.interfaces[DISPLAY_HDMI].connected) {
+               pipe_state.max_pipe[DISPLAY_HDMI] = 1;
+               pipe_state.current_pipe[DISPLAY_HDMI] = 0;
+               pipe_state.max_pipe[DISPLAY_INTERNAL] = NUM_BLENDER_PIPES;
+               pipe_state.current_pipe[DISPLAY_INTERNAL] = 1;
+       } else {
+               pipe_state.max_pipe[DISPLAY_INTERNAL] = NUM_BLENDER_PIPES;
+               pipe_state.current_pipe[DISPLAY_INTERNAL] = 0;
+               pipe_state.max_pipe[DISPLAY_HDMI] = 0;
+               pipe_state.current_pipe[DISPLAY_HDMI] = 0;
+       }
+
+       pipe_assignments =
+               kzalloc(sizeof(struct pipe_assignments), GFP_KERNEL);
+       if (!pipe_assignments) {
+               dev_err(dev->dev, "Failed to allocate pipe assignment state\n");
+               err = -ENOMEM;
+               goto err_free_assignments;
+       }
+
+
+       if (cfg->n_bufs > MAX_BUFFERS) {
+               dev_err(dev->dev, "Trying to post %d buffers (max %d)\n",
+                       MAX_BUFFERS, NUM_OVERLAYS);
+               err = -EINVAL;
+               goto err_free_assignments;
+       }
+
+       for (i = 0; i < cfg->n_bufs; i++) {
+               bool buffer_is_sane;
+               struct adf_buffer *buf = &cfg->bufs[i];
+               struct adf_buffer_config_ext *ebuf = &bufs_ext[i];
+
+               dpy = get_buf_display(buf);
+               if (dpy < 0) {
+                       dev_err(dev->dev, "Buffer %d has invalid assigned overlay\n",
+                               i);
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+
+               buffer_is_sane =
+                       adf_img_buffer_sanity_check(
+                               &sunxi.interfaces[dpy].interface,
+                               buf,
+                               ebuf);
+
+               if (!buffer_is_sane) {
+                       dev_err(dev->dev, "Buffer %d failed sanity check\n",
+                               i);
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+
+               if (!is_supported_format(buf->format)) {
+                       /* This should be cleanly rejected when trying to assign
+                        * an overlay engine */
+                       dev_err(dev->dev, "Buffer %d has unrecognised format 0x%08x\n",
+                               i, buf->format);
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+               if (buffer_is_scaled(ebuf)) {
+                       /* The assumption is that there is a single scaled
+                        * layer allowed per display, otherwise there may
+                        * be a unbounded top end to the samples required per
+                        * frame when testing validity a single layer at a time
+                        * */
+                       if (scaler_in_use[dpy]) {
+                               val_log(post_id, "Buffer %d is second scaled layer\n",
+                                       i);
+                               err = -EINVAL;
+                               goto err_free_assignments;
+                       }
+                       scaler_in_use[dpy] = true;
+                       if (!sunxi.disp_ops.is_support_scaler_layer(dpy,
+                               ebuf->crop.x2 - ebuf->crop.x1,
+                               ebuf->crop.y2 - ebuf->crop.y1,
+                               ebuf->display.x2 - ebuf->display.x1,
+                               ebuf->display.y2 - ebuf->display.y1)) {
+                                       val_log(post_id, "Buffer %d unsupported scaled layer\n",
+                                               i);
+                                       err = -EINVAL;
+                                       goto err_free_assignments;
+                               }
+               }
+               if (ebuf->transform != ADF_BUFFER_TRANSFORM_NONE_EXT) {
+                       /* TODO: Sunxi transform support */
+                       val_log(post_id, "Transformed layers not supported at the minute\n");
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+
+               if (ebuf->blend_type != ADF_BUFFER_BLENDING_NONE_EXT &&
+                   ebuf->plane_alpha != 255 &&
+                   sunxi_format_has_alpha(buf->format)) {
+                       /* The sunxi display block appears to only support
+                        * pixel /or/ global (plane) alpha, not both */
+                       val_log(post_id, "Layer has both plane and pixel alpha\n");
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+
+               pipe = assign_pipe(&pipe_state, dpy,
+                       ebuf->blend_type != ADF_BUFFER_BLENDING_NONE_EXT,
+                       &ebuf->display);
+
+               if (pipe < 0) {
+                       val_log(post_id, "Ran out of blend pipes\n");
+                       err = -EINVAL;
+                       goto err_free_assignments;
+               }
+               pipe_assignments->pipe[i] = pipe;
+       }
+       val_log(post_id, "Validate succeeded\n");
+
+       *driver_state = pipe_assignments;
+
+       return 0;
+err_free_assignments:
+       if (is_post)
+               dev_err(dev->dev, "Failed validate for post\n");
+       kfree(pipe_assignments);
+       return err;
+}
+
+static void sunxi_retire_callback(void)
+{
+       atomic_inc(&sunxi.callbackcount);
+       wake_up(&sunxi.post_wait_queue);
+}
+
+static bool sunxi_post_completed(u32 post_id)
+{
+       return (atomic_read(&sunxi.callbackcount) >= post_id);
+}
+
+static void adf_sunxi_post(struct adf_device *adf_dev, struct adf_post *cfg,
+       void *driver_state)
+{
+       struct setup_dispc_data *disp_data;
+       int err, buf;
+       struct adf_post_ext *post_ext = cfg->custom_data;
+       struct adf_buffer_config_ext *ext_config_data = NULL;
+       int num_buffers[MAX_DISPLAYS];
+       int dpy;
+       struct pipe_assignments *pipe_assignments;
+       u32 post_count, post_id;
+       /* Allow a timeout of 4 frames before we force the frame off-screen */
+       long timeout =
+               msecs_to_jiffies((1000 / 60) * 4);
+
+       if (cfg->n_bufs == 0) {
+               val_log(0, "NULL flip\n");
+               post_id = 0;
+               post_ext = NULL;
+       } else {
+               BUG_ON(post_ext == NULL);
+               post_id = post_ext->post_id;
+               ext_config_data = &post_ext->bufs_ext[0];
+               val_log(post_id, "Posting\n");
+       }
+
+       pipe_assignments = driver_state;
+       if (!pipe_assignments && cfg->n_bufs != 0) {
+               dev_err(adf_dev->dev, "Invalid driver state\n");
+               return;
+       }
+
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++)
+               num_buffers[dpy] = 0;
+
+       disp_data = kzalloc(sizeof(struct setup_dispc_data), GFP_KERNEL);
+       if (!disp_data) {
+               dev_err(adf_dev->dev, "Failed to allocate post data");
+               return;
+       }
+
+       for (buf = 0; buf < cfg->n_bufs; buf++) {
+
+               dpy = get_buf_display(&cfg->bufs[buf]);
+               if (dpy < 0) {
+                       dev_err(adf_dev->dev, "Invalid overlay %p assigned to layer %d",
+                               cfg->bufs[buf].overlay_engine, buf);
+                       goto err_free_data;
+               }
+
+               err = sunxi_buffer_to_layer_info(&cfg->bufs[buf],
+                       &ext_config_data[buf],
+                       &cfg->mappings[buf],
+                       &disp_data->layer_info[dpy][num_buffers[dpy]]);
+
+               if (err) {
+                       dev_err(adf_dev->dev, "Failed to setup layer info (%d)\n",
+                               err);
+                       goto err_free_data;
+               }
+               disp_data->layer_info[dpy][num_buffers[dpy]].pipe =
+                       pipe_assignments->pipe[buf];
+               disp_data->layer_info[dpy][num_buffers[dpy]].zorder = buf;
+               num_buffers[dpy]++;
+       }
+
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               sunxi_dbg(adf_dev->dev, "Dpy %u has %u layers\n", dpy,
+                       num_buffers[dpy]);
+               disp_data->layer_num[dpy] = num_buffers[dpy];
+       }
+
+       disp_data->hConfigData = disp_data;
+
+       sunxi.last_config_pos = (sunxi.last_config_pos + 1)
+               % DEBUG_POST_DUMP_COUNT;
+
+       sunxi.last_config[sunxi.last_config_pos] = *disp_data;
+       sunxi.last_config_id[sunxi.last_config_pos] = post_id;
+
+       err = sunxi.disp_ops.dispc_gralloc_queue(disp_data);
+       if (err)
+               dev_err(adf_dev->dev, "Failed to queue post (%d)\n", err);
+
+       post_count = atomic_add_return(1, &sunxi.postcount);
+
+       if (wait_event_timeout(sunxi.post_wait_queue,
+               sunxi_post_completed(post_count-1), timeout) == 0) {
+               dev_err(sunxi.dev, "Timeout waiting for post callback\n");
+
+       }
+
+err_free_data:
+       kfree(disp_data);
+       return;
+
+}
+
+static bool adf_sunxi_supports_event(struct adf_obj *obj,
+       enum adf_event_type type)
+{
+       switch (obj->type) {
+       case ADF_OBJ_INTERFACE: {
+               struct adf_interface *intf =
+                       container_of(obj, struct adf_interface, base);
+               struct sunxi_interface *sunxi_intf =
+                       container_of(intf, struct sunxi_interface, interface);
+               switch (type) {
+               case ADF_EVENT_VSYNC:
+                       return true;
+               case ADF_EVENT_HOTPLUG:
+                       /* Only support hotplug on HDMI displays */
+                       return (sunxi_intf->disp_type == DISP_OUTPUT_TYPE_HDMI);
+               default:
+                       return false;
+               }
+       }
+       default:
+               return false;
+       }
+       return false;
+}
+
+static struct
+{
+       u32 width, height, refresh;
+       disp_tv_mode mode;
+} hdmi_valid_modes[] = {
+       /* List of modes in preference order */
+       { 1920, 1080,   60,     DISP_TV_MOD_1080P_60HZ},
+       { 1920, 1080,   50,     DISP_TV_MOD_1080P_50HZ},
+       { 1280, 720,    60,     DISP_TV_MOD_720P_60HZ},
+       { 1280, 720,    50,     DISP_TV_MOD_720P_50HZ},
+       { 1920, 1080,   25,     DISP_TV_MOD_1080P_25HZ},
+       { 1920, 1080,   30,     DISP_TV_MOD_1080P_30HZ},
+       { 640,  480,    30,     DISP_TV_MOD_480P},
+};
+#define NUM_HDMI_VALID_MODES \
+       (sizeof(hdmi_valid_modes)/sizeof(hdmi_valid_modes[0]))
+
+static void setup_drm_mode(struct drm_mode_modeinfo *mode, int height,
+       int width, int refresh)
+{
+       memset(mode, 0, sizeof(*mode));
+
+       mode->vrefresh = refresh;
+       mode->hdisplay = width;
+       mode->vdisplay = height;
+
+       adf_modeinfo_set_name(mode);
+}
+
+static void sunxi_disp_vsync_callback(void *user_data, u32 screen_id)
+{
+       adf_vsync_notify(&sunxi.interfaces[screen_id].interface, ktime_get());
+}
+
+static int sunxi_disp_hotplug_callback(void *user_data,
+       disp_hotplug_state state)
+{
+       struct sunxi_interface *intf = user_data;
+       int ret;
+       int mode_count = 0;
+       unsigned int idx;
+
+       dev_dbg(sunxi.dev, "%s: called state = %u\n", __func__, state);
+
+       /* Only HDMI displays can be hotplugged */
+       BUG_ON(intf->disp_type != DISP_OUTPUT_TYPE_HDMI);
+
+       kfree(intf->supported_modes);
+       intf->supported_modes = NULL;
+       intf->num_supported_modes = 0;
+       switch (state) {
+       default:
+               dev_err(sunxi.dev, "%s: Invalid hotplug state\n", __func__);
+               /* Fall-thru, treat as disconnect */
+       case DISP_HOTPLUG_DISCONNECT:
+               intf->connected = false;
+               adf_hotplug_notify_disconnected(&intf->interface);
+               dev_dbg(sunxi.dev, "%s: set disconnected\n", __func__);
+               return 0;
+       case DISP_HOTPLUG_CONNECT:
+               intf->connected = true;
+               break;
+       }
+
+       for (idx = 0; idx < NUM_HDMI_VALID_MODES; idx++) {
+               ret = sunxi.disp_ops.hdmi_check_support_mode(intf->display_id,
+                       hdmi_valid_modes[idx].mode);
+               if (ret == 1)
+                       mode_count++;
+       }
+
+       intf->num_supported_modes = mode_count;
+       if (mode_count == 0) {
+               dev_warn(sunxi.dev, "%s: No supported modes found for display id %d - forcing 720p\n",
+                       __func__, intf->display_id);
+               intf->num_supported_modes = 1;
+               intf->supported_modes = kzalloc(
+                       sizeof(struct drm_mode_modeinfo), GFP_KERNEL);
+               if (!intf->supported_modes) {
+                       dev_err(sunxi.dev, "%s: Failed to allocate mode list\n",
+                               __func__);
+                       goto err_out;
+               }
+               /* Force the first mode in the supported list */
+               setup_drm_mode(&intf->supported_modes[0],
+                       hdmi_valid_modes[0].height, hdmi_valid_modes[0].width,
+                       hdmi_valid_modes[0].refresh);
+       } else {
+               unsigned int supported_idx = 0;
+
+               intf->num_supported_modes = mode_count;
+               intf->supported_modes = kzalloc(
+                       mode_count * sizeof(struct drm_mode_modeinfo),
+                       GFP_KERNEL);
+               if (!intf->supported_modes) {
+                       dev_err(sunxi.dev, "%s: Failed to allocate mode list\n",
+                               __func__);
+                       goto err_out;
+               }
+               for (idx = 0; idx < NUM_HDMI_VALID_MODES; idx++) {
+                       if (sunxi.disp_ops.hdmi_check_support_mode(
+                               intf->display_id,
+                               hdmi_valid_modes[idx].mode) != 1) {
+                               continue;
+                       }
+                       BUG_ON(supported_idx >= intf->num_supported_modes);
+                       setup_drm_mode(&intf->supported_modes[supported_idx],
+                               hdmi_valid_modes[idx].height,
+                               hdmi_valid_modes[idx].width,
+                               hdmi_valid_modes[idx].refresh);
+                       supported_idx++;
+               }
+               BUG_ON(supported_idx != intf->num_supported_modes);
+       }
+       adf_hotplug_notify_connected(&intf->interface, intf->supported_modes,
+               intf->num_supported_modes);
+       /* Default to first mode */
+       ret = adf_interface_set_mode(&intf->interface,
+               &intf->supported_modes[0]);
+       if (ret) {
+               dev_err(sunxi.dev, "%s: Failed hotplug modeset (%d)\n",
+                       __func__, ret);
+               return ret;
+       }
+       dev_dbg(sunxi.dev, "%s: set connect\n", __func__);
+       return 0;
+
+err_out:
+       intf->num_supported_modes = 0;
+       kfree(intf->supported_modes);
+       intf->supported_modes = NULL;
+       return -1;
+}
+
+static void adf_sunxi_set_hotplug_state(struct sunxi_interface *intf,
+       bool enabled)
+{
+       BUG_ON(intf->disp_type != DISP_OUTPUT_TYPE_HDMI);
+       dev_dbg(sunxi.dev, "%s: hotplug set to %s\n", __func__,
+               enabled ? "enabled" : "disabled");
+       if (enabled) {
+               sunxi.disp_ops.hotplug_enable(intf->display_id, true);
+               sunxi.disp_ops.hotplug_callback(intf->display_id, intf,
+                       sunxi_disp_hotplug_callback);
+               sunxi.disp_ops.hdmi_enable(intf->display_id);
+
+       } else {
+               sunxi.disp_ops.hdmi_disable(intf->display_id);
+               sunxi.disp_ops.hotplug_enable(intf->display_id, false);
+               sunxi.disp_ops.hotplug_callback(intf->display_id, NULL, NULL);
+       }
+
+}
+
+static void adf_sunxi_set_event(struct adf_obj *obj, enum adf_event_type type,
+       bool enabled)
+{
+       switch (obj->type) {
+       case ADF_OBJ_INTERFACE: {
+               struct adf_interface *intf =
+                       container_of(obj, struct adf_interface, base);
+               struct sunxi_interface *sunxi_intf =
+                       container_of(intf, struct sunxi_interface, interface);
+               switch (type) {
+               case ADF_EVENT_VSYNC:
+                       sunxi.disp_ops.vsync_enable(sunxi_intf->display_id, enabled);
+                       break;
+               case ADF_EVENT_HOTPLUG:
+                       adf_sunxi_set_hotplug_state(sunxi_intf, enabled);
+                       break;
+               default:
+                       BUG();
+               }
+               break;
+       }
+       default:
+               BUG();
+       }
+}
+
+
+static disp_tv_mode
+find_matching_disp_tv_mode_id(struct drm_mode_modeinfo *mode)
+{
+       unsigned int idx;
+
+       for (idx = 0; idx < NUM_HDMI_VALID_MODES; idx++) {
+               if (hdmi_valid_modes[idx].width == mode->hdisplay &&
+                   hdmi_valid_modes[idx].height == mode->vdisplay &&
+                   hdmi_valid_modes[idx].refresh == mode->vrefresh) {
+                       return hdmi_valid_modes[idx].mode;
+               }
+       }
+       dev_err(sunxi.dev, "%s: No matching disp_tv_mode for %ux%u@%u\n",
+               __func__, mode->hdisplay, mode->vdisplay, mode->vrefresh);
+       return 0;
+}
+
+static int adf_sunxi_modeset(struct adf_interface *intf,
+       struct drm_mode_modeinfo *mode)
+{
+       disp_tv_mode disp_mode;
+       int err;
+       struct sunxi_interface *sunxi_intf =
+               container_of(intf, struct sunxi_interface, interface);
+
+       dev_dbg(sunxi.dev, "%s: setting %d (type %d) to %ux%u@%u\n", __func__,
+               sunxi_intf->display_id, sunxi_intf->disp_type, mode->hdisplay,
+               mode->vdisplay, mode->vrefresh);
+
+       if (sunxi_intf->disp_type != DISP_OUTPUT_TYPE_HDMI) {
+               dev_dbg(sunxi.dev, "%s: Stub modeset for internal display\n",
+                       __func__);
+               return 0;
+       }
+
+       disp_mode = find_matching_disp_tv_mode_id(mode);
+
+       dev_dbg(sunxi.dev, "%s: HDMI modeset to mode %d\n", __func__,
+               disp_mode);
+
+       err = sunxi.disp_ops.hdmi_disable(sunxi_intf->display_id);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to disable display id %d for modeset\n",
+                       __func__, sunxi_intf->display_id);
+               return -EFAULT;
+       }
+
+       err = sunxi.disp_ops.hdmi_set_mode(sunxi_intf->display_id, disp_mode);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to set mode %ux%u@%u (id %d) to display id %d\n",
+                       __func__, mode->hdisplay, mode->vdisplay,
+                       mode->vrefresh, disp_mode, sunxi_intf->display_id);
+               return -EFAULT;
+       }
+
+       err = sunxi.disp_ops.hdmi_enable(sunxi_intf->display_id);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to enable display id %d after modeset\n",
+                       __func__, sunxi_intf->display_id);
+               return -EFAULT;
+       }
+       return 0;
+}
+
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+
+static int adf_sunxi_alloc_simple_buffer(struct adf_interface *intf, u16 w,
+       u16 h, u32 format, struct dma_buf **dma_buf, u32 *offset, u32 *pitch)
+{
+       int err = 0;
+       u32 bpp = sunxi_format_bpp(format);
+       u32 size = h * w * bpp;
+       struct ion_handle *hdl;
+       struct adf_device *dev = intf->base.parent;
+
+       if (bpp == 0) {
+               dev_err(dev->dev, "%s: unknown format (0x%08x)\n",
+                       __func__, format);
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       hdl = ion_alloc(sunxi.ion_client, size, 0,
+               (1 << sunxi.ion_heap_id), 0);
+       if (IS_ERR(hdl)) {
+               err = PTR_ERR(hdl);
+               dev_err(dev->dev, "%s: ion_alloc failed (%d)\n",
+                       __func__, err);
+               goto err_out;
+       }
+       *dma_buf = ion_share_dma_buf(sunxi.ion_client, hdl);
+       if (IS_ERR(*dma_buf)) {
+               err = PTR_ERR(hdl);
+               dev_err(dev->dev, "%s: ion_share_dma_buf failed (%d)\n",
+                       __func__, err);
+               goto err_free_buffer;
+
+       }
+       *pitch = w * bpp;
+       *offset = 0;
+err_free_buffer:
+       ion_free(sunxi.ion_client, hdl);
+err_out:
+       return err;
+}
+
+static int adf_sunxi_describe_simple_post(struct adf_interface *intf,
+       struct adf_buffer *fb, void *data, size_t *size)
+{
+       *size = 0;
+       return 0;
+}
+
+#endif /* SUPPORT_ADF_SUNXI_FBDEV */
+
+static struct adf_device_ops adf_sunxi_device_ops = {
+       .owner = THIS_MODULE,
+       .base = {
+               .open = adf_sunxi_open,
+               .release = adf_sunxi_release,
+               .ioctl = adf_img_ioctl,
+       },
+       .state_free = adf_sunxi_state_free,
+       .validate = adf_sunxi_validate,
+       .post = adf_sunxi_post,
+};
+
+static struct adf_interface_ops adf_sunxi_interface_ops = {
+       .base = {
+               .supports_event = adf_sunxi_supports_event,
+               .set_event = adf_sunxi_set_event,
+       },
+       .modeset = adf_sunxi_modeset,
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+       .alloc_simple_buffer = adf_sunxi_alloc_simple_buffer,
+       .describe_simple_post = adf_sunxi_describe_simple_post,
+#endif
+};
+
+static struct adf_overlay_engine_ops adf_sunxi_overlay_ops = {
+       .supported_formats = &sunxi_supported_formats[0],
+       .n_supported_formats = NUM_SUPPORTED_FORMATS,
+};
+
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+
+static struct fb_ops adf_sunxi_fb_ops = {
+       .owner = THIS_MODULE,
+       .fb_open = adf_fbdev_open,
+       .fb_release = adf_fbdev_release,
+       .fb_check_var = adf_fbdev_check_var,
+       .fb_set_par = adf_fbdev_set_par,
+       .fb_blank = adf_fbdev_blank,
+       .fb_pan_display = adf_fbdev_pan_display,
+       .fb_fillrect = cfb_fillrect,
+       .fb_copyarea = cfb_copyarea,
+       .fb_imageblit = cfb_imageblit,
+       .fb_mmap = adf_fbdev_mmap,
+};
+#endif
+
+
+
+static void sunxi_debugfs_print_window(struct seq_file *s, const char *prefix,
+       const disp_window *win)
+{
+       if (win->x)
+               seq_printf(s, "%sx\t=\t%u\n", prefix, win->x);
+       if (win->y)
+               seq_printf(s, "%sy\t=\t%u\n", prefix, win->y);
+       seq_printf(s, "%sw\t=\t%u\n", prefix, win->width);
+       seq_printf(s, "%sh\t=\t%u\n", prefix, win->height);
+
+}
+
+static void sunxi_debugfs_print_fb_info(struct seq_file *s, const char *prefix,
+       const disp_fb_info *fb)
+{
+       int i;
+
+       for (i = 0; i < 3; i++)
+               if (fb->addr[i])
+                       seq_printf(s, "%saddr[%d]\t=\t0x%08x\n", prefix, i,
+                               fb->addr[i]);
+       seq_printf(s, "%ssize.w\t=\t%u\n", prefix, fb->size.width);
+       seq_printf(s, "%ssize.h\t=\t%u\n", prefix, fb->size.height);
+       seq_printf(s, "%sformat\t=\t0x%x\n", prefix, fb->format);
+       if (fb->cs_mode)
+               seq_printf(s, "%scs_mode\t=\t0x%x\n", prefix, fb->cs_mode);
+       if (fb->b_trd_src)
+               seq_printf(s, "%sb_trd_src\t=\t0x%x\n", prefix, fb->b_trd_src);
+       if (fb->trd_mode)
+               seq_printf(s, "%strd_mode\t=\t0x%x\n", prefix, fb->trd_mode);
+       for (i = 0; i < 3; i++)
+               if (fb->trd_right_addr[i])
+                       seq_printf(s, "%strd_right_addr[%d]\t=\t0x%x\n", prefix,
+                               i, fb->trd_right_addr[i]);
+       /* Default alpha mode is pre-multiply, so interesting values would
+        * not equal 0x1 */
+       if (fb->pre_multiply != 0x1)
+               seq_printf(s, "%spre_multiply\t=\t0x%x\n", prefix,
+                       fb->pre_multiply);
+
+}
+
+static void sunxi_debugfs_print_layer_info(struct seq_file *s, int layer_num,
+       disp_layer_info *layer_info)
+{
+       int i;
+
+       for (i = 0; i < layer_num; i++) {
+               disp_layer_info *layer = &layer_info[i];
+
+               seq_printf(s, "\tlayer[%d] = {\n", i);
+               if (layer->mode)
+                       seq_printf(s, "\t\tmode\t=\t0x%x\n", layer->mode);
+               seq_printf(s, "\t\tpipe\t=\t0x%x\n", layer->pipe);
+               seq_printf(s, "\t\tzorder\t=\t0x%x\n", layer->zorder);
+               if (layer->alpha_mode)
+                       seq_printf(s, "\t\talpha_mode\t=\t0x%x\n",
+                               layer->alpha_mode);
+               /* The default alpha is 0xff, so interesting values would be
+                * when it does not equal 0xff */
+               if (layer->alpha_value != 0xff)
+                       seq_printf(s, "\t\talpha_value\t=\t0x%x\n",
+                               layer->alpha_value);
+               if (layer->ck_enable)
+                       seq_printf(s, "\t\tck_enable\t=\t0x%x\n",
+                               layer->ck_enable);
+               sunxi_debugfs_print_window(s, "\t\tscreen_win.",
+                       &layer->screen_win);
+               sunxi_debugfs_print_fb_info(s, "\t\tfb.", &layer->fb);
+               if (layer->b_trd_out)
+                       seq_printf(s, "\t\tb_trd_out\t=\t0x%x\n",
+                               layer->b_trd_out);
+               if (layer->out_trd_mode)
+                       seq_printf(s, "\t\tout_trd_mode\t=\t0x%x\n",
+                       layer->out_trd_mode);
+               seq_printf(s, "\t\tid\t=\t%u }\n", layer->id);
+       }
+}
+
+static void sunxi_debugfs_print_config(struct seq_file *s, u32 post_id,
+       struct setup_dispc_data *config)
+{
+       int dpy;
+
+       seq_printf(s, "adf_sunxi post_id %u = {\n", post_id);
+       for (dpy = 0; dpy < 3; dpy++) {
+               seq_printf(s, "\tlayer_num[%d] = %u\n", dpy,
+                       config->layer_num[dpy]);
+               sunxi_debugfs_print_layer_info(s,
+                       config->layer_num[dpy],
+                       &config->layer_info[dpy][0]);
+       }
+       seq_puts(s, "}\n");
+}
+
+static int sunxi_debugfs_show(struct seq_file *s, void *unused)
+{
+       /* FIXME: Should properly lock to reduce the risk of modification
+        * while printing? */
+       int post;
+
+       for (post = 0; post < DEBUG_POST_DUMP_COUNT; post++) {
+               /* Start at current buffer position +1 (oldest post in the
+                * log) */
+               int pos = (sunxi.last_config_pos + post + 1)
+                       % DEBUG_POST_DUMP_COUNT;
+               sunxi_debugfs_print_config(s, sunxi.last_config_id[pos],
+                       &sunxi.last_config[pos]);
+       }
+       return 0;
+}
+
+static int sunxi_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, sunxi_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations adf_sunxi_debugfs_fops = {
+       .open = sunxi_debugfs_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int sunxi_debugfs_val_show(struct seq_file *s, void *unused)
+{
+       int line;
+
+       for (line = 0; line < VALIDATE_LOG_LINES; line++) {
+               int pos = (sunxi.validate_log_position + line + 1)
+                       % VALIDATE_LOG_LINES;
+               seq_puts(s, sunxi.validate_log[pos]);
+       }
+       return 0;
+}
+
+static int sunxi_debugfs_val_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, sunxi_debugfs_val_show, inode->i_private);
+}
+
+static const struct file_operations adf_sunxi_debugfs_val_fops = {
+       .open = sunxi_debugfs_val_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int adf_init_lcd_interface(struct sunxi_interface *interface)
+{
+       int height, width;
+       int refresh = 60;
+       int err;
+
+       interface->connected = true;
+       interface->name = "LCD";
+       interface->adf_type = ADF_INTF_DSI;
+       err = adf_interface_init(&interface->interface, &sunxi.device,
+               interface->adf_type, interface->display_id,
+               ADF_INTF_FLAG_PRIMARY, &adf_sunxi_interface_ops,
+               interface->name);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to init adf interface %d (%d)\n",
+                       __func__, interface->display_id, err);
+               goto err_out;
+       }
+       height = sunxi.disp_ops.get_screen_height(interface->display_id);
+       if (height < 0) {
+               dev_err(sunxi.dev, "%s: Failed to query display height (%d)\n",
+                       __func__, height);
+               err = -EFAULT;
+               goto err_out;
+       }
+       width = sunxi.disp_ops.get_screen_width(interface->display_id);
+       if (width < 0) {
+               dev_err(sunxi.dev, "%s: Failed to query display width (%d)\n",
+                       __func__, width);
+               err = -EFAULT;
+               goto err_out;
+       }
+
+       interface->supported_modes = kzalloc(sizeof(struct drm_mode_modeinfo),
+               GFP_KERNEL);
+       if (!interface->supported_modes) {
+               dev_err(sunxi.dev, "%s: Failed to allocate mode struct\n",
+                       __func__);
+               err = -ENOMEM;
+               goto err_out;
+       }
+       interface->num_supported_modes = 1;
+       setup_drm_mode(&interface->supported_modes[0], height, width, refresh);
+
+       err = adf_hotplug_notify_connected(&interface->interface,
+               interface->supported_modes, interface->num_supported_modes);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to notify connected (%d)\n",
+                       __func__, err);
+               goto err_out;
+       }
+       /* We need to set initial mode */
+       err = adf_interface_set_mode(&interface->interface,
+               &interface->supported_modes[0]);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed initial modeset (%d)\n",
+                       __func__, err);
+               goto err_out;
+       }
+       err = sunxi.disp_ops.vsync_callback(NULL, sunxi_disp_vsync_callback);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to set vsync callback (%d)\n",
+                       __func__, err);
+               goto err_out;
+       }
+       err = 0;
+err_out:
+       return err;
+}
+
+static int adf_init_hdmi_interface(struct sunxi_interface *interface)
+{
+       disp_hotplug_state hotplug_state;
+       int err;
+
+       interface->name = "HDMI";
+       interface->adf_type = ADF_INTF_HDMI;
+       hotplug_state = sunxi.disp_ops.hotplug_state(interface->display_id);
+
+       err = adf_interface_init(&interface->interface, &sunxi.device,
+               interface->adf_type, interface->display_id,
+               ADF_INTF_FLAG_EXTERNAL, &adf_sunxi_interface_ops,
+               interface->name);
+       if (err) {
+               dev_err(sunxi.dev, "%s: Failed to init adf interface %d (%d)\n",
+                       __func__, interface->display_id, err);
+               goto err_out;
+       }
+
+       switch (hotplug_state) {
+       case DISP_HOTPLUG_CONNECT:
+               interface->connected = true;
+               break;
+       default:
+               dev_err(sunxi.dev, "%s: Error querying hotplug state for display id %d\n",
+                       __func__, interface->display_id);
+               hotplug_state = DISP_HOTPLUG_DISCONNECT;
+               /* Fall-thru, act as if disconnected*/
+       case DISP_HOTPLUG_DISCONNECT:
+               interface->connected = false;
+               break;
+       }
+       /* Call the hotplug function to setup modes */
+       sunxi_disp_hotplug_callback(interface, hotplug_state);
+
+       err = 0;
+err_out:
+       return err;
+}
+
+
+static void adf_init_interface(struct sunxi_interface *interface, int id)
+{
+       BUG_ON(!interface);
+       memset(interface, 0, sizeof(*interface));
+       interface->disp_type = sunxi.disp_ops.get_output_type(id);
+       interface->display_id = id;
+       dev_dbg(sunxi.dev, "%s: interface %d\n", __func__, id);
+
+       switch (interface->disp_type) {
+       default:
+               dev_err(sunxi.dev, "%s: Unsupported interface type %d for display %d\n",
+                       __func__, interface->disp_type, id);
+               interface->disp_type = DISP_OUTPUT_TYPE_NONE;
+               /* Fall-thru */
+       case DISP_OUTPUT_TYPE_NONE:
+               dev_dbg(sunxi.dev, "%s: Skipping interface %d - type %d\n",
+                       __func__, id, interface->disp_type);
+               interface->connected = false;
+               return;
+       case DISP_OUTPUT_TYPE_LCD:
+               adf_init_lcd_interface(interface);
+               break;
+       case DISP_OUTPUT_TYPE_HDMI:
+               adf_init_hdmi_interface(interface);
+               break;
+       }
+}
+
+static int adf_sunxi_probe(struct platform_device *pdev)
+{
+       int err = 0;
+       int dpy = 0;
+       int ovl = 0;
+
+       memset(&sunxi.last_config, 0, sizeof(sunxi.last_config));
+
+       atomic_set(&sunxi.postcount, 0);
+       atomic_set(&sunxi.callbackcount, 0);
+       init_waitqueue_head(&sunxi.post_wait_queue);
+
+       sunxi.dev = &pdev->dev;
+
+       err = adf_device_init(&sunxi.device, sunxi.dev,
+               &adf_sunxi_device_ops, "sunxi_device");
+       if (err) {
+               dev_err(sunxi.dev, "Failed to init ADF device (%d)\n",
+                       err);
+               goto err_out;
+       }
+
+       err = disp_get_composer_ops(&sunxi.disp_ops);
+       if (err) {
+               dev_err(sunxi.dev, "Failed to get composer ops (%d)\n",
+                       err);
+               goto err_free_overlays;
+       }
+       /* Set the retire callback */
+       err = sunxi.disp_ops.set_retire_callback(sunxi_retire_callback);
+       if (err) {
+               dev_err(sunxi.dev, "Failed to set retire callback (%d)\n",
+                       err);
+               goto err_free_overlays;
+       }
+       /* The HDMI must be enabled to receive hotplug events, which in turn
+        * must already must have a valid mode set */
+       err = sunxi.disp_ops.hdmi_set_mode(1, DISP_TV_MOD_720P_60HZ);
+       if (err) {
+               dev_warn(sunxi.dev, "Failed to enable initial hdmi mode on dpy 1 (%d)\n",
+                       err);
+               /* Not fatal */
+       }
+       dev_dbg(sunxi.dev, "%s: %d hdmi_enable\n", __func__, __LINE__);
+       err = sunxi.disp_ops.hdmi_enable(1);
+       if (err) {
+               dev_warn(sunxi.dev, "Failed to enable hdmi on dpy 1 (%d)\n",
+                       err);
+               /* Not fatal */
+       }
+
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++)
+               adf_init_interface(&sunxi.interfaces[dpy], dpy);
+
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               for (ovl = 0; ovl < NUM_OVERLAYS; ovl++) {
+                       err = adf_overlay_engine_init(
+                               &sunxi.overlays[dpy][ovl].overlay,
+                               &sunxi.device, &adf_sunxi_overlay_ops,
+                               "sunxi_overlay_%d-%d", dpy, ovl);
+                       if (err) {
+                               dev_err(sunxi.dev, "Failed to init overlay %d-%d (%d)\n",
+                                       dpy, ovl, err);
+                               goto err_free_overlays;
+                       }
+                       err = adf_attachment_allow(&sunxi.device,
+                               &sunxi.overlays[dpy][ovl].overlay,
+                               &sunxi.interfaces[dpy].interface);
+
+                       if (err) {
+                               dev_err(sunxi.dev, "Failed to attach overlay %d-%d (%d)\n",
+                                       dpy, ovl, err);
+                               goto err_free_overlays;
+                       }
+               }
+       }
+
+
+       sunxi.ion_heap_id = ION_HEAP_TYPE_CARVEOUT;
+
+       sunxi.ion_client = ion_client_create(idev, "adf_sunxi");
+
+       if (IS_ERR(sunxi.ion_client)) {
+               err = PTR_ERR(sunxi.ion_client);
+               dev_err(sunxi.dev, "Failed to create ion client (%d)\n",
+                       err);
+               goto err_free_overlays;
+       }
+
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+       err = adf_fbdev_init(&sunxi.fbdev,
+               &sunxi.interfaces[DISPLAY_INTERNAL].interface,
+               &sunxi.overlays[DISPLAY_INTERNAL].overlay,
+               sunxi.interfaces[DISPLAY_INTERNAL].width,
+               sunxi.interfaces[DISPLAY_INTERNAL].height,
+               DRM_FORMAT_BGRA8888,
+               &adf_sunxi_fb_ops,
+               "adf_sunxi_fb");
+       if (err) {
+               dev_err(sunxi.dev, "Failed to init ADF fbdev (%d)\n", err);
+               goto err_free_ion_client;
+       }
+#endif
+
+       sunxi.debugfs_config_file = debugfs_create_file("adf_debug", S_IRUGO,
+               NULL, NULL, &adf_sunxi_debugfs_fops);
+
+       sunxi.debugfs_val_log = debugfs_create_file("adf_val_log", S_IRUGO,
+               NULL, NULL, &adf_sunxi_debugfs_val_fops);
+       dev_err(sunxi.dev, "Successfully loaded adf_sunxi\n");
+
+       return 0;
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+err_free_ion_client:
+#endif
+       ion_client_destroy(sunxi.ion_client);
+err_free_overlays:
+       for (; dpy > 0; dpy--) {
+               if (sunxi.interfaces[dpy-1].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               for (; ovl > 0; ovl--) {
+                       adf_overlay_engine_destroy(
+                               &sunxi.overlays[dpy-1][ovl-1].overlay);
+               }
+       }
+       dpy = MAX_DISPLAYS;
+       for (; dpy > 0; dpy--) {
+               if (sunxi.interfaces[dpy-1].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               if (sunxi.interfaces[dpy-1].disp_type == DISP_OUTPUT_TYPE_HDMI)
+                       adf_sunxi_set_hotplug_state(&sunxi.interfaces[dpy],
+                               false);
+               adf_interface_destroy(&sunxi.interfaces[dpy-1].interface);
+       }
+       adf_device_destroy(&sunxi.device);
+err_out:
+       debugfs_remove(sunxi.debugfs_config_file);
+       sunxi.debugfs_config_file = NULL;
+       debugfs_remove(sunxi.debugfs_val_log);
+       sunxi.debugfs_val_log = NULL;
+       return err;
+}
+
+static int adf_sunxi_remove(struct platform_device *pdev)
+{
+       int dpy;
+       int ovl;
+#ifdef SUPPORT_ADF_SUNXI_FBDEV
+       adf_fbdev_destroy(&sunxi.fbdev);
+#endif
+       debugfs_remove(sunxi.debugfs_config_file);
+       sunxi.debugfs_config_file = NULL;
+       debugfs_remove(sunxi.debugfs_val_log);
+       sunxi.debugfs_val_log = NULL;
+       ion_client_destroy(sunxi.ion_client);
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               for (ovl = 0; ovl < NUM_OVERLAYS; ovl++)
+                       adf_overlay_engine_destroy(
+                               &sunxi.overlays[dpy][ovl].overlay);
+       }
+       for (dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_NONE)
+                       continue;
+               if (sunxi.interfaces[dpy].disp_type == DISP_OUTPUT_TYPE_HDMI)
+                       adf_sunxi_set_hotplug_state(&sunxi.interfaces[dpy],
+                               false);
+               adf_interface_destroy(&sunxi.interfaces[dpy].interface);
+       }
+       adf_device_destroy(&sunxi.device);
+       return 0;
+}
+
+static void adf_sunxi_device_release(struct device *dev)
+{
+       /* NOOP */
+       return;
+}
+
+static int adf_sunxi_device_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       return 0;
+}
+static int adf_sunxi_device_resume(struct platform_device *pdev)
+{
+       return 0;
+}
+
+struct platform_device adf_sunxi_platform_device =
+{
+       .name = "adf_sunxi",
+       .id = -1,
+       .dev.release = adf_sunxi_device_release,
+};
+
+struct platform_driver adf_sunxi_platform_driver =
+{
+       .driver.name = "adf_sunxi",
+       .probe = adf_sunxi_probe,
+       .remove = adf_sunxi_remove,
+       .suspend = adf_sunxi_device_suspend,
+       .resume = adf_sunxi_device_resume,
+};
+
+static int __init adf_sunxi_init(void)
+{
+       platform_device_register(&adf_sunxi_platform_device);
+       platform_driver_register(&adf_sunxi_platform_driver);
+       return 0;
+}
+
+static void __exit adf_sunxi_exit(void)
+{
+       platform_device_unregister(&adf_sunxi_platform_device);
+       platform_driver_unregister(&adf_sunxi_platform_driver);
+}
+
+module_init(adf_sunxi_init);
+module_exit(adf_sunxi_exit);
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/adf_sunxi.h
new file mode 100644 (file)
index 0000000..cc1956a
--- /dev/null
@@ -0,0 +1,84 @@
+/*************************************************************************/ /*!
+@File           adf_sunxi.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#ifndef _ADF_SUNXI_
+#define _ADF_SUNXI_
+
+extern struct ion_device *idev;
+
+#include <video/drv_display.h>
+#define DISPLAY_INTERNAL 0
+#define DISPLAY_HDMI 1
+#define DISPLAY_EDP 2
+
+struct setup_dispc_data {
+       int                     layer_num[3];
+       disp_layer_info         layer_info[3][4];
+       void                    *hConfigData;
+};
+
+struct disp_composer_ops {
+       int (*get_screen_width)(u32 screen_id);
+       int (*get_screen_height)(u32 screen_id);
+       int (*get_output_type)(u32 screen_id);
+       int (*hdmi_enable)(u32 screen_id);
+       int (*hdmi_disable)(u32 screen_id);
+       int (*hdmi_set_mode)(u32 screen_id,  disp_tv_mode mode);
+       int (*hdmi_get_mode)(u32 screen_id);
+       int (*hdmi_check_support_mode)(u32 screen_id,  u8 mode);
+       int (*is_support_scaler_layer)(unsigned int screen_id,
+               unsigned int src_w, unsigned int src_h, unsigned int out_w,
+               unsigned int out_h);
+       int (*dispc_gralloc_queue)(struct setup_dispc_data *psDispcData);
+       int (*set_retire_callback)(void (*retire_fn)(void));
+       int (*vsync_enable)(u32 screen_id, bool enable);
+       int (*vsync_callback)(void *user_data, void (*cb_fn)(void *user_data,
+               u32 screen_id));
+       int (*hotplug_enable)(u32 screen_id, bool enable);
+       int (*hotplug_callback)(u32 screen_id, void *user_data,
+               hdmi_hotplug_callback_function cb_fn);
+       int (*hotplug_state)(u32 screen_id);
+
+};
+extern int disp_get_composer_ops(struct disp_composer_ops *ops);
+
+#endif
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo.c
new file mode 100644 (file)
index 0000000..f79839d
--- /dev/null
@@ -0,0 +1,1578 @@
+/*************************************************************************/ /*!
+@File           apollo.c
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+/*
+ * This is a device driver for the apollo testchip framework. It creates
+ * platform devices for the pdp and rogue sub-devices, and exports functions
+ * to manage the shared interrupt handling
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+
+#include <asm/mtrr.h>
+
+#include "apollo_drv.h"
+
+#include "apollo_regs.h"
+#include "tcf_clk_ctrl.h"
+#include "tcf_pll.h"
+
+#include "pvrmodule.h"
+#include "rgxdefs_km.h"
+
+#if defined(SUPPORT_ION)
+#include "ion_lma_heap.h"
+#endif
+
+#define DRV_NAME "apollo"
+
+/* How much memory to give to the PDP heap (used for pdp buffers). */
+#define APOLLO_PDP_MEM_SIZE            (384*1024*1024)
+
+#define PCI_VENDOR_ID_POWERVR          0x1010
+#define DEVICE_ID_PCI_APOLLO_FPGA      0x1CF1
+#define DEVICE_ID_PCIE_APOLLO_FPGA     0x1CF2
+
+#define DCPDP_REG_PCI_BASENUM          (0)
+#define APOLLO_MEM_PCI_BASENUM         (2)
+
+#define APOLLO_INTERRUPT_FLAG_PDP      (1 << PDP1_INT_SHIFT)
+#define APOLLO_INTERRUPT_FLAG_ROGUE    (1 << EXT_INT_SHIFT)
+
+MODULE_DESCRIPTION("APOLLO testchip framework driver");
+
+static int apollo_core_clock = RGX_TC_CORE_CLOCK_SPEED;
+static int apollo_mem_clock = RGX_TC_MEM_CLOCK_SPEED;
+
+module_param(apollo_core_clock, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(apollo_core_clock, "Apollo Rogue core clock speed");
+module_param(apollo_mem_clock, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(apollo_mem_clock, "Apollo memory clock speed");
+
+#define APOLLO_ION_HEAP_COUNT 3
+
+struct apollo_device {
+       struct pci_dev *pdev;
+       resource_size_t tcf_register_resource;
+       void __iomem *tcf_registers;
+       spinlock_t interrupt_handler_lock;
+       spinlock_t interrupt_enable_lock;
+
+       struct {
+               bool enabled;
+               void (*handler_function)(void *);
+               void *handler_data;
+       } interrupt_handlers[APOLLO_INTERRUPT_COUNT];
+
+       struct platform_device *pdp_dev;
+       struct platform_device *rogue_dev;
+
+
+       resource_size_t apollo_mem_base;
+       resource_size_t apollo_mem_size;
+
+       resource_size_t pdp_heap_mem_base;
+       resource_size_t pdp_heap_mem_size;
+       resource_size_t rogue_heap_mem_base;
+       resource_size_t rogue_heap_mem_size;
+
+#if defined(SUPPORT_ION)
+       struct ion_device *ion_device;
+       struct ion_heap *ion_heaps[APOLLO_ION_HEAP_COUNT];
+       int ion_heap_count;
+#endif
+};
+
+static int request_pci_io_addr(struct pci_dev *pdev, u32 index,
+       resource_size_t offset, resource_size_t length)
+{
+       resource_size_t start, end;
+       start = pci_resource_start(pdev, index);
+       end = pci_resource_end(pdev, index);
+
+       if ((start + offset + length - 1) > end)
+               return -EIO;
+       if (pci_resource_flags(pdev, index) & IORESOURCE_IO) {
+               if (request_region(start + offset, length, DRV_NAME) == NULL)
+                       return -EIO;
+       } else {
+               if (request_mem_region(start + offset, length, DRV_NAME)
+                       == NULL)
+                       return -EIO;
+       }
+       return 0;
+}
+
+static void release_pci_io_addr(struct pci_dev *pdev, u32 index,
+       resource_size_t start, resource_size_t length)
+{
+       if (pci_resource_flags(pdev, index) & IORESOURCE_IO)
+               release_region(start, length);
+       else
+               release_mem_region(start, length);
+}
+
+static int apollo_set_clocks(struct apollo_device *apollo)
+{
+       int err = 0;
+       u32 val;
+
+       resource_size_t pll_clock_resource;
+       void __iomem *pll_regs;
+
+       err = request_pci_io_addr(apollo->pdev, SYS_APOLLO_REG_PCI_BASENUM,
+               SYS_APOLLO_REG_PLL_OFFSET, SYS_APOLLO_REG_PLL_SIZE);
+       if (err) {
+               dev_err(&apollo->pdev->dev,
+                       "Failed to request apollo PLL register region\n");
+               goto err_out;
+       }
+       pll_clock_resource =
+               pci_resource_start(apollo->pdev, SYS_APOLLO_REG_PCI_BASENUM)
+                       + SYS_APOLLO_REG_PLL_OFFSET;
+       pll_regs = ioremap_nocache(pll_clock_resource, SYS_APOLLO_REG_PLL_SIZE);
+       if (!pll_regs) {
+               dev_err(&apollo->pdev->dev,
+                       "Failed to map apollo PLL registers\n");
+               err = -EIO;
+               goto err_release_registers;
+       }
+
+#if !((RGX_BVNC_KM_B == 1) && (RGX_BVNC_KM_V == 82) && \
+         (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 5))
+       /* This is if 0 out since the current FPGA builds do not like their core
+        * clocks being set (it takes apollo down). */
+       val = apollo_core_clock / 1000000;
+       iowrite32(val, pll_regs + TCF_PLL_PLL_CORE_CLK0);
+       val = 0x1 << PLL_CORE_DRP_GO_SHIFT;
+       iowrite32(val, pll_regs + TCF_PLL_PLL_CORE_DRP_GO);
+#endif
+
+       val = apollo_mem_clock / 1000000;
+       iowrite32(val, pll_regs + TCF_PLL_PLL_MEMIF_CLK0);
+       val = 0x1 << PLL_MEM_DRP_GO_SHIFT;
+       iowrite32(val, pll_regs + TCF_PLL_PLL_MEM_DRP_GO);
+
+       dev_dbg(&apollo->pdev->dev, "Setting clocks to %uMHz/%uMHz\n",
+                        apollo_core_clock / 1000000,
+                        apollo_mem_clock / 1000000);
+       udelay(400);
+
+       iounmap(pll_regs);
+err_release_registers:
+       release_pci_io_addr(apollo->pdev, SYS_APOLLO_REG_PCI_BASENUM,
+               pll_clock_resource, SYS_APOLLO_REG_PLL_SIZE);
+err_out:
+       return err;
+}
+
+static int mtrr_setup(struct pci_dev *pdev,
+                     resource_size_t mem_start,
+                     resource_size_t mem_size)
+{
+       int err = 0;
+       int mtrr;
+
+       /* Reset MTRR */
+       mtrr = mtrr_add(mem_start, mem_size, MTRR_TYPE_UNCACHABLE, 0);
+       if (mtrr < 0) {
+               dev_err(&pdev->dev, "%d - %s: mtrr_add failed (%d)\n",
+                       __LINE__, __func__, mtrr);
+               err = mtrr;
+               goto err_out;
+       }
+
+       err = mtrr_del(mtrr, mem_start, mem_size);
+       if (err < 0) {
+               dev_err(&pdev->dev, "%d - %s: mtrr_del failed (%d)\n",
+                       __LINE__, __func__, err);
+               goto err_out;
+       }
+
+       mtrr = mtrr_add(mem_start, mem_size, MTRR_TYPE_WRBACK, 0);
+       if (mtrr < 0) {
+               /* Stop, but not an error as this may be already be setup */
+               dev_dbg(&pdev->dev, "%d - %s: mtrr_del failed (%d) - probably means the mtrr is already setup\n",
+                       __LINE__, __func__, err);
+               err = 0;
+               goto err_out;
+       }
+
+       err = mtrr_del(mtrr, mem_start, mem_size);
+       if (err < 0) {
+               dev_err(&pdev->dev, "%d - %s: mtrr_del failed (%d)\n",
+                       __LINE__, __func__, err);
+               goto err_out;
+       }
+
+       if (mtrr == 0) {
+               /* Replace 0 with a non-overlapping WRBACK mtrr */
+               err = mtrr_add(0, mem_start, MTRR_TYPE_WRBACK, 0);
+               if (err < 0) {
+                       dev_err(&pdev->dev, "%d - %s: mtrr_add failed (%d)\n",
+                               __LINE__, __func__, err);
+                       goto err_out;
+               }
+       }
+
+       mtrr = mtrr_add(mem_start, mem_size, MTRR_TYPE_WRCOMB, 0);
+
+       if (mtrr < 0)
+               dev_err(&pdev->dev, "%d - %s: mtrr_add failed (%d)\n",
+                       __LINE__, __func__, mtrr);
+       err = 0;
+
+err_out:
+       return err;
+}
+
+static void apollo_init_memory(struct apollo_device *apollo)
+{
+       u32 val;
+
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_TEST_CTRL);
+       val &= ~(ADDRESS_FORCE_MASK | PCI_TEST_MODE_MASK | HOST_ONLY_MODE_MASK
+               | HOST_PHY_MODE_MASK);
+       val |= (0x1 << ADDRESS_FORCE_SHIFT);
+       iowrite32(val, apollo->tcf_registers + TCF_CLK_CTRL_TEST_CTRL);
+}
+
+static void apollo_deinit_memory(struct apollo_device *apollo)
+{
+       iowrite32(0x1 << ADDRESS_FORCE_SHIFT,
+               apollo->tcf_registers + TCF_CLK_CTRL_TEST_CTRL);
+}
+
+static void apollo_devres_release(struct device *dev, void *res)
+{
+       /* No extra cleanup needed */
+}
+
+#if ((RGX_BVNC_KM_B == 1) && (RGX_BVNC_KM_V == 82) && \
+       (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 5)) || \
+    ((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+       (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+
+static int is_interface_aligned(u32 eyes, u32 clk_taps, u32 train_ack)
+{
+       u32     max_eye_start = eyes >> 16;
+       u32     min_eye_end   = eyes & 0xffff;
+
+       /* If either the training or training ack failed, we haven't aligned */
+       if (!(clk_taps & 0x10000) || !(train_ack & 0x100))
+               return 0;
+
+       /* If the max eye >= min eye it means the readings are nonsense */
+       if (max_eye_start >= min_eye_end)
+               return 0;
+
+       /* If we failed the ack pattern more than 4 times */
+       if (((train_ack & 0xf0) >> 4) > 4)
+               return 0;
+
+       /* If there is less than 7 taps (240ps @40ps/tap, this number should be
+        * lower for the fpga, since its taps are bigger We should really
+        * calculate the "7" based on the interface clock speed. */
+       if ((min_eye_end - max_eye_start) < 7)
+               return 0;
+
+       return 1;
+}
+
+static u32 sai_read(struct apollo_device *apollo, u32 addr)
+{
+       iowrite32(0x200 | addr, apollo->tcf_registers + 0x300);
+       iowrite32(0x1 | addr, apollo->tcf_registers + 0x318);
+       return ioread32(apollo->tcf_registers + 0x310);
+}
+
+static void spi_write(struct apollo_device *apollo,
+                                         u32 off, u32 val)
+{
+       iowrite32(off, apollo->tcf_registers +
+                         TCF_CLK_CTRL_TCF_SPI_MST_ADDR_RDNWR);
+       iowrite32(val, apollo->tcf_registers +
+                         TCF_CLK_CTRL_TCF_SPI_MST_WDATA);
+       iowrite32(TCF_SPI_MST_GO_MASK, apollo->tcf_registers +
+                         TCF_CLK_CTRL_TCF_SPI_MST_GO);
+       udelay(1000);
+}
+
+static int spi_read(struct apollo_device *apollo,
+                                       u32 off, u32 *val)
+{
+       int cnt = 0;
+
+       iowrite32(0x40000 | off, apollo->tcf_registers +
+                         TCF_CLK_CTRL_TCF_SPI_MST_ADDR_RDNWR);
+       iowrite32(TCF_SPI_MST_GO_MASK, apollo->tcf_registers +
+                         TCF_CLK_CTRL_TCF_SPI_MST_GO);
+       udelay(100);
+
+       while ((ioread32(apollo->tcf_registers +
+                               TCF_CLK_CTRL_TCF_SPI_MST_STATUS) != 0x08) &&
+                  (cnt < 10000))
+               ++cnt;
+
+       if (cnt == 10000) {
+               dev_err(&apollo->pdev->dev,
+                       "spi_read: Time out reading SPI register (0x%x)\n",
+                       off);
+               return -1;
+       }
+
+       *val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_TCF_SPI_MST_RDATA);
+
+       return 0;
+}
+
+static int apollo_hard_reset(struct apollo_device *apollo)
+{
+       u32 reg;
+       u32 reg_reset_n;
+
+       /* For displaying some build info */
+       u32 build_inc;
+       u32 build_owner;
+
+       int aligned = 0;
+       int reset_cnt = 0;
+
+       /* This is required for SPI reset which is not yet implemented. */
+       /*u32 aux_reset_n;*/
+
+#if !((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+        (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       /* Power down */
+       reg = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+       reg &= ~DUT_CTRL_VCC_0V9EN;
+       reg &= ~DUT_CTRL_VCC_1V8EN;
+       reg |= DUT_CTRL_VCC_IO_INH;
+       reg |= DUT_CTRL_VCC_CORE_INH;
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+       msleep(500);
+#endif
+
+       /* Set clock speed here, before reset. */
+       apollo_set_clocks(apollo);
+
+       /* Put DCM, DUT, DDR, PDP1, and PDP2 into reset */
+       reg_reset_n  = (0x1 << GLB_CLKG_EN_SHIFT);
+       reg_reset_n |= (0x1 << SCB_RESETN_SHIFT);
+       iowrite32(reg_reset_n, apollo->tcf_registers +
+                 TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+       msleep(100);
+
+#if !((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+        (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       /* Enable the voltage control regulators on DUT */
+       reg = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+       reg |= DUT_CTRL_VCC_0V9EN;
+       reg |= DUT_CTRL_VCC_1V8EN;
+       reg &= ~DUT_CTRL_VCC_IO_INH;
+       reg &= ~DUT_CTRL_VCC_CORE_INH;
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+       msleep(300);
+#endif
+
+       /* Take DCM, DDR, PDP1, and PDP2 out of reset */
+       reg_reset_n |= (0x1 << DDR_RESETN_SHIFT);
+       reg_reset_n |= (0x1 << DUT_DCM_RESETN_SHIFT);
+       reg_reset_n |= (0x1 << PDP1_RESETN_SHIFT);
+       reg_reset_n |= (0x1 << PDP2_RESETN_SHIFT);
+       iowrite32(reg_reset_n, apollo->tcf_registers +
+                 TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+
+#if !((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+        (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       /* Set ODT to a specific value that seems to provide the most stable
+        * signals. */
+       spi_write(apollo, 0x11, 0x413130);
+#endif
+
+       /* Take DUT out of reset */
+       reg_reset_n |= (0x1 << DUT_RESETN_SHIFT);
+       iowrite32(reg_reset_n, apollo->tcf_registers +
+                 TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+       msleep(100);
+
+       /* Try to enable the core clock PLL */
+       spi_write(apollo, 0x1, 0x0);
+       reg  = ioread32(apollo->tcf_registers + 0x320);
+       reg |= 0x1;
+       iowrite32(reg, apollo->tcf_registers + 0x320);
+       reg &= 0xfffffffe;
+       iowrite32(reg, apollo->tcf_registers + 0x320);
+       msleep(1000);
+
+       if (spi_read(apollo, 0x2, &reg))
+               dev_err(&apollo->pdev->dev,
+                               "Unable to read PLL status\n");
+
+       if (reg == 0x1) {
+               /* Select DUT PLL as core clock */
+               reg  = ioread32(apollo->tcf_registers + 0x108);
+               reg &= 0xfffffff7;
+               iowrite32(reg, apollo->tcf_registers + 0x108);
+       } else {
+               dev_err(&apollo->pdev->dev,
+                       "PLL has failed to lock, status = %x\n", reg);
+       }
+
+       while (!aligned && reset_cnt < 10) {
+               int bank;
+               u32 eyes;
+               u32 clk_taps;
+               u32 train_ack;
+
+               ++reset_cnt;
+
+               /* Reset the DUT to allow the SAI to retrain */
+               reg_reset_n &= ~(0x1 << DUT_RESETN_SHIFT);
+               iowrite32(reg_reset_n, apollo->tcf_registers +
+                         TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+               udelay(100);
+               reg_reset_n |= (0x1 << DUT_RESETN_SHIFT);
+               iowrite32(reg_reset_n, apollo->tcf_registers +
+                         TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+               udelay(100);
+
+               /* Assume alignment passed, if any bank fails on either DUT or
+                * FPGA we will set this to false and try again for a max of 10
+                * times. */
+               aligned = 1;
+
+               /* For each of the banks */
+               for (bank = 0; bank < 10; bank++) {
+                       /* Check alignment on the DUT */
+                       u32 bank_base = 0x7000 + (0x1000 * bank);
+
+                       spi_read(apollo, bank_base + 0x4, &eyes);
+                       spi_read(apollo, bank_base + 0x3, &clk_taps);
+                       spi_read(apollo, bank_base + 0x6, &train_ack);
+
+                       if (!is_interface_aligned(eyes, clk_taps, train_ack)) {
+                               dev_warn(&apollo->pdev->dev, "Alignment check failed, retrying\n");
+                               aligned = 0;
+                               break;
+                       }
+
+                       /* Check alignment on the FPGA */
+                       bank_base = 0xb0 + (0x10 * bank);
+
+                       eyes = sai_read(apollo, bank_base + 0x4);
+                       clk_taps = sai_read(apollo, bank_base + 0x3);
+                       train_ack = sai_read(apollo, bank_base + 0x6);
+
+                       if (!is_interface_aligned(eyes, clk_taps, train_ack)) {
+                               dev_warn(&apollo->pdev->dev, "Alignment check failed, retrying\n");
+                               aligned = 0;
+                               break;
+                       }
+               }
+       }
+
+       if (!aligned) {
+               dev_err(&apollo->pdev->dev,
+                               "Unable to intialise the testchip (interface alignment failure), "
+                               "please restart the system.\n");
+               return -1;
+       }
+
+       if (reset_cnt > 1) {
+               dev_dbg(&apollo->pdev->dev, "Note: The testchip required more than one reset to find a good interface alignment!\n");
+               dev_dbg(&apollo->pdev->dev, "      This should be harmless, but if you do suspect foul play, please reset the machine.\n");
+               dev_dbg(&apollo->pdev->dev, "      If you continue to see this message you may want to report it to IMGWORKS.\n");
+       }
+
+#if !((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+        (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       /* Enable the temperature sensor */
+       spi_write(apollo, 0xc, 0); /* power up */
+       spi_write(apollo, 0xc, 2); /* reset */
+       spi_write(apollo, 0xc, 6); /* init & run */
+#endif
+
+       /* Check the build */
+       reg = ioread32(apollo->tcf_registers + 0x10);
+       build_inc = (reg >> 12) & 0xff;
+       build_owner = (reg >> 20) & 0xf;
+
+       if (build_inc) {
+               dev_alert(&apollo->pdev->dev, "BE WARNED: You are not running a tagged release of the FPGA image!\n");
+               dev_alert(&apollo->pdev->dev, "Owner: 0x%01x, Inc: 0x%02x\n",
+                         build_owner, build_inc);
+       }
+
+       dev_dbg(&apollo->pdev->dev, "FPGA Release: %u.%02u\n", reg >> 8 & 0xf,
+               reg & 0xff);
+
+       return 0;
+}
+
+static int apollo_hw_init(struct apollo_device *apollo)
+{
+       apollo_hard_reset(apollo);
+       apollo_init_memory(apollo);
+
+#if ((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+        (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       {       
+               u32 reg;
+               /* Enable ASTC via SPI */
+               if (spi_read(apollo, 0xf, &reg)) {
+                       dev_err(&apollo->pdev->dev, "Failed to read apollo ASTC register\n");
+                       goto err_out;
+               }    
+
+               reg |= 0x1 << 4;
+               spi_write(apollo, 0xf, reg);
+       }
+err_out:
+#endif 
+
+       return 0;
+}
+
+static void apollo_hw_fini(struct apollo_device *apollo)
+{
+       apollo_deinit_memory(apollo);
+}
+
+int apollo_sys_info(struct device *dev, u32 *tmp, u32 *pll)
+{
+       int err = -ENODEV;
+       struct apollo_device *apollo = devres_find(dev, apollo_devres_release,
+               NULL, NULL);
+
+       if (!apollo) {
+               dev_err(dev, "No apollo device resources found\n");
+               goto err_out;
+       }
+
+#if !((RGX_BVNC_KM_B == 4) && (RGX_BVNC_KM_V == 31) && \
+         (RGX_BVNC_KM_N == 4) && (RGX_BVNC_KM_C == 55))
+       if (spi_read(apollo, TCF_TEMP_SENSOR_SPI_OFFSET, tmp)) {
+               dev_err(dev, "Failed to read apollo temperature sensor\n");
+               goto err_out;
+       }
+       
+       *tmp = TCF_TEMP_SENSOR_TO_C(*tmp);
+#endif
+
+       if (spi_read(apollo, 0x2, pll)) {
+               dev_err(dev, "Failed to read PLL status\n");
+               goto err_out;
+       }
+
+       err = 0;
+err_out:
+       return err;
+}
+EXPORT_SYMBOL(apollo_sys_info);
+
+#else
+
+static int iopol32(u32 val, u32 mask, void __iomem *addr)
+{
+       int polnum;
+       for (polnum = 0; polnum < 500; polnum++) {
+               if ((ioread32(addr) & mask) == val)
+                       break;
+               /* NOTE: msleep() < 20 ms may sleep up to 20ms */
+               msleep(1);
+       }
+       if (polnum == 500) {
+               pr_err(DRV_NAME " iopol32 timeout\n");
+               return -ETIME;
+       }
+       return 0;
+}
+
+
+static int apollo_rogue_bist(struct apollo_device *apollo)
+{
+       int err = 0;
+       void __iomem *rogue_regs;
+       resource_size_t regs_resource;
+       resource_size_t regs_resource_size;
+       int i;
+       int instance;
+
+       regs_resource =
+               pci_resource_start(apollo->pdev, SYS_RGX_REG_PCI_BASENUM);
+       regs_resource_size =
+               pci_resource_len(apollo->pdev, SYS_RGX_REG_PCI_BASENUM);
+
+       if (regs_resource_size < SYS_RGX_REG_REGION_SIZE) {
+               dev_err(&apollo->pdev->dev,
+                       "Rogue register region too small\n");
+               err = -EIO;
+               goto err_out;
+       }
+
+       err = pci_request_region(apollo->pdev, SYS_RGX_REG_PCI_BASENUM,
+               DRV_NAME);
+       if (err) {
+               dev_err(&apollo->pdev->dev,
+                       "Failed to request rogue register region\n");
+               goto err_out;
+       }
+       rogue_regs = ioremap_nocache(regs_resource, regs_resource_size);
+       if (!rogue_regs) {
+               dev_err(&apollo->pdev->dev,
+                       "Failed to map rogue register region\n");
+               err = -EIO;
+               goto err_release_registers;
+       }
+       /* Force clocks on */
+       iowrite32(0x55555555, rogue_regs + 0);
+       iowrite32(0x55555555, rogue_regs + 4);
+
+       iopol32(0x05000000, 0x05000000, rogue_regs + 0xa18);
+       iowrite32(0x048000b0, rogue_regs + 0xa10);
+       iowrite32(0x55111111, rogue_regs + 0xa08);
+       iopol32(0x05000000, 0x05000000, rogue_regs + 0xa18);
+
+       /* Clear PDS CSRM and USRM to prevent ERRORs at end of test */
+       iowrite32(0x1, rogue_regs + 0x630);
+       iowrite32(0x1, rogue_regs + 0x648);
+       iowrite32(0x1, rogue_regs + 0x608);
+
+       /* Run BIST for SLC (43) */
+       /* Reset BIST */
+       iowrite32(0x8, rogue_regs + 0x7000);
+       udelay(100);
+
+       /* Clear BIST controller */
+       iowrite32(0x10, rogue_regs + 0x7000);
+       iowrite32(0, rogue_regs + 0x7000);
+       udelay(100);
+
+       for (i = 0; i < 3; i++) {
+               u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+               /* Start BIST */
+               iowrite32(0x4, rogue_regs + 0x7000);
+
+               udelay(100);
+
+               /* Wait for pause */
+               iopol32(polval, polval, rogue_regs + 0x7000);
+       }
+       udelay(100);
+
+       /* Check results for 43 RAMs */
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7010);
+       iopol32(0x7, 0x7, rogue_regs + 0x7014);
+
+       iowrite32(8, rogue_regs + 0x7000);
+       iowrite32(0, rogue_regs + 0x7008);
+       iowrite32(6, rogue_regs + 0x7000);
+       iopol32(0x00010000, 0x00010000, rogue_regs + 0x7000);
+       udelay(100);
+
+       iopol32(0, ~0U, rogue_regs + 0x75B0);
+       iopol32(0, ~0U, rogue_regs + 0x75B4);
+       iopol32(0, ~0U, rogue_regs + 0x75B8);
+       iopol32(0, ~0U, rogue_regs + 0x75BC);
+       iopol32(0, ~0U, rogue_regs + 0x75C0);
+       iopol32(0, ~0U, rogue_regs + 0x75C4);
+       iopol32(0, ~0U, rogue_regs + 0x75C8);
+       iopol32(0, ~0U, rogue_regs + 0x75CC);
+
+       /* Sidekick */
+       iowrite32(8, rogue_regs + 0x7040);
+       udelay(100);
+
+       iowrite32(0x10, rogue_regs + 0x7040);
+       udelay(100);
+
+       for (i = 0; i < 3; i++) {
+               u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+               iowrite32(4, rogue_regs + 0x7040);
+               udelay(100);
+               iopol32(polval, polval, rogue_regs + 0x7040);
+       }
+
+       udelay(100);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7050);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7054);
+       iopol32(0x1, 0x1, rogue_regs + 0x7058);
+
+       /* USC */
+       for (instance = 0; instance < 4; instance++) {
+               iowrite32(instance, rogue_regs + 0x8010);
+
+               iowrite32(8, rogue_regs + 0x7088);
+               udelay(100);
+
+               iowrite32(0x10, rogue_regs + 0x7088);
+               udelay(100);
+
+               for (i = 0; i < 3; i++) {
+                       u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+                       iowrite32(4, rogue_regs + 0x7088);
+                       udelay(100);
+                       iopol32(polval, polval, rogue_regs + 0x7088);
+               }
+
+               udelay(100);
+               iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7098);
+               iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x709c);
+               iopol32(0x3f, 0x3f, rogue_regs + 0x70a0);
+       }
+
+       /* tpumcul0 DustA and DustB */
+       for (instance = 0; instance < 2; instance++) {
+               iowrite32(instance, rogue_regs + 0x8018);
+
+               iowrite32(8, rogue_regs + 0x7380);
+               udelay(100);
+
+               iowrite32(0x10, rogue_regs + 0x7380);
+               udelay(100);
+
+               for (i = 0; i < 3; i++) {
+                       u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+                       iowrite32(4, rogue_regs + 0x7380);
+                       udelay(100);
+                       iopol32(polval, polval, rogue_regs + 0x7380);
+               }
+
+               udelay(100);
+               iopol32(0x1fff, 0x1fff, rogue_regs + 0x7390);
+       }
+
+       /* TA */
+       iowrite32(8, rogue_regs + 0x7500);
+       udelay(100);
+
+       iowrite32(0x10, rogue_regs + 0x7500);
+       udelay(100);
+
+       for (i = 0; i < 3; i++) {
+               u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+               iowrite32(4, rogue_regs + 0x7500);
+               udelay(100);
+               iopol32(polval, polval, rogue_regs + 0x7500);
+       }
+
+       udelay(100);
+       iopol32(0x1fffffff, 0x1fffffff, rogue_regs + 0x7510);
+
+       /* Rasterisation */
+       iowrite32(8, rogue_regs + 0x7540);
+       udelay(100);
+
+       iowrite32(0x10, rogue_regs + 0x7540);
+       udelay(100);
+
+       for (i = 0; i < 3; i++) {
+               u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+               iowrite32(4, rogue_regs + 0x7540);
+               udelay(100);
+               iopol32(polval, polval, rogue_regs + 0x7540);
+       }
+
+       udelay(100);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7550);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7554);
+       iopol32(0xf, 0xf, rogue_regs + 0x7558);
+
+       /* hub_bifpmache */
+       iowrite32(8, rogue_regs + 0x7588);
+       udelay(100);
+
+       iowrite32(0x10, rogue_regs + 0x7588);
+       udelay(100);
+
+       for (i = 0; i < 3; i++) {
+               u32 polval = i == 2 ? 0x10000 : 0x20000;
+
+               iowrite32(4, rogue_regs + 0x7588);
+               udelay(100);
+               iopol32(polval, polval, rogue_regs + 0x7588);
+       }
+
+       udelay(100);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x7598);
+       iopol32(0xffffffff, 0xffffffff, rogue_regs + 0x759c);
+       iopol32(0x1111111f, 0x1111111f, rogue_regs + 0x75a0);
+
+       iounmap(rogue_regs);
+err_release_registers:
+       pci_release_region(apollo->pdev, SYS_RGX_REG_PCI_BASENUM);
+err_out:
+       return err;
+}
+
+static void apollo_hard_reset(struct apollo_device *apollo)
+{
+       u32 reg;
+
+       reg =  (0x1 << GLB_CLKG_EN_SHIFT);
+       reg |= (0x1 << SCB_RESETN_SHIFT);
+       reg |= (0x1 << PDP2_RESETN_SHIFT);
+       reg |= (0x1 << PDP1_RESETN_SHIFT);
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+
+       reg |= (0x1 << DDR_RESETN_SHIFT);
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+
+       reg |= (0x1 << DUT_RESETN_SHIFT);
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+
+       reg |= (0x1 << DUT_DCM_RESETN_SHIFT);
+       iowrite32(reg, apollo->tcf_registers + TCF_CLK_CTRL_CLK_AND_RST_CTRL);
+
+       /* NOTE: msleep() < 20 ms may sleep up to 20ms */
+       msleep(4);
+       iopol32(0x7, DCM_LOCK_STATUS_MASK,
+               apollo->tcf_registers + TCF_CLK_CTRL_DCM_LOCK_STATUS);
+}
+
+static int apollo_set_rogue_pll(struct apollo_device *apollo)
+{
+       int err = 0;
+       /* Enable the rogue PLL (defaults to 3x), giving a Rogue clock of
+        * 3 x RGX_TC_CORE_CLOCK_SPEED */
+       u32 val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+       iowrite32(val & 0xFFFFFFFB,
+               apollo->tcf_registers + TCF_CLK_CTRL_DUT_CONTROL_1);
+
+       return err;
+}
+
+static int apollo_hw_init(struct apollo_device *apollo)
+{
+       int err;
+
+       apollo_hard_reset(apollo);
+       err = apollo_rogue_bist(apollo);
+       if (err) {
+               dev_err(&apollo->pdev->dev, "Failed to run BIST on rogue\n");
+               goto exit;
+       }
+       apollo_hard_reset(apollo);
+       apollo_init_memory(apollo);
+
+       err = apollo_set_clocks(apollo);
+       if (err) {
+               dev_err(&apollo->pdev->dev, "Failed to init clocks\n");
+               goto exit;
+       }
+
+       err = apollo_set_rogue_pll(apollo);
+       if (err) {
+               dev_err(&apollo->pdev->dev, "Failed to set rogue PLL\n");
+               goto exit;
+       }
+
+exit:
+       return err;
+}
+
+static void apollo_hw_fini(struct apollo_device *apollo)
+{
+       apollo_deinit_memory(apollo);
+}
+
+int apollo_sys_info(struct device *dev, u32 *tmp, u32 *pll)
+{
+       /* Not implemented for TC1 */
+       return -1;
+}
+EXPORT_SYMBOL(apollo_sys_info);
+
+#endif
+
+int apollo_core_clock_speed(struct device *dev)
+{
+       return apollo_core_clock;
+}
+EXPORT_SYMBOL(apollo_core_clock_speed);
+
+#define HEX2DEC(v) ((((v) >> 4) * 10) + ((v) & 0x0F))
+int apollo_sys_strings(struct device *dev,
+                      char *str_fpga_rev, size_t size_fpga_rev,
+                      char *str_tcf_core_rev, size_t size_tcf_core_rev,
+                      char *str_tcf_core_target_build_id,
+                      size_t size_tcf_core_target_build_id,
+                      char *str_pci_ver, size_t size_pci_ver,
+                      char *str_macro_ver, size_t size_macro_ver)
+{
+       int err = 0;
+       u32 val;
+       resource_size_t host_fpga_register_resource;
+       void __iomem *host_fpga_registers;
+
+       struct apollo_device *apollo = devres_find(dev, apollo_devres_release,
+               NULL, NULL);
+
+       if (!str_fpga_rev || !size_fpga_rev ||
+           !str_tcf_core_rev || !size_tcf_core_rev ||
+           !str_tcf_core_target_build_id || !size_tcf_core_target_build_id ||
+           !str_pci_ver || !size_pci_ver ||
+           !str_macro_ver || !size_macro_ver) {
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       if (!apollo) {
+               dev_err(dev, "No apollo device resources found\n");
+               err = -ENODEV;
+               goto err_out;
+       }
+
+       /* To get some of the version information we need to read from a
+          register that we don't normally have mapped. Map it temporarily
+          (without trying to reserve it) to get the information we need. */
+       host_fpga_register_resource =
+               pci_resource_start(apollo->pdev, SYS_APOLLO_REG_PCI_BASENUM)
+               + 0x40F0;
+
+       host_fpga_registers = ioremap_nocache(host_fpga_register_resource,
+                                             0x04);
+       if (!host_fpga_registers) {
+               dev_err(&apollo->pdev->dev, "Failed to map host fpga registers\n");
+               err = -EIO;
+               goto err_out;
+       }
+
+       /* Create the components of the PCI and macro versions */
+       val = ioread32(host_fpga_registers);
+       snprintf(str_pci_ver, size_pci_ver, "%d",
+                HEX2DEC((val & 0x00FF0000) >> 16));
+       snprintf(str_macro_ver, size_macro_ver, "%d.%d",
+                (val & 0x00000F00) >> 8,
+                HEX2DEC((val & 0x000000FF) >> 0));
+
+       /* Unmap the register now that we no longer need it */
+       iounmap(host_fpga_registers);
+
+       /* Create the components of the FPGA revision number */
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_FPGA_REV_REG);
+       snprintf(str_fpga_rev, size_fpga_rev, "%d.%d.%d",
+                HEX2DEC((val & FPGA_REV_REG_MAJOR_MASK)
+                        >> FPGA_REV_REG_MAJOR_SHIFT),
+                HEX2DEC((val & FPGA_REV_REG_MINOR_MASK)
+                        >> FPGA_REV_REG_MINOR_SHIFT),
+                HEX2DEC((val & FPGA_REV_REG_MAINT_MASK)
+                        >> FPGA_REV_REG_MAINT_SHIFT));
+
+       /* Create the components of the TCF core revision number */
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_TCF_CORE_REV_REG);
+       snprintf(str_tcf_core_rev, size_tcf_core_rev, "%d.%d.%d",
+                HEX2DEC((val & TCF_CORE_REV_REG_MAJOR_MASK)
+                        >> TCF_CORE_REV_REG_MAJOR_SHIFT),
+                HEX2DEC((val & TCF_CORE_REV_REG_MINOR_MASK)
+                        >> TCF_CORE_REV_REG_MINOR_SHIFT),
+                HEX2DEC((val & TCF_CORE_REV_REG_MAINT_MASK)
+                        >> TCF_CORE_REV_REG_MAINT_SHIFT));
+
+       /* Create the component of the TCF core target build ID */
+       val = ioread32(apollo->tcf_registers +
+                      TCF_CLK_CTRL_TCF_CORE_TARGET_BUILD_CFG);
+       snprintf(str_tcf_core_target_build_id, size_tcf_core_target_build_id,
+                "%d",
+                (val & TCF_CORE_TARGET_BUILD_ID_MASK)
+                >> TCF_CORE_TARGET_BUILD_ID_SHIFT);
+
+err_out:
+       return err;
+}
+EXPORT_SYMBOL(apollo_sys_strings);
+
+static irqreturn_t apollo_irq_handler(int irq, void *data)
+{
+       u32 interrupt_status;
+       u32 interrupt_clear = 0;
+       unsigned long flags;
+       irqreturn_t ret = IRQ_NONE;
+       struct apollo_device *apollo = (struct apollo_device *)data;
+
+       spin_lock_irqsave(&apollo->interrupt_handler_lock, flags);
+
+       interrupt_status = ioread32(apollo->tcf_registers
+               + TCF_CLK_CTRL_INTERRUPT_STATUS);
+
+       if (interrupt_status & APOLLO_INTERRUPT_FLAG_ROGUE) {
+               if (apollo->interrupt_handlers[APOLLO_INTERRUPT_ROGUE].enabled
+                   && apollo->interrupt_handlers[APOLLO_INTERRUPT_ROGUE]
+                       .handler_function) {
+                       apollo->interrupt_handlers[APOLLO_INTERRUPT_ROGUE]
+                               .handler_function(apollo->interrupt_handlers
+                                       [APOLLO_INTERRUPT_ROGUE].handler_data);
+                       interrupt_clear |= APOLLO_INTERRUPT_FLAG_ROGUE;
+               }
+               ret = IRQ_HANDLED;
+       }
+       if (interrupt_status & APOLLO_INTERRUPT_FLAG_PDP) {
+               if (apollo->interrupt_handlers[APOLLO_INTERRUPT_PDP].enabled
+                   && apollo->interrupt_handlers[APOLLO_INTERRUPT_PDP]
+                       .handler_function) {
+                       apollo->interrupt_handlers[APOLLO_INTERRUPT_PDP]
+                               .handler_function(apollo->interrupt_handlers
+                                       [APOLLO_INTERRUPT_PDP].handler_data);
+                       interrupt_clear |= APOLLO_INTERRUPT_FLAG_PDP;
+               }
+               ret = IRQ_HANDLED;
+       }
+
+       if (interrupt_clear)
+               iowrite32(0xffffffff,
+                       apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_CLEAR);
+
+       spin_unlock_irqrestore(&apollo->interrupt_handler_lock, flags);
+
+       return ret;
+}
+
+static int apollo_enable_irq(struct apollo_device *apollo)
+{
+       int err = 0;
+       iowrite32(0, apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+       iowrite32(0xffffffff,
+               apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_CLEAR);
+       err = request_irq(apollo->pdev->irq, apollo_irq_handler, IRQF_SHARED,
+               DRV_NAME, apollo);
+       return err;
+}
+
+static void apollo_disable_irq(struct apollo_device *apollo)
+{
+       iowrite32(0, apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+       iowrite32(0xffffffff,
+               apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_CLEAR);
+       free_irq(apollo->pdev->irq, apollo);
+}
+
+static int register_pdp_device(struct apollo_device *apollo)
+{
+       int err = 0;
+       struct apollo_pdp_platform_data pdata = {
+               .pdev = apollo->pdev,
+#if defined(SUPPORT_ION)
+               .ion_device = apollo->ion_device,
+               .ion_heap_id = ION_HEAP_APOLLO_PDP,
+#endif
+               .apollo_memory_base = apollo->apollo_mem_base,
+       };
+       struct platform_device_info pdp_device_info = {
+               .parent = &apollo->pdev->dev,
+               .name = APOLLO_DEVICE_NAME_PDP,
+               .id = -1,
+               .res = NULL,
+               .num_res = 0,
+               .data = &pdata,
+               .size_data = sizeof(pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       apollo->pdp_dev = platform_device_register_full(&pdp_device_info);
+       if (IS_ERR(apollo->pdp_dev)) {
+               err = PTR_ERR(apollo->pdp_dev);
+               dev_err(&apollo->pdev->dev,
+                       "Failed to register PDP device (%d)\n", err);
+               apollo->pdp_dev = NULL;
+               goto err;
+       }
+err:
+       return err;
+}
+
+static int register_rogue_device(struct apollo_device *apollo)
+{
+       int err = 0;
+       struct apollo_rogue_platform_data pdata = {
+               .pdev = apollo->pdev,
+#if defined(SUPPORT_ION)
+               .ion_device = apollo->ion_device,
+               .ion_heap_id = ION_HEAP_APOLLO_ROGUE,
+#endif
+               .apollo_memory_base = apollo->apollo_mem_base,
+               .pdp_heap_memory_base = apollo->pdp_heap_mem_base,
+               .pdp_heap_memory_size = apollo->pdp_heap_mem_size,
+               .rogue_heap_memory_base = apollo->rogue_heap_mem_base,
+               .rogue_heap_memory_size = apollo->rogue_heap_mem_size,
+       };
+       struct platform_device_info rogue_device_info = {
+               .parent = &apollo->pdev->dev,
+               .name = APOLLO_DEVICE_NAME_ROGUE,
+               .id = -1,
+               .res = NULL,
+               .num_res = 0,
+               .data = &pdata,
+               .size_data = sizeof(pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+       apollo->rogue_dev = platform_device_register_full(&rogue_device_info);
+       if (IS_ERR(apollo->rogue_dev)) {
+               err = PTR_ERR(apollo->rogue_dev);
+               dev_err(&apollo->pdev->dev,
+                       "Failed to register rogue device (%d)\n", err);
+               apollo->rogue_dev = NULL;
+               goto err;
+       }
+err:
+       return err;
+}
+
+#if defined(SUPPORT_ION)
+static int apollo_ion_init(struct apollo_device *apollo)
+{
+       int i, err = 0;
+       struct ion_platform_heap ion_heap_data[APOLLO_ION_HEAP_COUNT] = {
+               {
+                       .type = ION_HEAP_TYPE_SYSTEM,
+                       .id = ION_HEAP_TYPE_SYSTEM,
+                       .name = "system",
+               },
+               {
+                       .type = ION_HEAP_TYPE_CUSTOM,
+                       .id = ION_HEAP_APOLLO_PDP,
+                       .size = apollo->pdp_heap_mem_size,
+                       .base = apollo->pdp_heap_mem_base,
+                       .name = "apollo-pdp",
+               },
+               {
+                       .type = ION_HEAP_TYPE_CUSTOM,
+                       .id = ION_HEAP_APOLLO_ROGUE,
+                       .size = apollo->rogue_heap_mem_size,
+                       .base = apollo->rogue_heap_mem_base,
+                       .name = "apollo-rogue",
+               }
+       };
+
+       apollo->ion_device = ion_device_create(NULL);
+       if (IS_ERR_OR_NULL(apollo->ion_device)) {
+               err = PTR_ERR(apollo->ion_device);
+               goto err_out;
+       }
+
+       err = request_pci_io_addr(apollo->pdev, APOLLO_MEM_PCI_BASENUM, 0,
+               apollo->apollo_mem_size);
+       if (err) {
+               dev_err(&apollo->pdev->dev,
+                       "Failed to request APOLLO memory (%d)\n", err);
+               goto err_free_device;
+       }
+
+       apollo->ion_heaps[0] = ion_heap_create(&ion_heap_data[0]);
+       if (IS_ERR_OR_NULL(apollo->ion_heaps[0])) {
+               err = PTR_ERR(apollo->ion_heaps[0]);
+               apollo->ion_heaps[0] = NULL;
+               goto err_free_device;
+       }
+       ion_device_add_heap(apollo->ion_device, apollo->ion_heaps[0]);
+
+       for (i = 1; i < APOLLO_ION_HEAP_COUNT; i++) {
+               apollo->ion_heaps[i] = ion_lma_heap_create(&ion_heap_data[i]);
+               if (IS_ERR_OR_NULL(apollo->ion_heaps[i])) {
+                       err = PTR_ERR(apollo->ion_heaps[i]);
+                       apollo->ion_heaps[i] = NULL;
+                       goto err_free_heaps;
+               }
+               ion_device_add_heap(apollo->ion_device, apollo->ion_heaps[i]);
+       }
+
+       return 0;
+
+err_free_heaps:
+       ion_heap_destroy(apollo->ion_heaps[0]);
+
+       for (i = 1; i < APOLLO_ION_HEAP_COUNT; i++) {
+               if (!apollo->ion_heaps[i])
+                       break;
+               ion_lma_heap_destroy(apollo->ion_heaps[i]);
+       }
+
+       release_pci_io_addr(apollo->pdev, APOLLO_MEM_PCI_BASENUM,
+               apollo->apollo_mem_base, apollo->apollo_mem_size);
+err_free_device:
+       ion_device_destroy(apollo->ion_device);
+err_out:
+       /* If the ptr was NULL, it is possible that err is 0 in the err path */
+       if (err == 0)
+               err = -ENOMEM;
+       return err;
+}
+
+static void apollo_ion_deinit(struct apollo_device *apollo)
+{
+       int i = 0;
+       ion_device_destroy(apollo->ion_device);
+       ion_heap_destroy(apollo->ion_heaps[0]);
+       for (i = 1; i < APOLLO_ION_HEAP_COUNT; i++)
+               ion_lma_heap_destroy(apollo->ion_heaps[i]);
+       release_pci_io_addr(apollo->pdev, APOLLO_MEM_PCI_BASENUM,
+               apollo->apollo_mem_base, apollo->apollo_mem_size);
+}
+#endif /* defined(SUPPORT_ION) */
+
+static int apollo_dev_init(struct apollo_device *apollo, struct pci_dev *pdev)
+{
+       int err;
+
+       apollo->pdev = pdev;
+
+       spin_lock_init(&apollo->interrupt_handler_lock);
+       spin_lock_init(&apollo->interrupt_enable_lock);
+
+       /* Reserve and map the TCF registers */
+       err = request_pci_io_addr(pdev, SYS_APOLLO_REG_PCI_BASENUM,
+               SYS_APOLLO_REG_SYS_OFFSET, SYS_APOLLO_REG_SYS_SIZE);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "Failed to request apollo registers (err=%d)\n", err);
+               return err;
+       }
+
+       apollo->tcf_register_resource =
+               pci_resource_start(pdev, SYS_APOLLO_REG_PCI_BASENUM)
+               + SYS_APOLLO_REG_SYS_OFFSET;
+
+       apollo->tcf_registers = ioremap_nocache(apollo->tcf_register_resource,
+               SYS_APOLLO_REG_SYS_SIZE);
+       if (!apollo->tcf_registers) {
+               dev_err(&pdev->dev, "Failed to map TCF registers\n");
+               err = -EIO;
+               goto err_release_registers;
+       }
+
+       /* Setup card memory */
+       apollo->apollo_mem_base =
+               pci_resource_start(pdev, APOLLO_MEM_PCI_BASENUM);
+       apollo->apollo_mem_size =
+               pci_resource_len(pdev, APOLLO_MEM_PCI_BASENUM);
+
+       err = mtrr_setup(pdev, apollo->apollo_mem_base,
+                        apollo->apollo_mem_size);
+       if (err)
+               goto err_unmap_registers;
+
+       /* Setup ranges for the device heaps */
+       apollo->pdp_heap_mem_size = APOLLO_PDP_MEM_SIZE;
+       apollo->rogue_heap_mem_size = apollo->apollo_mem_size
+               - apollo->pdp_heap_mem_size;
+
+       apollo->rogue_heap_mem_base = apollo->apollo_mem_base;
+       apollo->pdp_heap_mem_base = apollo->apollo_mem_base +
+               apollo->rogue_heap_mem_size;
+
+#if defined(SUPPORT_ION)
+       err = apollo_ion_init(apollo);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to initialise ION\n");
+               goto err_unmap_registers;
+       }
+#endif
+
+       return 0;
+
+err_unmap_registers:
+       iounmap(apollo->tcf_registers);
+err_release_registers:
+       release_pci_io_addr(pdev, SYS_APOLLO_REG_PCI_BASENUM,
+               apollo->tcf_register_resource, SYS_APOLLO_REG_SYS_SIZE);
+       return err;
+}
+
+static void apollo_dev_cleanup(struct apollo_device *apollo)
+{
+#if defined(SUPPORT_ION)
+       apollo_ion_deinit(apollo);
+#endif
+       iounmap(apollo->tcf_registers);
+       release_pci_io_addr(apollo->pdev, SYS_APOLLO_REG_PCI_BASENUM,
+               apollo->tcf_register_resource, SYS_APOLLO_REG_SYS_SIZE);
+}
+
+static int apollo_init(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       struct apollo_device *apollo;
+       int err = 0;
+       u32 val;
+
+       if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
+               return -ENOMEM;
+
+       apollo = devres_alloc(apollo_devres_release,
+               sizeof(struct apollo_device), GFP_KERNEL);
+       if (!apollo) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       devres_add(&pdev->dev, apollo);
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "pci_enable_device returned %d\n", err);
+               goto err_out;
+       }
+
+       err = apollo_dev_init(apollo, pdev);
+       if (err)
+               goto err_disable_device;
+
+       err = apollo_hw_init(apollo);
+       if (err)
+               goto err_dev_cleanup;
+
+       err = apollo_enable_irq(apollo);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to initialise IRQ\n");
+               goto err_hw_fini;
+       }
+
+       /* Set sense to active high */
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_OP_CFG);
+       val &= ~(INT_SENSE_MASK);
+       iowrite32(val, apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_OP_CFG);
+
+       /* Register rogue and pdp platform devices
+        * Failures here aren't critical? */
+       register_pdp_device(apollo);
+       register_rogue_device(apollo);
+
+       devres_remove_group(&pdev->dev, NULL);
+
+       return err;
+
+err_hw_fini:
+       apollo_hw_fini(apollo);
+err_dev_cleanup:
+       apollo_dev_cleanup(apollo);
+err_disable_device:
+       pci_disable_device(pdev);
+err_out:
+       devres_release_group(&pdev->dev, NULL);
+       dev_err(&pdev->dev, "Failed to initialise apollo device\n");
+       return err;
+}
+
+static void apollo_exit(struct pci_dev *pdev)
+{
+       int i;
+       struct apollo_device *apollo = devres_find(&pdev->dev,
+               apollo_devres_release, NULL, NULL);
+
+       if (apollo->pdp_dev)
+               platform_device_unregister(apollo->pdp_dev);
+
+       if (apollo->rogue_dev)
+               platform_device_unregister(apollo->rogue_dev);
+
+       for (i = 0; i < APOLLO_INTERRUPT_COUNT; i++)
+               apollo_disable_interrupt(&pdev->dev, i);
+       apollo_disable_irq(apollo);
+       apollo_hw_fini(apollo);
+       apollo_dev_cleanup(apollo);
+       pci_disable_device(pdev);
+}
+
+DEFINE_PCI_DEVICE_TABLE(apollo_pci_tbl) = {
+       { PCI_VDEVICE(POWERVR, DEVICE_ID_PCI_APOLLO_FPGA) },
+       { PCI_VDEVICE(POWERVR, DEVICE_ID_PCIE_APOLLO_FPGA) },
+       { },
+};
+
+static struct pci_driver apollo_pci_driver = {
+       .name           = DRV_NAME,
+       .id_table       = apollo_pci_tbl,
+       .probe          = apollo_init,
+       .remove         = apollo_exit,
+};
+
+module_pci_driver(apollo_pci_driver);
+
+MODULE_DEVICE_TABLE(pci, apollo_pci_tbl);
+
+static u32 apollo_interrupt_id_to_flag(int interrupt_id)
+{
+       switch (interrupt_id) {
+       case APOLLO_INTERRUPT_PDP:
+               return APOLLO_INTERRUPT_FLAG_PDP;
+       case APOLLO_INTERRUPT_ROGUE:
+               return APOLLO_INTERRUPT_FLAG_ROGUE;
+       default:
+               BUG();
+       }
+}
+
+static void apollo_enable_interrupt_register(struct apollo_device *apollo,
+       int interrupt_id)
+{
+       u32 val;
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+       val |= apollo_interrupt_id_to_flag(interrupt_id);
+       iowrite32(val, apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+
+}
+
+static void apollo_disable_interrupt_register(struct apollo_device *apollo,
+       int interrupt_id)
+{
+       u32 val;
+       val = ioread32(apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+       val &= ~(apollo_interrupt_id_to_flag(interrupt_id));
+       iowrite32(val, apollo->tcf_registers + TCF_CLK_CTRL_INTERRUPT_ENABLE);
+}
+
+int apollo_set_interrupt_handler(struct device *dev, int interrupt_id,
+       void (*handler_function)(void *), void *data)
+{
+       struct apollo_device *apollo = devres_find(dev, apollo_devres_release,
+               NULL, NULL);
+       int err = 0;
+       unsigned long flags;
+       if (!apollo) {
+               dev_err(dev, "No apollo device resources found\n");
+               err = -ENODEV;
+               goto err_out;
+       }
+
+       if (interrupt_id < 0 || interrupt_id >= APOLLO_INTERRUPT_COUNT) {
+               dev_err(dev, "Invalid interrupt ID (%d)\n", interrupt_id);
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       if (!handler_function) {
+               dev_err(dev, "Invalid handler function\n");
+               err = -EINVAL;
+               goto err_out;
+       }
+
+       spin_lock_irqsave(&apollo->interrupt_handler_lock, flags);
+
+       apollo->interrupt_handlers[interrupt_id].handler_function =
+               handler_function;
+       apollo->interrupt_handlers[interrupt_id].handler_data = data;
+
+       spin_unlock_irqrestore(&apollo->interrupt_handler_lock, flags);
+
+err_out:
+       return err;
+}
+EXPORT_SYMBOL(apollo_set_interrupt_handler);
+
+int apollo_enable_interrupt(struct device *dev, int interrupt_id)
+{
+       struct apollo_device *apollo = devres_find(dev, apollo_devres_release,
+               NULL, NULL);
+       int err = 0;
+       unsigned long flags;
+       if (!apollo) {
+               dev_err(dev, "No apollo device resources found\n");
+               err = -ENODEV;
+               goto err_out;
+       }
+       if (interrupt_id < 0 || interrupt_id >= APOLLO_INTERRUPT_COUNT) {
+               dev_err(dev, "Invalid interrupt ID (%d)\n", interrupt_id);
+               err = -EINVAL;
+               goto err_out;
+       }
+       spin_lock_irqsave(&apollo->interrupt_enable_lock, flags);
+
+       if (apollo->interrupt_handlers[interrupt_id].enabled) {
+               dev_warn(dev, "Interrupt ID %d already enabled\n",
+                       interrupt_id);
+               err = -EEXIST;
+               goto err_unlock;
+       }
+       apollo->interrupt_handlers[interrupt_id].enabled = true;
+
+       apollo_enable_interrupt_register(apollo, interrupt_id);
+
+err_unlock:
+       spin_unlock_irqrestore(&apollo->interrupt_enable_lock, flags);
+err_out:
+       return err;
+}
+EXPORT_SYMBOL(apollo_enable_interrupt);
+
+int apollo_disable_interrupt(struct device *dev, int interrupt_id)
+{
+       struct apollo_device *apollo = devres_find(dev, apollo_devres_release,
+               NULL, NULL);
+       int err = 0;
+       unsigned long flags;
+       if (!apollo) {
+               dev_err(dev, "No apollo device resources found\n");
+               err = -ENODEV;
+               goto err_out;
+       }
+       if (interrupt_id < 0 || interrupt_id >= APOLLO_INTERRUPT_COUNT) {
+               dev_err(dev, "Invalid interrupt ID (%d)\n", interrupt_id);
+               err = -EINVAL;
+               goto err_out;
+       }
+       spin_lock_irqsave(&apollo->interrupt_enable_lock, flags);
+
+       if (!apollo->interrupt_handlers[interrupt_id].enabled) {
+               dev_warn(dev, "Interrupt ID %d already disabled\n",
+                       interrupt_id);
+               err = -EEXIST;
+               goto err_unlock;
+       }
+       apollo->interrupt_handlers[interrupt_id].enabled = false;
+
+       apollo_disable_interrupt_register(apollo, interrupt_id);
+
+err_unlock:
+       spin_unlock_irqrestore(&apollo->interrupt_enable_lock, flags);
+err_out:
+       return err;
+}
+EXPORT_SYMBOL(apollo_disable_interrupt);
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo_drv.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/apollo_drv.h
new file mode 100644 (file)
index 0000000..dfdda3e
--- /dev/null
@@ -0,0 +1,111 @@
+/*************************************************************************/ /*!
+@File           apollo_drv.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _APOLLO_DRV_H
+#define _APOLLO_DRV_H
+
+/*
+ * This contains the hooks for the apollo testchip driver, as used by the
+ * Rogue and PDP sub-devices, and the platform data passed to each of their
+ * drivers
+ */
+
+#include <linux/pci.h>
+#include <linux/device.h>
+
+#if defined(SUPPORT_ION)
+#include PVR_ANDROID_ION_HEADER
+
+/* NOTE: This should be kept in sync with the user side (in buffer_generic.c) */
+#define ION_HEAP_APOLLO_ROGUE  (ION_HEAP_TYPE_CUSTOM+1)
+#define ION_HEAP_APOLLO_PDP    (ION_HEAP_TYPE_CUSTOM+2)
+#endif
+
+#define APOLLO_INTERRUPT_PDP   0
+#define APOLLO_INTERRUPT_ROGUE 1
+#define APOLLO_INTERRUPT_COUNT 2
+
+int apollo_enable_interrupt(struct device *dev, int interrupt_id);
+int apollo_disable_interrupt(struct device *dev, int interrupt_id);
+
+int apollo_set_interrupt_handler(struct device *dev, int interrupt_id, void (*handler_function)(void *), void *handler_data);
+
+int apollo_sys_info(struct device *dev, u32 *tmp, u32 *pll);
+int apollo_sys_strings(struct device *dev, 
+                                          char *str_fpga_rev, size_t size_fpga_rev, char *str_tcf_core_rev, size_t size_tcf_core_rev,
+                                          char *str_tcf_core_target_build_id, size_t size_tcf_core_target_build_id,
+                                          char *str_pci_ver, size_t size_pci_ver, char *str_macro_ver, size_t size_macro_ver);
+int apollo_core_clock_speed(struct device *dev);
+
+#define APOLLO_DEVICE_NAME_PDP         "apollo_pdp"
+#define APOLLO_DEVICE_NAME_ROGUE       "apollo_rogue"
+
+/* The following structs are initialised and passed down by the parent apollo
+ * driver to the respective sub-drivers */
+
+struct apollo_pdp_platform_data {
+       struct pci_dev *pdev;
+#if defined(SUPPORT_ION)
+       struct ion_device *ion_device;
+       int ion_heap_id;
+#endif
+       resource_size_t apollo_memory_base;
+};
+
+struct apollo_rogue_platform_data {
+       struct pci_dev *pdev;
+#if defined(SUPPORT_ION)
+       struct ion_device *ion_device;
+       int ion_heap_id;
+#endif
+
+       /* The base address of the testchip memory (CPU physical address) -
+        * used to convert from CPU-Physical to device-physical addresses */
+       resource_size_t apollo_memory_base;
+
+       /* The following is used to setup the services heaps that map to the
+        * ion heaps */
+       resource_size_t pdp_heap_memory_base;
+       resource_size_t pdp_heap_memory_size;
+       resource_size_t rogue_heap_memory_base;
+       resource_size_t rogue_heap_memory_size;
+};
+
+#endif /* _APOLLO_DRV_H */
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.c
new file mode 100644 (file)
index 0000000..f86de4b
--- /dev/null
@@ -0,0 +1,257 @@
+/*************************************************************************/ /*!
+@File           ion_lma_heap.c
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#include "ion_lma_heap.h"
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/genalloc.h>
+#include <linux/scatterlist.h>
+
+/* Ion heap for LMA allocations. This heap is identical to CARVEOUT except
+ * that it does not do any CPU cache maintenance nor does it zero the memory
+ * using the CPU (this is handled with PVR_ANDROID_DEFER_CLEAR in userspace).
+ */
+
+struct ion_lma_heap {
+       struct ion_heap heap;
+       struct gen_pool *pool;
+       ion_phys_addr_t base;
+};
+
+static ion_phys_addr_t ion_lma_allocate(struct ion_heap *heap,
+                                       unsigned long size,
+                                       unsigned long align)
+{
+       struct ion_lma_heap *lma_heap =
+               container_of(heap, struct ion_lma_heap, heap);
+       unsigned long offset = gen_pool_alloc(lma_heap->pool, size);
+
+       if (!offset)
+               return ION_CARVEOUT_ALLOCATE_FAIL;
+
+       return offset;
+}
+
+static void ion_lma_free(struct ion_heap *heap, ion_phys_addr_t addr,
+                        unsigned long size)
+{
+       struct ion_lma_heap *lma_heap =
+               container_of(heap, struct ion_lma_heap, heap);
+
+       if (addr == ION_CARVEOUT_ALLOCATE_FAIL)
+               return;
+
+       gen_pool_free(lma_heap->pool, addr, size);
+}
+
+static int ion_lma_heap_phys(struct ion_heap *heap,
+                            struct ion_buffer *buffer,
+                            ion_phys_addr_t *addr, size_t *len)
+{
+       struct sg_table *table = buffer->priv_virt;
+       struct page *page = sg_page(table->sgl);
+       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+       *addr = paddr;
+       *len = buffer->size;
+       return 0;
+}
+
+static int ion_lma_heap_allocate(struct ion_heap *heap,
+                                struct ion_buffer *buffer,
+                                unsigned long size, unsigned long align,
+                                unsigned long flags)
+{
+       struct sg_table *table;
+       ion_phys_addr_t paddr;
+       int ret;
+
+       if (align > PAGE_SIZE)
+               return -EINVAL;
+
+       table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+       if (!table)
+               return -ENOMEM;
+
+       ret = sg_alloc_table(table, 1, GFP_KERNEL);
+       if (ret)
+               goto err_free;
+
+       paddr = ion_lma_allocate(heap, size, align);
+       if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) {
+               ret = -ENOMEM;
+               goto err_free_table;
+       }
+
+       sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0);
+       buffer->priv_virt = table;
+       return 0;
+
+err_free_table:
+       sg_free_table(table);
+err_free:
+       kfree(table);
+       return ret;
+}
+
+static void ion_lma_heap_free(struct ion_buffer *buffer)
+{
+       struct ion_heap *heap = buffer->heap;
+       struct sg_table *table = buffer->priv_virt;
+       struct page *page = sg_page(table->sgl);
+       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+       /* Do not zero the LMA heap from the CPU. This is very slow with
+        * the current TCF (w/ no DMA engine). We will use the TLA to clear
+        * the memory with Rogue in another place.
+        *
+        * We also skip the CPU cache maintenance for the heap space, as we
+        * statically know that the TCF PCI memory bar has UC/WC set by the
+        * MTRR/PAT subsystem.
+        */
+
+       ion_lma_free(heap, paddr, buffer->size);
+       sg_free_table(table);
+       kfree(table);
+}
+
+static struct sg_table *ion_lma_heap_map_dma(struct ion_heap *heap,
+                                            struct ion_buffer *buffer)
+{
+       return buffer->priv_virt;
+}
+
+static void ion_lma_heap_unmap_dma(struct ion_heap *heap,
+                                  struct ion_buffer *buffer)
+{
+       return;
+}
+
+static int ion_lma_heap_map_user(struct ion_heap *mapper,
+                                struct ion_buffer *buffer,
+                                struct vm_area_struct *vma)
+{
+       struct sg_table *table = buffer->priv_virt;
+       struct page *page = sg_page(table->sgl);
+       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+       return remap_pfn_range(vma, vma->vm_start,
+                              PFN_DOWN(paddr) + vma->vm_pgoff,
+                              vma->vm_end - vma->vm_start,
+                              pgprot_writecombine(vma->vm_page_prot));
+}
+
+static void *ion_lma_heap_map_kernel(struct ion_heap *heap,
+                                    struct ion_buffer *buffer)
+{
+       struct sg_table *table = buffer->priv_virt;
+       struct page *page = sg_page(table->sgl);
+       ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+       return ioremap_wc(paddr, buffer->size);
+}
+
+static void ion_lma_heap_unmap_kernel(struct ion_heap *heap,
+                                     struct ion_buffer *buffer)
+{
+       iounmap(buffer->vaddr);
+}
+
+static struct ion_heap_ops lma_heap_ops = {
+       .allocate = ion_lma_heap_allocate,
+       .free = ion_lma_heap_free,
+       .phys = ion_lma_heap_phys,
+       .map_dma = ion_lma_heap_map_dma,
+       .unmap_dma = ion_lma_heap_unmap_dma,
+       .map_user = ion_lma_heap_map_user,
+       .map_kernel = ion_lma_heap_map_kernel,
+       .unmap_kernel = ion_lma_heap_unmap_kernel,
+};
+
+struct ion_heap *ion_lma_heap_create(struct ion_platform_heap *heap_data)
+{
+       struct ion_lma_heap *lma_heap;
+       size_t size = heap_data->size;
+       struct page *page;
+
+       page = pfn_to_page(PFN_DOWN(heap_data->base));
+
+       /* Do not zero the LMA heap from the CPU. This is very slow with
+        * the current TCF (w/ no DMA engine). We will use the TLA to clear
+        * the memory with Rogue in another place.
+        *
+        * We also skip the CPU cache maintenance for the heap space, as we
+        * statically know that the TCF PCI memory bar has UC/WC set by the
+        * MTRR/PAT subsystem.
+        */
+
+       lma_heap = kzalloc(sizeof(struct ion_lma_heap), GFP_KERNEL);
+       if (!lma_heap)
+               return ERR_PTR(-ENOMEM);
+
+       lma_heap->pool = gen_pool_create(12, -1);
+       if (!lma_heap->pool) {
+               kfree(lma_heap);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       lma_heap->base = heap_data->base;
+       gen_pool_add(lma_heap->pool, lma_heap->base, size, -1);
+
+       lma_heap->heap.id = heap_data->id;
+       lma_heap->heap.ops = &lma_heap_ops;
+       lma_heap->heap.name = heap_data->name;
+       lma_heap->heap.type = ION_HEAP_TYPE_CUSTOM;
+       lma_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
+
+       return &lma_heap->heap;
+}
+
+void ion_lma_heap_destroy(struct ion_heap *heap)
+{
+       struct ion_lma_heap *lma_heap =
+               container_of(heap, struct ion_lma_heap, heap);
+       gen_pool_destroy(lma_heap->pool);
+       kfree(lma_heap);
+       lma_heap = NULL;
+}
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/ion_lma_heap.h
new file mode 100644 (file)
index 0000000..2e0b9bc
--- /dev/null
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@File           ion_lma_heap.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#ifndef __ION_LMA_HEAP__
+#define __ION_LMA_HEAP__
+
+#include PVR_ANDROID_ION_HEADER
+#include PVR_ANDROID_ION_PRIV_HEADER
+
+struct ion_heap *ion_lma_heap_create(struct ion_platform_heap *heap_data);
+void ion_lma_heap_destroy(struct ion_heap *heap);
+
+#endif /* __ION_LMA_HEAP__ */
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.c b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.c
new file mode 100644 (file)
index 0000000..5f5c8c0
--- /dev/null
@@ -0,0 +1,2330 @@
+/*************************************************************************/ /*!
+@File           pvr_sync.c
+@Title          Kernel driver for Android's sync mechanism
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#include "pvr_sync.h"
+#include "pvr_fd_sync_kernel.h"
+#include "services_kernel_client.h"
+
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/syscalls.h>
+#include <linux/miscdevice.h>
+#include <linux/anon_inodes.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+#include <linux/sync.h>
+#ifndef CONFIG_SW_SYNC_USER
+#include <linux/sw_sync.h>
+#endif
+#else
+#include <../drivers/staging/android/sync.h>
+#ifndef CONFIG_SW_SYNC_USER
+#include <../drivers/staging/android/sw_sync.h>
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
+
+static inline int kref_put_mutex(struct kref *kref,
+                                void (*release)(struct kref *kref),
+                                struct mutex *lock)
+{
+       WARN_ON(release == NULL);
+       if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
+               mutex_lock(lock);
+               if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
+                       mutex_unlock(lock);
+                       return 0;
+               }
+               release(kref);
+               return 1;
+       }
+       return 0;
+}
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
+
+static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt)
+{
+       return pt->parent;
+}
+
+static inline int sync_pt_get_status(struct sync_pt *pt)
+{
+       return pt->status;
+}
+
+#define for_each_sync_pt(s, f, c) \
+       (void)c; \
+       list_for_each_entry((s), &(f)->pt_list_head, pt_list)
+
+#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) */
+
+static inline int sync_pt_get_status(struct sync_pt *pt)
+{
+       /* No error state for raw dma-buf fences */
+       return fence_is_signaled(&pt->base) ? 1 : 0;
+}
+
+#define for_each_sync_pt(s, f, c) \
+       for ((c) = 0, (s) = (struct sync_pt *)(f)->cbs[0].sync_pt; \
+            (c) < (f)->num_fences; \
+            (c)++,   (s) = (struct sync_pt *)(f)->cbs[c].sync_pt)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) */
+
+/* #define DEBUG_OUTPUT 1 */
+
+#ifdef DEBUG_OUTPUT
+#define DPF(fmt, ...) pr_err("pvr_sync: " fmt "\n", __VA_ARGS__)
+#else
+#define DPF(fmt, ...) do {} while (0)
+#endif
+
+#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, fmt, ...) \
+       do { \
+               if (pfnDumpDebugPrintf) { \
+                       pfnDumpDebugPrintf(fmt, __VA_ARGS__); \
+               } else { \
+                       pr_info("pvr_sync: " fmt, __VA_ARGS__); \
+               } \
+       } while (0)
+
+#define SYNC_MAX_POOL_SIZE 10
+
+enum {
+       SYNC_TL_TYPE = 0,
+       SYNC_PT_FENCE_TYPE = 1,
+       SYNC_PT_CLEANUP_TYPE = 2,
+       SYNC_PT_FOREIGN_FENCE_TYPE = 3,
+       SYNC_PT_FOREIGN_CLEANUP_TYPE = 4,
+};
+
+struct pvr_sync_append_data {
+       u32                             nr_updates;
+       PRGXFWIF_UFO_ADDR               *update_ufo_addresses;
+       u32                             *update_values;
+       u32                             nr_checks;
+       PRGXFWIF_UFO_ADDR               *check_ufo_addresses;
+       u32                             *check_values;
+
+       /* The cleanup list is needed for rollback (as that's the only op
+        * taken) */
+       u32                             nr_cleaup_syncs;
+       struct pvr_sync_native_sync_prim        **cleanup_syncs;
+
+       /* Keep the sync points around for fput and if rollback is needed */
+       struct pvr_sync_alloc_data      *update_sync_data;
+       u32                             nr_fences;
+       struct sync_fence               *fences[];
+};
+
+
+/* Services client sync prim wrapper. This is used to hold debug information
+ * and make it possible to cache unused syncs. */
+struct pvr_sync_native_sync_prim {
+       /* List for the sync pool support. */
+       struct list_head list;
+
+       /* Base services sync prim structure */
+       struct PVRSRV_CLIENT_SYNC_PRIM *client_sync;
+
+       /* The next queued value which should be used */
+       u32 next_value;
+
+       /* Every sync data will get some unique id */
+       u32 id;
+
+       /* FWAddr used by the client sync */
+       u32 vaddr;
+
+       /* The type this sync is used for in our driver. Used in
+        * pvr_sync_debug_request. */
+       u8 type;
+
+       /* A debug class name also printed in pvr_sync_debug_request */
+       char class[32];
+};
+
+/* This is the actual timeline metadata. We might keep this around after the
+ * base sync driver has destroyed the pvr_sync_timeline_wrapper object.
+ */
+struct pvr_sync_timeline {
+       /* Back reference to the sync_timeline. Not always valid */
+       struct sync_timeline *obj;
+
+       /* Global timeline list support */
+       struct list_head list;
+
+       /* Timeline sync */
+       struct pvr_sync_kernel_pair *kernel;
+
+       /* Should we do timeline idle detection when creating a new fence? */
+       bool fencing_enabled;
+
+       /* Reference count for this object */
+       struct kref kref;
+
+       /* Used only by pvr_sync_update_all_timelines(). False if the timeline
+        * has been detected as racing with pvr_sync_destroy_timeline().
+        */
+       bool valid;
+};
+
+/* This is the IMG extension of a sync_timeline */
+struct pvr_sync_timeline_wrapper {
+       /* Original timeline struct. Needs to come first. */
+       struct sync_timeline obj;
+
+       /* Pointer to extra timeline data. Separated life-cycle. */
+       struct pvr_sync_timeline *timeline;
+};
+
+struct pvr_sync_kernel_pair {
+       /* Binary sync point representing the android native sync in hw. */
+       struct pvr_sync_native_sync_prim *fence_sync;
+
+       /* Cleanup sync structure.
+        * If the base sync prim is used for "checking" only within a gl stream,
+        * there is no way of knowing when this has happened. So use a second
+        * sync prim which just gets updated and check the update count when
+        * freeing this struct. */
+       struct pvr_sync_native_sync_prim *cleanup_sync;
+
+       /* Sync points can go away when there are deferred hardware operations
+        * still outstanding. We must not free the SERVER_SYNC_PRIMITIVE until
+        * the hardware is finished, so we add it to a defer list which is
+        * processed periodically ("defer-free").
+        *
+        * Note that the defer-free list is global, not per-timeline.
+        */
+       struct list_head list;
+};
+
+struct pvr_sync_data {
+       /* Every sync point has a services sync object. This object is used
+        * by the hardware to enforce ordering -- it is attached as a source
+        * dependency to various commands.
+        */
+       struct pvr_sync_kernel_pair *kernel;
+
+       /* The timeline update value for this sync point. */
+       u32 timeline_update_value;
+
+       /* This refcount is incremented at create and dup time, and decremented
+        * at free time. It ensures the object doesn't start the defer-free
+        * process until it is no longer referenced.
+        */
+       struct kref kref;
+};
+
+struct pvr_sync_alloc_data {
+       struct pvr_sync_timeline *timeline;
+       struct pvr_sync_data *sync_data;
+       struct file *file;
+};
+
+/* This is the IMG extension of a sync_pt */
+struct pvr_sync_pt {
+       /* Original sync_pt structure. Needs to come first. */
+       struct sync_pt pt;
+
+       /* Private shared data */
+       struct pvr_sync_data *sync_data;
+};
+
+/* This is the IMG extension of a sync_fence */
+struct pvr_sync_fence {
+       /* Original sync_fence structure. Needs to come first. */
+       struct sync_fence *fence;
+
+       /* To ensure callbacks are always received for fences / sync_pts, even
+        * after the fence has been 'put' (freed), we must take a reference to
+        * the fence. We still need to 'put' the fence ourselves, but this might
+        * happen in irq context, where fput() is not allowed (in kernels <3.6).
+        * We must add the fence to a list which is processed in WQ context.
+        */
+       struct list_head list;
+};
+
+/* Any sync point from a foreign (non-PVR) timeline needs to have a "shadow"
+ * sync prim. This is modelled as a software operation. The foreign driver
+ * completes the operation by calling a callback we registered with it. */
+struct pvr_sync_fence_waiter {
+       /* Base sync driver waiter structure */
+       struct sync_fence_waiter waiter;
+
+       /* "Shadow" sync prim backing the foreign driver's sync_pt */
+       struct pvr_sync_kernel_pair *kernel;
+
+       /* Optimizes lookup of fence for defer-put operation */
+       struct pvr_sync_fence *sync_fence;
+};
+
+/* Global data for the sync driver */
+static struct {
+       /* Services connection */
+       void *device_cookie;
+
+       /* Complete notify handle */
+       void *command_complete_handle;
+
+       /* defer_free workqueue. Syncs may still be in use by the HW when freed,
+        * so we have to keep them around until the HW is done with them at
+        * some later time. This workqueue iterates over the list of free'd
+        * syncs, checks if they are in use, and frees the sync device memory
+        * when done with. */
+       struct workqueue_struct *defer_free_wq;
+       struct work_struct defer_free_work;
+
+       /* check_status workqueue: When a foreign point is completed, a SW
+        * operation marks the sync as completed to allow the operations to
+        * continue. This completion may require the hardware to be notified,
+        * which may be expensive/take locks, so we push that to a workqueue
+        */
+       struct workqueue_struct *check_status_wq;
+       struct work_struct check_status_work;
+
+       /* Context used to create client sync prims. */
+       struct SYNC_PRIM_CONTEXT *sync_prim_context;
+
+       /* Debug notify handle */
+       void *debug_notify_handle;
+
+       /* Unique id counter for the sync prims */
+       atomic_t sync_id;
+
+       /* The global event object (used to wait between checks for deferred-
+        * free sync status) */
+       void *event_object_handle;
+} pvr_sync_data;
+
+/* List of timelines created by this driver */
+static LIST_HEAD(timeline_list);
+static DEFINE_MUTEX(timeline_list_mutex);
+
+/* Sync pool support */
+static LIST_HEAD(sync_pool_free_list);
+static LIST_HEAD(sync_pool_active_list);
+static DEFINE_MUTEX(sync_pool_mutex);
+static s32 sync_pool_size;
+static u32 sync_pool_created;
+static u32 sync_pool_reused;
+
+/* The "defer-free" object list. Driver global. */
+static LIST_HEAD(sync_prim_free_list);
+static DEFINE_SPINLOCK(sync_prim_free_list_spinlock);
+
+/* The "defer-put" object list. Driver global. */
+static LIST_HEAD(sync_fence_put_list);
+static DEFINE_SPINLOCK(sync_fence_put_list_spinlock);
+
+static inline void set_sync_value(struct pvr_sync_native_sync_prim *sync,
+                                 u32 value)
+{
+       *(sync->client_sync->pui32LinAddr) = value;
+}
+
+static inline u32 get_sync_value(struct pvr_sync_native_sync_prim *sync)
+{
+       return *(sync->client_sync->pui32LinAddr);
+}
+
+static inline void complete_sync(struct pvr_sync_native_sync_prim *sync)
+{
+       *(sync->client_sync->pui32LinAddr) = sync->next_value;
+}
+
+static inline int is_sync_met(struct pvr_sync_native_sync_prim *sync)
+{
+       return *(sync->client_sync->pui32LinAddr) == sync->next_value;
+}
+
+static inline struct pvr_sync_timeline *get_timeline(struct sync_timeline *obj)
+{
+       return ((struct pvr_sync_timeline_wrapper *)obj)->timeline;
+}
+
+static inline struct pvr_sync_timeline *get_timeline_pt(struct sync_pt *pt)
+{
+       return get_timeline(sync_pt_parent(pt));
+}
+
+static inline int
+pvr_sync_has_kernel_signaled(struct pvr_sync_kernel_pair *kernel)
+{
+       /* Idle syncs are always signaled */
+       if (!kernel)
+               return 1;
+
+       return is_sync_met(kernel->fence_sync);
+}
+
+static struct pvr_sync_alloc_data *pvr_sync_alloc_fence_fdget(int fd);
+
+#ifdef DEBUG_OUTPUT
+
+static char *debug_info_timeline(struct pvr_sync_timeline *timeline)
+{
+       static char info[256];
+
+       snprintf(info, sizeof(info),
+                "n='%s' id=%u fw=0x%x tl_curr=%u tl_next=%u",
+                timeline->obj ? timeline->obj->name : "?",
+                timeline->kernel->fence_sync->id,
+                timeline->kernel->fence_sync->vaddr,
+                get_sync_value(timeline->kernel->fence_sync),
+                timeline->kernel->fence_sync->next_value);
+
+       return info;
+}
+
+static char *debug_info_sync_pt(struct sync_pt *pt)
+{
+       struct pvr_sync_timeline *timeline = get_timeline_pt(pt);
+       struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)pt;
+       struct pvr_sync_kernel_pair *kernel = pvr_pt->sync_data->kernel;
+       static char info[256], info1[256];
+
+       if (kernel) {
+               struct pvr_sync_native_sync_prim *cleanup_sync =
+                       kernel->cleanup_sync;
+
+               if (cleanup_sync) {
+                       snprintf(info1, sizeof(info1),
+                                " # cleanup: id=%u fw=0x%x curr=%u next=%u",
+                                cleanup_sync->id,
+                                cleanup_sync->vaddr,
+                                get_sync_value(cleanup_sync),
+                                cleanup_sync->next_value);
+               } else {
+                       info1[0] = 0;
+               }
+
+               snprintf(info, sizeof(info),
+                        "status=%d tl_taken=%u ref=%d # sync: id=%u fw=0x%x curr=%u next=%u%s # tl: %s",
+                        pvr_sync_has_kernel_signaled(kernel),
+                        pvr_pt->sync_data->timeline_update_value,
+                        atomic_read(&pvr_pt->sync_data->kref.refcount),
+                        kernel->fence_sync->id,
+                        kernel->fence_sync->vaddr,
+                        get_sync_value(kernel->fence_sync),
+                        kernel->fence_sync->next_value,
+                        info1, debug_info_timeline(timeline));
+       } else {
+               snprintf(info, sizeof(info),
+                        "status=%d tl_taken=%u ref=%d # sync: idle # tl: %s",
+                        pvr_sync_has_kernel_signaled(kernel),
+                        pvr_pt->sync_data->timeline_update_value,
+                        atomic_read(&pvr_pt->sync_data->kref.refcount),
+                        debug_info_timeline(timeline));
+       }
+
+       return info;
+}
+
+#endif /* DEBUG_OUTPUT */
+
+static enum PVRSRV_ERROR
+sync_pool_get(struct pvr_sync_native_sync_prim **_sync,
+             const char *class_name, u8 type)
+{
+       struct pvr_sync_native_sync_prim *sync;
+       enum PVRSRV_ERROR error = PVRSRV_OK;
+
+       mutex_lock(&sync_pool_mutex);
+
+       if (list_empty(&sync_pool_free_list)) {
+               /* If there is nothing in the pool, create a new sync prim. */
+               sync = kmalloc(sizeof(struct pvr_sync_native_sync_prim),
+                              GFP_KERNEL);
+               if (!sync) {
+                       pr_err("pvr_sync: %s: Failed to allocate sync data",
+                              __func__);
+                       error = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto err_unlock;
+               }
+
+               error = SyncPrimAlloc(pvr_sync_data.sync_prim_context,
+                                     &sync->client_sync, class_name);
+               if (error != PVRSRV_OK) {
+                       pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)",
+                              __func__, PVRSRVGetErrorStringKM(error));
+                       goto err_free;
+               }
+
+               sync->vaddr = SyncPrimGetFirmwareAddr(sync->client_sync);
+
+               list_add_tail(&sync->list, &sync_pool_active_list);
+               ++sync_pool_created;
+       } else {
+               sync = list_first_entry(&sync_pool_free_list,
+                                       struct pvr_sync_native_sync_prim, list);
+               list_move_tail(&sync->list, &sync_pool_active_list);
+               --sync_pool_size;
+               ++sync_pool_reused;
+       }
+
+       sync->id = atomic_inc_return(&pvr_sync_data.sync_id);
+       sync->type = type;
+
+       strncpy(sync->class, class_name, sizeof(sync->class));
+       /* Its crucial to reset the sync to zero */
+       set_sync_value(sync, 0);
+       sync->next_value = 0;
+
+       *_sync = sync;
+err_unlock:
+       mutex_unlock(&sync_pool_mutex);
+       return error;
+
+err_free:
+       kfree(sync);
+       goto err_unlock;
+}
+
+static void sync_pool_put(struct pvr_sync_native_sync_prim *sync)
+{
+       mutex_lock(&sync_pool_mutex);
+
+       if (sync_pool_size < SYNC_MAX_POOL_SIZE) {
+               /* Mark it as unused */
+               set_sync_value(sync, 0xffffffff);
+
+               list_move(&sync->list, &sync_pool_free_list);
+               ++sync_pool_size;
+       } else {
+               /* Mark it as invalid */
+               set_sync_value(sync, 0xdeadbeef);
+
+               list_del(&sync->list);
+               SyncPrimFree(sync->client_sync);
+               kfree(sync);
+       }
+
+       mutex_unlock(&sync_pool_mutex);
+}
+
+static void sync_pool_clear(void)
+{
+       struct pvr_sync_native_sync_prim *sync, *n;
+
+       mutex_lock(&sync_pool_mutex);
+
+       list_for_each_entry_safe(sync, n, &sync_pool_free_list, list) {
+               /* Mark it as invalid */
+               set_sync_value(sync, 0xdeadbeef);
+
+               list_del(&sync->list);
+               SyncPrimFree(sync->client_sync);
+               kfree(sync);
+               --sync_pool_size;
+       }
+
+       mutex_unlock(&sync_pool_mutex);
+}
+
+static void pvr_sync_debug_request(void *hDebugRequestHandle,
+                                  u32 ui32VerbLevel)
+{
+       struct pvr_sync_native_sync_prim *sync;
+
+       static const char *const type_names[] = {
+               "Timeline", "Fence", "Cleanup",
+               "Foreign Fence", "Foreign Cleanup"
+       };
+
+       if (ui32VerbLevel == DEBUG_REQUEST_VERBOSITY_HIGH) {
+               mutex_lock(&sync_pool_mutex);
+
+               PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+                                 "Dumping all pending android native syncs (Pool usage: %d%% - %d %d)",
+                                 sync_pool_reused ?
+                                 (10000 /
+                                  ((sync_pool_created + sync_pool_reused) *
+                                   100 / sync_pool_reused)) : 0,
+                                 sync_pool_created, sync_pool_reused);
+
+               list_for_each_entry(sync, &sync_pool_active_list, list) {
+                       if (is_sync_met(sync))
+                               continue;
+
+                       BUG_ON(sync->type >= ARRAY_SIZE(type_names));
+
+                       PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+                                         "\tID = %d, FWAddr = 0x%08x: Current = 0x%08x, Next = 0x%08x, %s (%s)",
+                                         sync->id, sync->vaddr,
+                                         get_sync_value(sync),
+                                         sync->next_value,
+                                         sync->class,
+                                         type_names[sync->type]);
+               }
+#if 0
+               PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+                                 "Dumping all unused syncs");
+               list_for_each_entry(sync, &sync_pool_free_list, list) {
+                       BUG_ON(sync->type >= ARRAY_SIZE(type_names));
+
+                       PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+                                         "\tID = %d, FWAddr = 0x%08x: Current = 0x%08x, Next = 0x%08x, %s (%s)",
+                                         sync->id, sync->vaddr,
+                                         get_sync_value(sync),
+                                         sync->next_value,
+                                         sync->class,
+                                         type_names[sync->type]);
+               }
+#endif
+               mutex_unlock(&sync_pool_mutex);
+       }
+}
+
+static struct sync_pt *pvr_sync_dup(struct sync_pt *sync_pt)
+{
+       struct pvr_sync_pt *pvr_pt_a = (struct pvr_sync_pt *)sync_pt;
+       struct pvr_sync_pt *pvr_pt_b = NULL;
+
+       DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt));
+
+       pvr_pt_b = (struct pvr_sync_pt *)
+               sync_pt_create(sync_pt_parent(sync_pt),
+                              sizeof(struct pvr_sync_pt));
+       if (!pvr_pt_b) {
+               pr_err("pvr_sync: %s: Failed to dup sync pt", __func__);
+               goto err_out;
+       }
+
+       kref_get(&pvr_pt_a->sync_data->kref);
+
+       pvr_pt_b->sync_data = pvr_pt_a->sync_data;
+
+err_out:
+       return (struct sync_pt *)pvr_pt_b;
+}
+
+static int pvr_sync_has_signaled(struct sync_pt *sync_pt)
+{
+       struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt;
+
+       DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt));
+
+       return pvr_sync_has_kernel_signaled(pvr_pt->sync_data->kernel);
+}
+
+static int pvr_sync_compare(struct sync_pt *a, struct sync_pt *b)
+{
+       u32 a1 = ((struct pvr_sync_pt *)a)->sync_data->timeline_update_value;
+       u32 b1 = ((struct pvr_sync_pt *)b)->sync_data->timeline_update_value;
+
+       DPF("%s: a # %s", __func__, debug_info_sync_pt(a));
+       DPF("%s: b # %s", __func__, debug_info_sync_pt(b));
+
+       if (a1 == b1)
+               return 0;
+
+       /* Take integer wrapping into account */
+       return ((s32)a1 - (s32)b1) < 0 ? -1 : 1;
+}
+
+static void wait_for_sync(struct pvr_sync_native_sync_prim *sync)
+{
+#ifndef NO_HARDWARE
+       void *event_object = NULL;
+       enum PVRSRV_ERROR error = PVRSRV_OK;
+
+       while (sync && !is_sync_met(sync)) {
+               if (!event_object) {
+                       error = OSEventObjectOpen(
+                               pvr_sync_data.event_object_handle,
+                               &event_object);
+                       if (error != PVRSRV_OK) {
+                               pr_err("pvr_sync: %s: Error opening event object (%s)\n",
+                                       __func__,
+                                       PVRSRVGetErrorStringKM(error));
+                               break;
+                       }
+               }
+               error = OSEventObjectWait(event_object);
+               if (error != PVRSRV_OK && error != PVRSRV_ERROR_TIMEOUT) {
+                       pr_err("pvr_sync: %s: Error waiting on event object (%s)\n",
+                               __func__,
+                               PVRSRVGetErrorStringKM(error));
+               }
+       }
+
+       if (event_object)
+               OSEventObjectClose(event_object);
+#endif
+}
+
+static void pvr_sync_defer_free(struct pvr_sync_kernel_pair *kernel)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&sync_prim_free_list_spinlock, flags);
+       list_add_tail(&kernel->list, &sync_prim_free_list);
+       spin_unlock_irqrestore(&sync_prim_free_list_spinlock, flags);
+
+       queue_work(pvr_sync_data.defer_free_wq, &pvr_sync_data.defer_free_work);
+}
+
+/* This function assumes the timeline_list_mutex is held while it runs */
+
+static void pvr_sync_destroy_timeline_locked(struct kref *kref)
+{
+       struct pvr_sync_timeline *timeline = (struct pvr_sync_timeline *)
+               container_of(kref, struct pvr_sync_timeline, kref);
+
+       pvr_sync_defer_free(timeline->kernel);
+       list_del(&timeline->list);
+       kfree(timeline);
+}
+
+static void pvr_sync_destroy_timeline(struct kref *kref)
+{
+       mutex_lock(&timeline_list_mutex);
+       pvr_sync_destroy_timeline_locked(kref);
+       mutex_unlock(&timeline_list_mutex);
+}
+
+static void pvr_sync_release_timeline(struct sync_timeline *obj)
+{
+       struct pvr_sync_timeline *timeline = get_timeline(obj);
+
+       /* If pvr_sync_open failed after calling sync_timeline_create, this
+        * can be called with a timeline that has not got a timeline sync
+        * or been added to our timeline list. Use a NULL timeline to
+        * detect and handle this condition
+        */
+       if (!timeline)
+               return;
+
+       DPF("%s: # %s", __func__, debug_info_timeline(timeline));
+
+       wait_for_sync(timeline->kernel->fence_sync);
+
+       /* Whether or not we're the last reference, obj is going away
+        * after this function returns, so remove our back reference
+        * to it.
+        */
+       timeline->obj = NULL;
+
+       /* This might be the last reference to the timeline object.
+        * If so, we'll go ahead and delete it now.
+        */
+       kref_put(&timeline->kref, pvr_sync_destroy_timeline);
+}
+
+/* The print_obj() and print_pt() functions have been removed, so we're forced
+ * to use the timeline_value_str() and pt_value_str() functions. These are
+ * worse because we're limited to 64 characters, and the strings for sync
+ * pts have to be formatted like:
+ *
+ *   pt active: pt_info / tl_info
+ *
+ * For us, the tl_info is complicated and doesn't need to be repeated over
+ * and over. So try to detect the way sync_print_pt() calls the two value_str
+ * functions and change what pvr_sync_timeline_value_str() returns dynamically.
+ */
+static struct sync_timeline *last_pt_timeline;
+
+static void pvr_sync_timeline_value_str(struct sync_timeline *sync_timeline,
+                                       char *str, int size)
+{
+       struct pvr_sync_timeline *timeline = get_timeline(sync_timeline);
+
+       if (sync_timeline != last_pt_timeline) {
+               snprintf(str, size, "%u 0x%x %u/%u",
+                        timeline->kernel->fence_sync->id,
+                        timeline->kernel->fence_sync->vaddr,
+                        get_sync_value(timeline->kernel->fence_sync),
+                        timeline->kernel->fence_sync->next_value);
+       } else {
+               snprintf(str, size, "%u",
+                        get_sync_value(timeline->kernel->fence_sync));
+       }
+}
+
+static void pvr_sync_pt_value_str(struct sync_pt *sync_pt, char *str, int size)
+{
+       struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt;
+       struct pvr_sync_kernel_pair *kernel;
+
+       if (!pvr_pt->sync_data)
+               return;
+
+       kernel = pvr_pt->sync_data->kernel;
+
+       /* Messages must be at most 64 bytes (including the null terminator):
+        *
+        * 123456789012345678901234567890123456789012345678901234567890123
+        *
+        * ID     FW ADDR    C/N # REF TAKEN
+        * 123456 0xdeadbeef 0/1 # r=2 123456
+        *
+        * ID     FW ADDR    C/N # ID     FW ADDR    C/N # REF TAKEN
+        * 123456 0xdeadbeef 0/1 # 123456 0xdeadbeef 0/1 # r=2 123456
+        */
+       if (kernel) {
+               if (!kernel->cleanup_sync) {
+                       snprintf(str, size,
+                                "%u 0x%x %u/%u r=%d %u",
+                                kernel->fence_sync->id,
+                                kernel->fence_sync->vaddr,
+                                get_sync_value(kernel->fence_sync),
+                                kernel->fence_sync->next_value,
+                                atomic_read(&pvr_pt->sync_data->kref.refcount),
+                                pvr_pt->sync_data->timeline_update_value);
+               } else {
+                       snprintf(str, size,
+                                "%u 0x%x %u/%u # %u 0x%x %u/%u # r=%d %u",
+                                kernel->fence_sync->id,
+                                kernel->fence_sync->vaddr,
+                                get_sync_value(kernel->fence_sync),
+                                kernel->fence_sync->next_value,
+                                kernel->cleanup_sync->id,
+                                kernel->cleanup_sync->vaddr,
+                                get_sync_value(kernel->cleanup_sync),
+                                kernel->cleanup_sync->next_value,
+                                atomic_read(&pvr_pt->sync_data->kref.refcount),
+                                pvr_pt->sync_data->timeline_update_value);
+               }
+       } else {
+               snprintf(str, size, "idle # r=%d %u",
+                        atomic_read(&pvr_pt->sync_data->kref.refcount),
+                        pvr_pt->sync_data->timeline_update_value);
+       }
+
+       last_pt_timeline = sync_pt_parent(sync_pt);
+}
+
+static struct pvr_sync_data *
+pvr_sync_create_sync_data(struct sync_timeline *obj)
+{
+       struct pvr_sync_data *sync_data = NULL;
+       enum PVRSRV_ERROR error;
+
+       sync_data = kzalloc(sizeof(struct pvr_sync_data), GFP_KERNEL);
+       if (!sync_data)
+               goto err_out;
+
+       kref_init(&sync_data->kref);
+
+       sync_data->kernel =
+               kzalloc(sizeof(struct pvr_sync_kernel_pair),
+               GFP_KERNEL);
+
+       if (!sync_data->kernel)
+               goto err_free_data;
+
+       OSAcquireBridgeLock();
+       error = sync_pool_get(&sync_data->kernel->fence_sync,
+                             obj->name, SYNC_PT_FENCE_TYPE);
+       OSReleaseBridgeLock();
+
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               goto err_free_kernel;
+       }
+
+err_out:
+       return sync_data;
+
+err_free_kernel:
+       kfree(sync_data->kernel);
+err_free_data:
+       kfree(sync_data);
+       sync_data = NULL;
+       goto err_out;
+}
+
+static void pvr_sync_free_sync_data(struct kref *kref)
+{
+       struct pvr_sync_data *sync_data = (struct pvr_sync_data *)
+               container_of(kref, struct pvr_sync_data, kref);
+
+       if (sync_data->kernel)
+               pvr_sync_defer_free(sync_data->kernel);
+       kfree(sync_data);
+}
+
+static void pvr_sync_free_sync(struct sync_pt *sync_pt)
+{
+       struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt;
+
+       DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt));
+
+       kref_put(&pvr_pt->sync_data->kref, pvr_sync_free_sync_data);
+}
+
+/* this function uses pvr_sync_timeline_ops defined below */
+static int pvr_sync_fill_driver_data(struct sync_pt *, void *, int);
+
+static struct sync_timeline_ops pvr_sync_timeline_ops = {
+       .driver_name        = PVRSYNC_MODNAME,
+       .dup                = pvr_sync_dup,
+       .has_signaled       = pvr_sync_has_signaled,
+       .compare            = pvr_sync_compare,
+       .free_pt            = pvr_sync_free_sync,
+       .release_obj        = pvr_sync_release_timeline,
+       .timeline_value_str = pvr_sync_timeline_value_str,
+       .pt_value_str       = pvr_sync_pt_value_str,
+       .fill_driver_data   = pvr_sync_fill_driver_data,
+};
+
+static inline bool is_pvr_timeline(struct sync_timeline *obj)
+{
+       return obj->ops == &pvr_sync_timeline_ops;
+}
+
+static inline bool is_pvr_timeline_pt(struct sync_pt *pt)
+{
+       return is_pvr_timeline(sync_pt_parent(pt));
+}
+
+static int
+pvr_sync_fill_driver_data(struct sync_pt *sync_pt, void *data, int size)
+{
+       struct pvr_sync_pt_info *info = (struct pvr_sync_pt_info *)data;
+       struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt;
+       struct pvr_sync_data *sync_data = pvr_pt->sync_data;
+       struct pvr_sync_kernel_pair *kernel = sync_data->kernel;
+
+       if (size < sizeof(struct pvr_sync_pt_info))
+               return -ENOMEM;
+
+       info->ui32TlTaken = sync_data->timeline_update_value;
+
+       if (kernel) {
+               info->id         = kernel->fence_sync->id;
+               info->ui32FWAddr = kernel->fence_sync->vaddr;
+               info->ui32CurrOp = get_sync_value(kernel->fence_sync);
+               info->ui32NextOp = kernel->fence_sync->next_value;
+       } else {
+               info->id         = 0;
+               info->ui32FWAddr = 0;
+               info->ui32CurrOp = 0;
+               info->ui32NextOp = 0;
+       }
+
+       return sizeof(struct pvr_sync_pt_info);
+}
+
+/* foreign sync handling */
+
+static void pvr_sync_foreign_sync_pt_signaled(struct sync_fence *fence,
+                                             struct sync_fence_waiter *_waiter)
+{
+       struct pvr_sync_fence_waiter *waiter =
+               (struct pvr_sync_fence_waiter *)_waiter;
+       unsigned long flags;
+
+       /* Complete the SW operation and free the sync if we can. If we can't,
+        * it will be checked by a later workqueue kick. */
+       complete_sync(waiter->kernel->fence_sync);
+
+       /* We can 'put' the fence now, but this function might be called in
+       * irq context so we must defer to WQ.
+       * This WQ is triggered in pvr_sync_defer_free, so adding it to the
+       * put list before that should guarantee it's cleaned up on the next
+       * wq run */
+       spin_lock_irqsave(&sync_fence_put_list_spinlock, flags);
+       list_add_tail(&waiter->sync_fence->list, &sync_fence_put_list);
+       spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags);
+
+       pvr_sync_defer_free(waiter->kernel);
+
+       /* The completed sw-sync may allow other tasks to complete,
+        * so we need to allow them to progress */
+       queue_work(pvr_sync_data.check_status_wq,
+               &pvr_sync_data.check_status_work);
+
+       kfree(waiter);
+}
+
+static struct pvr_sync_kernel_pair *
+pvr_sync_create_waiter_for_foreign_sync(int fd)
+{
+       struct pvr_sync_kernel_pair *kernel = NULL;
+       struct pvr_sync_fence_waiter *waiter;
+       struct pvr_sync_fence *sync_fence;
+       struct sync_fence *fence;
+       enum PVRSRV_ERROR error;
+       int err;
+
+       fence = sync_fence_fdget(fd);
+       if (!fence) {
+               pr_err("pvr_sync: %s: Failed to take reference on fence",
+                      __func__);
+               goto err_out;
+       }
+
+       kernel = kmalloc(sizeof(struct pvr_sync_kernel_pair), GFP_KERNEL);
+       if (!kernel) {
+               pr_err("pvr_sync: %s: Failed to allocate sync kernel",
+                      __func__);
+               goto err_put_fence;
+       }
+
+       sync_fence = kmalloc(sizeof(struct pvr_sync_fence), GFP_KERNEL);
+       if (!sync_fence) {
+               pr_err("pvr_sync: %s: Failed to allocate pvr sync fence",
+                      __func__);
+               goto err_free_kernel;
+       }
+
+       sync_fence->fence = fence;
+
+       error = sync_pool_get(&kernel->fence_sync,
+                             fence->name, SYNC_PT_FOREIGN_FENCE_TYPE);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               goto err_free_sync_fence;
+       }
+
+       kernel->fence_sync->next_value++;
+
+       error = sync_pool_get(&kernel->cleanup_sync,
+                             fence->name, SYNC_PT_FOREIGN_CLEANUP_TYPE);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to allocate cleanup sync prim (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               goto err_free_sync;
+       }
+
+       kernel->cleanup_sync->next_value++;
+
+       /* The custom waiter structure is freed in the waiter callback */
+       waiter = kmalloc(sizeof(struct pvr_sync_fence_waiter), GFP_KERNEL);
+       if (!waiter) {
+               pr_err("pvr_sync: %s: Failed to allocate waiter", __func__);
+               goto err_free_cleanup_sync;
+       }
+
+       waiter->kernel = kernel;
+       waiter->sync_fence = sync_fence;
+
+       sync_fence_waiter_init(&waiter->waiter,
+                              pvr_sync_foreign_sync_pt_signaled);
+
+       err = sync_fence_wait_async(fence, &waiter->waiter);
+       if (err) {
+               if (err < 0) {
+                       pr_err("pvr_sync: %s: Fence was in error state (%d)",
+                              __func__, err);
+                       /* Fall-thru */
+               }
+
+               /* -1 means the fence was broken, 1 means the fence already
+                * signalled. In either case, roll back what we've done and
+                * skip using this sync_pt for synchronization.
+                */
+               goto err_free_waiter;
+       }
+
+err_out:
+       return kernel;
+err_free_waiter:
+       kfree(waiter);
+err_free_cleanup_sync:
+       sync_pool_put(kernel->cleanup_sync);
+err_free_sync:
+       sync_pool_put(kernel->fence_sync);
+err_free_sync_fence:
+       kfree(sync_fence);
+err_free_kernel:
+       kfree(kernel);
+       kernel = NULL;
+err_put_fence:
+       sync_fence_put(fence);
+       goto err_out;
+}
+
+enum PVRSRV_ERROR pvr_sync_append_fences(
+       const char                  *name,
+       const u32                   nr_check_fences,
+       const s32                   *check_fence_fds,
+       const s32                   update_fence_fd,
+       const u32                   nr_updates,
+       const PRGXFWIF_UFO_ADDR     *update_ufo_addresses,
+       const u32                   *update_values,
+       const u32                   nr_checks,
+       const PRGXFWIF_UFO_ADDR     *check_ufo_addresses,
+       const u32                   *check_values,
+       struct pvr_sync_append_data **append_sync_data)
+{
+       struct pvr_sync_append_data *sync_data;
+       enum PVRSRV_ERROR err = PVRSRV_OK;
+       struct pvr_sync_native_sync_prim **cleanup_sync_pos;
+       PRGXFWIF_UFO_ADDR *update_address_pos;
+       PRGXFWIF_UFO_ADDR *check_address_pos;
+       u32 *update_value_pos;
+       u32 *check_value_pos;
+       unsigned num_used_sync_checks;
+       unsigned num_used_sync_updates;
+       struct pvr_sync_alloc_data *alloc_sync_data = NULL;
+       unsigned i;
+
+       if ((nr_updates && (!update_ufo_addresses || !update_values)) ||
+               (nr_checks && (!check_ufo_addresses || !check_values)))
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       sync_data =
+               kzalloc(sizeof(struct pvr_sync_append_data)
+                       + nr_check_fences * sizeof(struct sync_fence *),
+                       GFP_KERNEL);
+       if (!sync_data) {
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_out;
+       }
+
+       sync_data->nr_checks = nr_checks;
+       sync_data->nr_updates = nr_updates;
+
+       sync_data->nr_fences = nr_check_fences;
+
+       /* Loop through once to get the fences and count the total number of
+        * points */
+       for (i = 0; i < nr_check_fences; i++) {
+               struct sync_fence *fence = sync_fence_fdget(check_fence_fds[i]);
+               struct pvr_sync_kernel_pair *sync_kernel;
+               unsigned int points_on_fence = 0;
+               bool has_foreign_point = false;
+               struct sync_pt *sync_pt;
+               int j;
+
+               if (!fence) {
+                       pr_err("pvr_sync: %s: Failed to read sync private data for fd %d\n",
+                               __func__, check_fence_fds[i]);
+                       err = PVRSRV_ERROR_HANDLE_NOT_FOUND;
+                       goto err_free_append_data;
+               }
+
+               sync_data->fences[i] = fence;
+
+               for_each_sync_pt(sync_pt, fence, j) {
+                       struct pvr_sync_pt *pvr_pt;
+
+                       if (!is_pvr_timeline_pt(sync_pt)) {
+                               if (!sync_pt_get_status(sync_pt))
+                                       has_foreign_point = true;
+                               continue;
+                       }
+
+                       pvr_pt = (struct pvr_sync_pt *)sync_pt;
+                       sync_kernel = pvr_pt->sync_data->kernel;
+
+                       if (!sync_kernel ||
+                           is_sync_met(sync_kernel->fence_sync)) {
+                               continue;
+                       }
+                       /* We will use the above sync for "check" only. In this
+                       * case also insert a "cleanup" update command into the
+                       * opengl stream. This can later be used for checking if
+                       * the sync prim could be freed. */
+                       if (!sync_kernel->cleanup_sync) {
+                               err = sync_pool_get(&sync_kernel->cleanup_sync,
+                                       sync_pt_parent(&pvr_pt->pt)->name,
+                                       SYNC_PT_CLEANUP_TYPE);
+                               if (err != PVRSRV_OK) {
+                                       pr_err("pvr_sync: %s: Failed to allocate cleanup sync prim (%s)",
+                                              __func__,
+                                              PVRSRVGetErrorStringKM(err));
+                                       goto err_free_append_data;
+                               }
+                       }
+                       points_on_fence++;
+               }
+
+               if (has_foreign_point)
+                       points_on_fence++;
+
+               /* Each point has 1 check value, and 1 update value (for the
+                * cleanup fence) */
+               sync_data->nr_checks += points_on_fence;
+               sync_data->nr_updates += points_on_fence;
+               sync_data->nr_cleaup_syncs += points_on_fence;
+       }
+
+       if (update_fence_fd >= 0) {
+               alloc_sync_data = pvr_sync_alloc_fence_fdget(update_fence_fd);
+               if (!alloc_sync_data) {
+                       pr_err("pvr_sync: %s: Failed to read alloc sync private data for fd %d\n",
+                               __func__, update_fence_fd);
+                       err = PVRSRV_ERROR_HANDLE_NOT_FOUND;
+                       goto err_free_append_data;
+               }
+               /* Store the alloc sync data now, so it's correctly fput()
+                * even on error */
+               sync_data->update_sync_data = alloc_sync_data;
+               /* If an alloc-sync has already been appended to a kick that
+                * is an error (and the sync_data will be NULL */
+               if (!alloc_sync_data->sync_data) {
+                       pr_err("pvr_sync: %s: Failed to read alloc sync sync_data for fd %d\n",
+                               __func__, update_fence_fd);
+                       err = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+                       goto err_free_append_data;
+
+               }
+               /* A fence update requires 2 update values (fence and timeline)
+                */
+                sync_data->nr_updates += 2;
+       }
+
+       sync_data->update_ufo_addresses =
+               kzalloc(sizeof(PRGXFWIF_UFO_ADDR) * sync_data->nr_updates,
+                       GFP_KERNEL);
+       if (!sync_data->update_ufo_addresses) {
+               pr_err("pvr_sync: %s: Failed to allocate update UFO address list\n",
+                       __func__);
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_free_append_data;
+       }
+
+       sync_data->update_values =
+               kzalloc(sizeof(u32) * sync_data->nr_updates,
+                       GFP_KERNEL);
+       if (!sync_data->update_values) {
+               pr_err("pvr_sync: %s: Failed to allocate update value list\n",
+                       __func__);
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_free_append_data;
+       }
+
+       sync_data->check_ufo_addresses =
+               kzalloc(sizeof(PRGXFWIF_UFO_ADDR) * sync_data->nr_checks,
+                       GFP_KERNEL);
+       if (!sync_data->check_ufo_addresses) {
+               pr_err("pvr_sync: %s: Failed to allocate check UFO address list\n",
+                       __func__);
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_free_append_data;
+       }
+
+       sync_data->check_values =
+               kzalloc(sizeof(u32) * sync_data->nr_checks,
+                       GFP_KERNEL);
+       if (!sync_data->check_values) {
+               pr_err("pvr_sync: %s: Failed to allocate check value list\n",
+                       __func__);
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_free_append_data;
+       }
+
+       sync_data->cleanup_syncs =
+               kzalloc(sizeof(struct pvr_sync_native_sync_prim *) *
+                       sync_data->nr_cleaup_syncs, GFP_KERNEL);
+       if (!sync_data->cleanup_syncs) {
+               pr_err("pvr_sync: %s: Failed to allocate cleanup rollback list\n",
+                       __func__);
+               err = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_free_append_data;
+       }
+
+       update_address_pos = sync_data->update_ufo_addresses;
+       update_value_pos = sync_data->update_values;
+       check_address_pos = sync_data->check_ufo_addresses;
+       check_value_pos = sync_data->check_values;
+       cleanup_sync_pos = sync_data->cleanup_syncs;
+
+
+       /* Everything should be allocated/sanity checked. No errors are possible
+        * after this point */
+
+       /* Append any check syncs */
+       for (i = 0; i < nr_check_fences; i++) {
+               struct sync_fence *fence = sync_data->fences[i];
+               bool has_foreign_point = false;
+               struct sync_pt *sync_pt;
+               int j;
+
+               for_each_sync_pt(sync_pt, fence, j) {
+                       struct pvr_sync_pt *pvr_pt;
+                       struct pvr_sync_kernel_pair *sync_kernel;
+
+                       if (!is_pvr_timeline_pt(sync_pt)) {
+                               if (!sync_pt_get_status(sync_pt))
+                                       has_foreign_point = true;
+                               continue;
+                       }
+
+                       pvr_pt = (struct pvr_sync_pt *)sync_pt;
+                       sync_kernel = pvr_pt->sync_data->kernel;
+
+                       if (!sync_kernel ||
+                           is_sync_met(sync_kernel->fence_sync)) {
+                               continue;
+                       }
+
+                       (*check_address_pos++).ui32Addr =
+                               sync_kernel->fence_sync->vaddr;
+                       *check_value_pos++ =
+                               sync_kernel->fence_sync->next_value;
+
+                       (*update_address_pos++).ui32Addr =
+                               sync_kernel->cleanup_sync->vaddr;
+                       *update_value_pos++ =
+                               ++sync_kernel->cleanup_sync->next_value;
+                       *cleanup_sync_pos++ = sync_kernel->cleanup_sync;
+               }
+
+               if (has_foreign_point) {
+                       struct pvr_sync_kernel_pair *foreign_sync_kernel =
+                               pvr_sync_create_waiter_for_foreign_sync(
+                                       check_fence_fds[i]);
+
+                       if (foreign_sync_kernel) {
+                               struct pvr_sync_native_sync_prim *fence_sync =
+                                       foreign_sync_kernel->fence_sync;
+                               struct pvr_sync_native_sync_prim *cleanup_sync =
+                                       foreign_sync_kernel->cleanup_sync;
+
+
+                               (*check_address_pos++).ui32Addr =
+                                       fence_sync->vaddr;
+                               *check_value_pos++ =
+                                       fence_sync->next_value;
+
+                               (*update_address_pos++).ui32Addr =
+                                       cleanup_sync->vaddr;
+                               *update_value_pos++ =
+                                       ++cleanup_sync->next_value;
+                               *cleanup_sync_pos++ = cleanup_sync;
+                       }
+               }
+       }
+
+       /* Append the update sync (if supplied) */
+       if (sync_data->update_sync_data) {
+               struct pvr_sync_alloc_data *update_data =
+                       sync_data->update_sync_data;
+               struct pvr_sync_timeline *timeline =
+                       update_data->timeline;
+               struct pvr_sync_kernel_pair *sync_kernel =
+                       update_data->sync_data->kernel;
+
+               (*update_address_pos++).ui32Addr =
+                       sync_kernel->fence_sync->vaddr;
+               *update_value_pos++ =
+                       ++sync_kernel->fence_sync->next_value;
+
+               (*update_address_pos++).ui32Addr =
+                       timeline->kernel->fence_sync->vaddr;
+
+               /* Increment the timeline value... */
+               update_data->sync_data->timeline_update_value =
+                       ++timeline->kernel->fence_sync->next_value;
+
+               /* ...and set that to be updated when this kick is completed */
+               *update_value_pos++ =
+                       update_data->sync_data->timeline_update_value;
+
+
+               /* Reset the fencing enabled flag. If nobody sets this to 1
+                * until the next fence point is inserted, we will do timeline
+                * idle detection. */
+               timeline->fencing_enabled = false;
+       }
+       /* We count the total number of sync points we attach, as it's possible
+       * some have become complete since the first loop through, or a waiter
+       * for a foreign point skipped (But they can never become un-complete, so
+       * it will only ever be the same or less, so the allocated arrays should
+       * still be sufficiently sized) */
+       num_used_sync_updates =
+               update_address_pos - sync_data->update_ufo_addresses;
+       num_used_sync_checks =
+               check_address_pos - sync_data->check_ufo_addresses;
+
+
+       sync_data->nr_checks = nr_checks + num_used_sync_checks;
+       sync_data->nr_updates = nr_updates + num_used_sync_updates;
+       /* Append original check and update sync values/addresses */
+       if (update_ufo_addresses)
+               memcpy(update_address_pos, update_ufo_addresses,
+                          sizeof(PRGXFWIF_UFO_ADDR) * nr_updates);
+       if (update_values)
+               memcpy(update_value_pos, update_values,
+                          sizeof(u32) * nr_updates);
+
+       if (check_ufo_addresses)
+               memcpy(check_address_pos, check_ufo_addresses,
+                          sizeof(PRGXFWIF_UFO_ADDR) * nr_checks);
+       if (check_values)
+               memcpy(check_value_pos, check_values,
+                          sizeof(u32) * nr_checks);
+
+       *append_sync_data = sync_data;
+
+       return PVRSRV_OK;
+
+err_free_append_data:
+       pvr_sync_free_append_fences_data(sync_data);
+err_out:
+       return err;
+}
+
+void pvr_sync_get_updates(const struct pvr_sync_append_data *sync_data,
+       u32 *nr_fences, PRGXFWIF_UFO_ADDR **ufo_addrs, u32 **values)
+{
+       *nr_fences = sync_data->nr_updates;
+       *ufo_addrs = sync_data->update_ufo_addresses;
+       *values = sync_data->update_values;
+}
+
+void pvr_sync_get_checks(const struct pvr_sync_append_data *sync_data,
+       u32 *nr_fences, PRGXFWIF_UFO_ADDR **ufo_addrs, u32 **values)
+{
+       *nr_fences = sync_data->nr_checks;
+       *ufo_addrs = sync_data->check_ufo_addresses;
+       *values = sync_data->check_values;
+}
+
+void pvr_sync_rollback_append_fences(
+       struct pvr_sync_append_data *sync_append_data)
+{
+       unsigned i;
+
+       if (!sync_append_data)
+               return;
+
+       for (i = 0; i < sync_append_data->nr_cleaup_syncs; i++) {
+               struct pvr_sync_native_sync_prim *cleanup_sync =
+                       sync_append_data->cleanup_syncs[i];
+               /* If this cleanup was called on a partially-created data set
+                * it's possible to have NULL cleanup sync pointers */
+               if (!cleanup_sync)
+                       continue;
+               cleanup_sync->next_value--;
+       }
+
+       if (sync_append_data->update_sync_data) {
+               struct pvr_sync_data *sync_data =
+                       sync_append_data->update_sync_data->sync_data;
+               struct pvr_sync_timeline *timeline =
+                       sync_append_data->update_sync_data->timeline;
+               /* We can get a NULL sync_data if the corresponding
+                * append failed with a re-used alloc sync */
+               if (sync_data) {
+                       sync_data->kernel->fence_sync->next_value--;
+                       timeline->fencing_enabled = true;
+                       timeline->kernel->fence_sync->next_value--;
+               }
+       }
+}
+
+void pvr_sync_free_append_fences_data(
+       struct pvr_sync_append_data *sync_append_data)
+{
+       unsigned i;
+
+       if (!sync_append_data)
+               return;
+
+       for (i = 0; i < sync_append_data->nr_fences; i++) {
+               struct sync_fence *fence = sync_append_data->fences[i];
+               /* If this cleanup was called on a partially-created data set
+                * it's possible to have NULL sync data pointers */
+               if (!fence)
+                       continue;
+               sync_fence_put(fence);
+       }
+
+       if (sync_append_data->update_sync_data)
+               fput(sync_append_data->update_sync_data->file);
+
+       kfree(sync_append_data->update_ufo_addresses);
+       kfree(sync_append_data->update_values);
+       kfree(sync_append_data->check_ufo_addresses);
+       kfree(sync_append_data->check_values);
+       kfree(sync_append_data->cleanup_syncs);
+       kfree(sync_append_data);
+}
+
+void pvr_sync_nohw_complete_fences(
+       struct pvr_sync_append_data *sync_append_data)
+{
+       unsigned i;
+
+       if (!sync_append_data)
+               return;
+
+       for (i = 0; i < sync_append_data->nr_cleaup_syncs; i++) {
+               struct pvr_sync_native_sync_prim *cleanup_sync =
+                       sync_append_data->cleanup_syncs[i];
+
+               if (!cleanup_sync)
+                       continue;
+
+               complete_sync(cleanup_sync);
+       }
+       if (sync_append_data->update_sync_data) {
+               /* Skip any invalid update syncs (should only be hit on error */
+               if (sync_append_data->update_sync_data->sync_data) {
+                       struct pvr_sync_data *sync_data =
+                               sync_append_data->update_sync_data->sync_data;
+                       struct pvr_sync_timeline *timeline =
+                               sync_append_data->update_sync_data->timeline;
+                       complete_sync(sync_data->kernel->fence_sync);
+                       set_sync_value(timeline->kernel->fence_sync,
+                               sync_data->timeline_update_value);
+               }
+       }
+}
+
+/* ioctl and fops handling */
+
+static int pvr_sync_open(struct inode *inode, struct file *file)
+{
+       struct pvr_sync_timeline_wrapper *timeline_wrapper;
+       struct pvr_sync_timeline *timeline;
+       char task_comm[TASK_COMM_LEN];
+       enum PVRSRV_ERROR error;
+       int err = -ENOMEM;
+
+       get_task_comm(task_comm, current);
+
+       timeline_wrapper = (struct pvr_sync_timeline_wrapper *)
+               sync_timeline_create(&pvr_sync_timeline_ops,
+                       sizeof(struct pvr_sync_timeline_wrapper), task_comm);
+       if (!timeline_wrapper) {
+               pr_err("pvr_sync: %s: sync_timeline_create failed", __func__);
+               goto err_out;
+       }
+
+       timeline = kmalloc(sizeof(struct pvr_sync_timeline), GFP_KERNEL);
+       if (!timeline) {
+               pr_err("pvr_sync: %s: Out of memory", __func__);
+               goto err_free_timeline_wrapper;
+       }
+
+       timeline->kernel = kzalloc(sizeof(struct pvr_sync_kernel_pair),
+                                  GFP_KERNEL);
+       if (!timeline->kernel) {
+               pr_err("pvr_sync: %s: Out of memory", __func__);
+               goto err_free_timeline;
+       }
+
+       OSAcquireBridgeLock();
+       error = sync_pool_get(&timeline->kernel->fence_sync,
+                             task_comm, SYNC_TL_TYPE);
+       OSReleaseBridgeLock();
+
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)",
+                       __func__, PVRSRVGetErrorStringKM(error));
+               goto err_free_timeline_kernel;
+       }
+
+       timeline_wrapper->timeline = timeline;
+
+       timeline->obj = &timeline_wrapper->obj;
+       timeline->fencing_enabled = true;
+       kref_init(&timeline->kref);
+
+       mutex_lock(&timeline_list_mutex);
+       list_add_tail(&timeline->list, &timeline_list);
+       mutex_unlock(&timeline_list_mutex);
+
+       DPF("%s: # %s", __func__, debug_info_timeline(timeline));
+
+       file->private_data = timeline_wrapper;
+       err = 0;
+err_out:
+       return err;
+
+err_free_timeline_kernel:
+       kfree(timeline->kernel);
+err_free_timeline:
+       kfree(timeline);
+
+       /* Use a NULL timeline to detect this partially-setup timeline in the
+        * timeline release function (called by sync_timeline_destroy) and
+        * handle it appropriately.
+        */
+       timeline_wrapper->timeline = NULL;
+err_free_timeline_wrapper:
+       sync_timeline_destroy(&timeline_wrapper->obj);
+       goto err_out;
+}
+
+static int pvr_sync_close(struct inode *inode, struct file *file)
+{
+       struct sync_timeline *obj = file->private_data;
+
+       if (is_pvr_timeline(obj)) {
+               DPF("%s: # %s", __func__,
+                   debug_info_timeline(get_timeline(obj)));
+       }
+
+       sync_timeline_destroy(obj);
+       return 0;
+}
+
+static int pvr_sync_alloc_release(struct inode *inode, struct file *file)
+{
+       struct pvr_sync_alloc_data *alloc_sync_data = file->private_data;
+
+       /* Drop alloc sync's reference to the raw timeline structure. We need
+        * to hold the timeline list lock here too, so we don't race with
+        * pvr_sync_update_all_timelines().
+        */
+       if (kref_put_mutex(&alloc_sync_data->timeline->kref,
+                          pvr_sync_destroy_timeline_locked,
+                          &timeline_list_mutex)) {
+               mutex_unlock(&timeline_list_mutex);
+       }
+
+       /* Normally ->sync_data is NULL unless the fd was never used */
+       if (alloc_sync_data->sync_data) {
+               kref_put(&alloc_sync_data->sync_data->kref,
+                        pvr_sync_free_sync_data);
+       }
+
+       kfree(alloc_sync_data);
+       return 0;
+}
+
+static const struct file_operations pvr_alloc_sync_fops = {
+       .release = pvr_sync_alloc_release,
+};
+
+static struct pvr_sync_alloc_data *pvr_sync_alloc_fence_fdget(int fd)
+{
+       struct file *file = fget(fd);
+
+       if (!file)
+               return NULL;
+       if (file->f_op != &pvr_alloc_sync_fops)
+               goto err;
+       return file->private_data;
+err:
+       fput(file);
+       return NULL;
+}
+
+static long pvr_sync_ioctl_create_fence(struct pvr_sync_timeline *timeline,
+       void __user *user_data)
+{
+       struct pvr_sync_create_fence_ioctl_data data;
+       struct pvr_sync_alloc_data *alloc_sync_data;
+       int err = -EFAULT, fd = get_unused_fd();
+       struct pvr_sync_data *sync_data;
+       struct pvr_sync_pt *pvr_pt;
+       struct sync_fence *fence;
+
+       if (fd < 0) {
+               pr_err("pvr_sync: %s: Failed to find unused fd (%d)",
+                      __func__, fd);
+               goto err_out;
+       }
+
+       if (!access_ok(VERIFY_READ, user_data, sizeof(data)))
+               goto err_put_fd;
+
+       if (copy_from_user(&data, user_data, sizeof(data)))
+               goto err_put_fd;
+
+       alloc_sync_data = pvr_sync_alloc_fence_fdget(data.iAllocFenceFd);
+       if (!alloc_sync_data) {
+               pr_err("pvr_sync: %s: Invalid alloc sync fd (%d)\n",
+                       __func__, data.iAllocFenceFd);
+               goto err_put_fd;
+       }
+
+       if (alloc_sync_data->timeline != timeline) {
+               pr_err("pvr_sync: %s: Trying to create sync from alloc of timeline %p in timeline %p\n",
+                       __func__, alloc_sync_data->timeline, timeline);
+               fput(alloc_sync_data->file);
+               goto err_put_fd;
+       }
+
+       /* Take ownership of the sync_data */
+       sync_data = alloc_sync_data->sync_data;
+       alloc_sync_data->sync_data = NULL;
+
+       pvr_pt = (struct pvr_sync_pt *)
+               sync_pt_create(timeline->obj, sizeof(struct pvr_sync_pt));
+
+       fput(alloc_sync_data->file);
+
+       if (!pvr_pt) {
+               pr_err("pvr_sync: %s: Failed to create sync pt", __func__);
+               kref_put(&sync_data->kref, pvr_sync_free_sync_data);
+               err = -ENOMEM;
+               goto err_put_fd;
+       }
+
+       /* Point owns the sync data now. Let sync_pt_free() deal with it. */
+       pvr_pt->sync_data = sync_data;
+
+       data.szName[sizeof(data.szName) - 1] = '\0';
+
+       DPF("%s: %d('%s') # %s", __func__,
+           fd, data.szName, debug_info_timeline(timeline));
+
+       fence = sync_fence_create(data.szName, &pvr_pt->pt);
+       if (!fence) {
+               pr_err("pvr_sync: %s: Failed to create a fence (%d)",
+                      __func__, fd);
+               sync_pt_free(&pvr_pt->pt);
+               err = -ENOMEM;
+               goto err_put_fd;
+       }
+
+       data.iFenceFd = fd;
+
+       if (!access_ok(VERIFY_WRITE, user_data, sizeof(data)))
+               goto err_put_fence;
+
+       if (copy_to_user(user_data, &data, sizeof(data)))
+               goto err_put_fence;
+
+       sync_fence_install(fence, fd);
+       err = 0;
+err_out:
+       return err;
+
+err_put_fence:
+       sync_fence_put(fence);
+err_put_fd:
+       put_unused_fd(fd);
+       goto err_out;
+}
+
+static long pvr_sync_ioctl_alloc_fence(struct pvr_sync_timeline *timeline,
+       void __user *user_data)
+{
+       struct pvr_sync_alloc_fence_ioctl_data data;
+       struct pvr_sync_alloc_data *alloc_sync_data;
+       int err = -EFAULT, fd = get_unused_fd();
+       struct pvr_sync_data *sync_data;
+       struct file *file;
+
+       if (fd < 0) {
+               pr_err("pvr_sync: %s: Failed to find unused fd (%d)",
+                      __func__, fd);
+               goto err_out;
+       }
+
+       if (!access_ok(VERIFY_READ, user_data, sizeof(data)))
+               goto err_put_fd;
+
+       if (!access_ok(VERIFY_WRITE, user_data, sizeof(data)))
+               goto err_put_fd;
+
+       alloc_sync_data =
+               kzalloc(sizeof(struct pvr_sync_alloc_data), GFP_KERNEL);
+       if (!alloc_sync_data) {
+               err = -ENOMEM;
+               pr_err("pvr_sync: %s: Failed to alloc sync data\n", __func__);
+               goto err_put_fd;
+       }
+
+       sync_data = pvr_sync_create_sync_data(timeline->obj);
+       if (!sync_data) {
+               err = -ENOMEM;
+               pr_err("pvr_sync: %s: Failed to create sync data\n", __func__);
+               goto err_free_alloc_data;
+       }
+
+       file = anon_inode_getfile("pvr_sync_alloc", &pvr_alloc_sync_fops,
+               alloc_sync_data, 0);
+       if (!file) {
+               err = -ENOMEM;
+               pr_err("pvr_sync: %s: Failed to create alloc inode\n",
+                       __func__);
+               goto err_free_data;
+       }
+
+       alloc_sync_data->file = file;
+       alloc_sync_data->sync_data = sync_data;
+
+       /* We pass the raw timeline pointer through to the alloc sync, but
+        * to make sure the timeline data doesn't go away if the timeline
+        * is destroyed, we increment the timeline reference count.
+        */
+       alloc_sync_data->timeline = timeline;
+       kref_get(&timeline->kref);
+
+       data.bTimelineIdle = is_sync_met(timeline->kernel->fence_sync) &&
+               timeline->fencing_enabled == false;
+
+       data.iFenceFd = fd;
+
+       if (!access_ok(VERIFY_WRITE, user_data, sizeof(data)))
+               goto err_timeline_kref_put;
+
+       if (copy_to_user(user_data, &data, sizeof(data)))
+               goto err_timeline_kref_put;
+
+       fd_install(fd, file);
+       err = 0;
+
+err_out:
+       return err;
+
+err_timeline_kref_put:
+       if (kref_put_mutex(&timeline->kref,
+                          pvr_sync_destroy_timeline_locked,
+                          &timeline_list_mutex)) {
+               mutex_unlock(&timeline_list_mutex);
+       }
+err_free_data:
+       kref_put(&sync_data->kref, pvr_sync_free_sync_data);
+err_free_alloc_data:
+       kfree(alloc_sync_data);
+err_put_fd:
+       put_unused_fd(fd);
+       goto err_out;
+}
+
+static long pvr_sync_ioctl_enable_fencing(struct pvr_sync_timeline *timeline,
+       void __user *user_data)
+{
+       struct pvr_sync_enable_fencing_ioctl_data data;
+       int err = -EFAULT;
+
+       if (!access_ok(VERIFY_READ, user_data, sizeof(data)))
+               goto err_out;
+
+       if (copy_from_user(&data, user_data, sizeof(data)))
+               goto err_out;
+
+       timeline->fencing_enabled = data.bFencingEnabled;
+       err = 0;
+err_out:
+       return err;
+}
+
+static long pvr_sync_ioctl_rename(struct pvr_sync_timeline *timeline,
+       void __user *user_data)
+{
+       int err = 0;
+       struct pvr_sync_rename_ioctl_data data;
+
+       if (!access_ok(VERIFY_READ, user_data, sizeof(data))) {
+               err = -EFAULT;
+               goto err;
+       }
+
+       if (copy_from_user(&data, user_data, sizeof(data))) {
+               err = -EFAULT;
+               goto err;
+       }
+
+       data.szName[sizeof(data.szName) - 1] = '\0';
+       strlcpy(timeline->obj->name, data.szName, sizeof(timeline->obj->name));
+
+err:
+       return err;
+}
+
+#ifndef CONFIG_SW_SYNC_USER
+
+static long pvr_sync_ioctl_force_sw_only(struct pvr_sync_timeline *timeline,
+       void **private_data)
+{
+       struct sw_sync_timeline *sw_sync_timeline;
+
+       /* We can only convert an empty GPU timeline */
+       if (timeline->kernel->fence_sync->next_value)
+               return -EFAULT;
+
+       /* Create a sw_sync timeline with the old GPU timeline's name */
+       sw_sync_timeline = sw_sync_timeline_create(timeline->obj->name);
+       if (!sw_sync_timeline)
+               return -ENOMEM;
+
+       /* Destroy the old GPU timeline and update the struct file */
+       DPF("%s: # %s", __func__, debug_info_timeline(timeline));
+
+       sync_timeline_destroy(timeline->obj);
+       *private_data = sw_sync_timeline;
+       return 0;
+}
+
+static long pvr_sync_ioctl_sw_create_fence(struct sw_sync_timeline *timeline,
+       void __user *user_data)
+{
+       struct sw_sync_create_fence_data data;
+       struct sync_fence *fence;
+       int fd = get_unused_fd();
+       struct sync_pt *sync_pt;
+       int err = -EFAULT;
+
+       if (fd < 0) {
+               pr_err("pvr_sync: %s: Failed to find unused fd (%d)",
+                      __func__, fd);
+               goto err_out;
+       }
+
+       if (copy_from_user(&data, user_data, sizeof(data)))
+               goto err_put_fd;
+
+       sync_pt = sw_sync_pt_create(timeline, data.value);
+       if (!sync_pt) {
+               pr_err("pvr_sync: %s: Failed to create a sync point (%d)",
+                      __func__, fd);
+               err = -ENOMEM;
+               goto err_put_fd;
+       }
+
+       data.name[sizeof(data.name) - 1] = '\0';
+       fence = sync_fence_create(data.name, sync_pt);
+       if (!fence) {
+               pr_err("pvr_sync: %s: Failed to create a fence (%d)",
+                      __func__, fd);
+               sync_pt_free(sync_pt);
+               err = -ENOMEM;
+               goto err_put_fd;
+       }
+
+       data.fence = fd;
+
+       if (copy_to_user(user_data, &data, sizeof(data)))
+               goto err_put_fence;
+
+       sync_fence_install(fence, fd);
+       err = 0;
+err_out:
+       return err;
+err_put_fence:
+       sync_fence_put(fence);
+err_put_fd:
+       put_unused_fd(fd);
+       goto err_out;
+}
+
+static long pvr_sync_ioctl_sw_inc(struct sw_sync_timeline *timeline,
+       void __user *user_data)
+{
+       u32 value;
+
+       if (copy_from_user(&value, user_data, sizeof(value)))
+               return -EFAULT;
+
+       sw_sync_timeline_inc(timeline, value);
+       return 0;
+}
+
+#endif /* !CONFIG_SW_SYNC_USER */
+
+static long
+pvr_sync_ioctl(struct file *file, unsigned int cmd, unsigned long __user arg)
+{
+       struct sync_timeline *obj = file->private_data;
+       void __user *user_data = (void __user *)arg;
+       long err = -ENOTTY;
+
+       if (is_pvr_timeline(obj)) {
+               struct pvr_sync_timeline *pvr = get_timeline(obj);
+
+               switch (cmd) {
+               case PVR_SYNC_IOC_CREATE_FENCE:
+                       err = pvr_sync_ioctl_create_fence(pvr, user_data);
+                       break;
+               case PVR_SYNC_IOC_ENABLE_FENCING:
+                       err = pvr_sync_ioctl_enable_fencing(pvr, user_data);
+                       break;
+               case PVR_SYNC_IOC_ALLOC_FENCE:
+                       err = pvr_sync_ioctl_alloc_fence(pvr, user_data);
+                       break;
+               case PVR_SYNC_IOC_RENAME:
+                       err = pvr_sync_ioctl_rename(pvr, user_data);
+                       break;
+#ifndef CONFIG_SW_SYNC_USER
+               case PVR_SYNC_IOC_FORCE_SW_ONLY:
+                       err = pvr_sync_ioctl_force_sw_only(pvr,
+                               &file->private_data);
+                       break;
+#endif /* !CONFIG_SW_SYNC_USER */
+               default:
+                       break;
+               }
+       } else {
+#ifndef CONFIG_SW_SYNC_USER
+               struct sw_sync_timeline *sw = file->private_data;
+
+               switch (cmd) {
+               case SW_SYNC_IOC_CREATE_FENCE:
+                       err = pvr_sync_ioctl_sw_create_fence(sw, user_data);
+                       break;
+               case SW_SYNC_IOC_INC:
+                       err = pvr_sync_ioctl_sw_inc(sw, user_data);
+                       break;
+               default:
+                       break;
+               }
+#endif /* !CONFIG_SW_SYNC_USER */
+       }
+
+       return err;
+}
+
+static void
+pvr_sync_check_status_work_queue_function(struct work_struct *data)
+{
+       /* A completed SW operation may un-block the GPU */
+       PVRSRVCheckStatus(NULL);
+}
+
+/* Returns true if the freelist still has entries, else false if empty */
+static bool
+pvr_sync_clean_freelist(void)
+{
+       struct pvr_sync_kernel_pair *kernel, *k;
+       struct pvr_sync_fence *sync_fence, *f;
+       LIST_HEAD(unlocked_free_list);
+       unsigned long flags;
+       bool freelist_empty;
+
+       /* We can't call PVRSRVServerSyncFreeKM directly in this loop because
+        * that will take the mmap mutex. We can't take mutexes while we have
+        * this list locked with a spinlock. So move all the items we want to
+        * free to another, local list (no locking required) and process it
+        * in a second loop. */
+
+       spin_lock_irqsave(&sync_prim_free_list_spinlock, flags);
+       list_for_each_entry_safe(kernel, k, &sync_prim_free_list, list) {
+               /* Check if this sync is not used anymore. */
+               if (!is_sync_met(kernel->fence_sync) ||
+                   (kernel->cleanup_sync &&
+                    !is_sync_met(kernel->cleanup_sync))) {
+                       continue;
+               }
+
+               /* Remove the entry from the free list. */
+               list_move_tail(&kernel->list, &unlocked_free_list);
+       }
+
+       /* Wait and loop if there are still syncs on the free list (IE
+        * are still in use by the HW) */
+       freelist_empty = list_empty(&sync_prim_free_list);
+
+       spin_unlock_irqrestore(&sync_prim_free_list_spinlock, flags);
+
+       OSAcquireBridgeLock();
+
+       list_for_each_entry_safe(kernel, k, &unlocked_free_list, list) {
+               list_del(&kernel->list);
+
+               sync_pool_put(kernel->fence_sync);
+               if (kernel->cleanup_sync)
+                       sync_pool_put(kernel->cleanup_sync);
+               kfree(kernel);
+       }
+
+       OSReleaseBridgeLock();
+
+       /* sync_fence_put() must be called from process/WQ context
+        * because it uses fput(), which is not allowed to be called
+        * from interrupt context in kernels <3.6.
+        */
+       INIT_LIST_HEAD(&unlocked_free_list);
+
+       spin_lock_irqsave(&sync_fence_put_list_spinlock, flags);
+       list_for_each_entry_safe(sync_fence, f, &sync_fence_put_list, list) {
+               list_move_tail(&sync_fence->list, &unlocked_free_list);
+       }
+       spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags);
+
+       list_for_each_entry_safe(sync_fence, f, &unlocked_free_list, list) {
+               list_del(&sync_fence->list);
+               sync_fence_put(sync_fence->fence);
+               kfree(sync_fence);
+       }
+
+       return !freelist_empty;
+}
+
+static void
+pvr_sync_defer_free_work_queue_function(struct work_struct *data)
+{
+       enum PVRSRV_ERROR error = PVRSRV_OK;
+       void *event_object;
+
+       error = OSEventObjectOpen(pvr_sync_data.event_object_handle,
+               &event_object);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Error opening event object (%s)\n",
+                       __func__, PVRSRVGetErrorStringKM(error));
+               return;
+
+       }
+
+       while (pvr_sync_clean_freelist()) {
+
+               error = OSEventObjectWait(event_object);
+
+               switch (error) {
+
+               case PVRSRV_OK:
+               case PVRSRV_ERROR_TIMEOUT:
+                       /* Timeout is normal behaviour */
+                       continue;
+               default:
+                       pr_err("pvr_sync: %s: Error waiting for event object (%s)\n",
+                               __func__, PVRSRVGetErrorStringKM(error));
+                       break;
+               }
+       }
+       error = OSEventObjectClose(event_object);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Error closing event object (%s)\n",
+                       __func__, PVRSRVGetErrorStringKM(error));
+       }
+}
+
+static const struct file_operations pvr_sync_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pvr_sync_open,
+       .release        = pvr_sync_close,
+       .unlocked_ioctl = pvr_sync_ioctl,
+       .compat_ioctl   = pvr_sync_ioctl,
+};
+
+static struct miscdevice pvr_sync_device = {
+       .minor          = MISC_DYNAMIC_MINOR,
+       .name           = PVRSYNC_MODNAME,
+       .fops           = &pvr_sync_fops,
+};
+
+static
+void pvr_sync_update_all_timelines(void *command_complete_handle)
+{
+       struct pvr_sync_timeline *timeline, *n;
+
+       mutex_lock(&timeline_list_mutex);
+
+       list_for_each_entry(timeline, &timeline_list, list) {
+               /* If a timeline is destroyed via pvr_sync_release_timeline()
+                * in parallel with a call to pvr_sync_update_all_timelines(),
+                * the timeline_list_mutex will block destruction of the
+                * 'timeline' pointer. Use kref_get_unless_zero() to detect
+                * and handle this race. Skip the timeline if it's being
+                * destroyed, blocked only on the timeline_list_mutex.
+                */
+               timeline->valid =
+                       kref_get_unless_zero(&timeline->kref) ? true : false;
+       }
+
+       list_for_each_entry_safe(timeline, n, &timeline_list, list) {
+               /* We know timeline is valid at this point because we're
+                * holding the list lock (so pvr_sync_destroy_timeline() has
+                * to wait).
+                */
+               void *obj = timeline->obj;
+
+               /* If we're racing with pvr_sync_release_timeline(), ignore */
+               if (!timeline->valid)
+                       continue;
+
+               /* If syncs have signaled on the GPU, echo this in pvr_sync.
+                *
+                * At this point we know the timeline is valid, but obj might
+                * have raced and been set to NULL. It's only important that
+                * we use NULL / non-NULL consistently with the if() and call
+                * to sync_timeline_signal() -- the timeline->obj can't be
+                * freed (pvr_sync_release_timeline() will be stuck waiting
+                * for the timeline_list_mutex) but it might have been made
+                * invalid by the base sync driver, in which case this call
+                * will bounce harmlessly.
+                */
+               if (obj)
+                       sync_timeline_signal(obj);
+
+               /* We're already holding the timeline_list_mutex */
+               kref_put(&timeline->kref, pvr_sync_destroy_timeline_locked);
+       }
+
+       mutex_unlock(&timeline_list_mutex);
+}
+
+enum PVRSRV_ERROR pvr_sync_init(void)
+{
+       enum PVRSRV_ERROR error;
+       int err;
+
+       DPF("%s", __func__);
+
+       atomic_set(&pvr_sync_data.sync_id, 0);
+
+       error = PVRSRVAcquireDeviceDataKM(0, PVRSRV_DEVICE_TYPE_RGX,
+                                         &pvr_sync_data.device_cookie);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to initialise services (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               goto err_out;
+       }
+
+       error = AcquireGlobalEventObjectServer(
+               &pvr_sync_data.event_object_handle);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to acquire global event object (%s)",
+                       __func__, PVRSRVGetErrorStringKM(error));
+               goto err_release_device_data;
+       }
+
+       OSAcquireBridgeLock();
+
+       error = SyncPrimContextCreate(0,
+                                     pvr_sync_data.device_cookie,
+                                     &pvr_sync_data.sync_prim_context);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to create sync prim context (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               OSReleaseBridgeLock();
+               goto err_release_event_object;
+       }
+
+       OSReleaseBridgeLock();
+
+       pvr_sync_data.defer_free_wq =
+               create_freezable_workqueue("pvr_sync_defer_free_workqueue");
+       if (!pvr_sync_data.defer_free_wq) {
+               pr_err("pvr_sync: %s: Failed to create pvr_sync defer_free workqueue",
+                      __func__);
+               goto err_free_sync_context;
+       }
+
+       INIT_WORK(&pvr_sync_data.defer_free_work,
+               pvr_sync_defer_free_work_queue_function);
+
+       pvr_sync_data.check_status_wq =
+               create_freezable_workqueue("pvr_sync_check_status_workqueue");
+       if (!pvr_sync_data.check_status_wq) {
+               pr_err("pvr_sync: %s: Failed to create pvr_sync check_status workqueue",
+                      __func__);
+               goto err_destroy_defer_free_wq;
+       }
+
+       INIT_WORK(&pvr_sync_data.check_status_work,
+               pvr_sync_check_status_work_queue_function);
+       error = PVRSRVRegisterCmdCompleteNotify(
+                       &pvr_sync_data.command_complete_handle,
+                       &pvr_sync_update_all_timelines,
+                       &pvr_sync_data.device_cookie);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to register MISR notification (%s)",
+                      __func__, PVRSRVGetErrorStringKM(error));
+               goto err_destroy_status_wq;
+       }
+
+       error = PVRSRVRegisterDbgRequestNotify(
+                       &pvr_sync_data.debug_notify_handle,
+                       pvr_sync_debug_request,
+                       DEBUG_REQUEST_ANDROIDSYNC,
+                       NULL);
+       if (error != PVRSRV_OK) {
+               pr_err("pvr_sync: %s: Failed to register debug notifier (%s)",
+                       __func__, PVRSRVGetErrorStringKM(error));
+               goto err_unregister_cmd_complete;
+       }
+
+       err = misc_register(&pvr_sync_device);
+       if (err) {
+               pr_err("pvr_sync: %s: Failed to register pvr_sync device (%d)",
+                      __func__, err);
+               error = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+               goto err_unregister_dbg;
+       }
+
+       error = PVRSRV_OK;
+       return error;
+
+err_unregister_dbg:
+       PVRSRVUnregisterDbgRequestNotify(pvr_sync_data.debug_notify_handle);
+err_unregister_cmd_complete:
+       PVRSRVUnregisterCmdCompleteNotify(
+               pvr_sync_data.command_complete_handle);
+err_destroy_status_wq:
+       destroy_workqueue(pvr_sync_data.check_status_wq);
+err_destroy_defer_free_wq:
+       destroy_workqueue(pvr_sync_data.defer_free_wq);
+err_free_sync_context:
+       OSAcquireBridgeLock();
+       SyncPrimContextDestroy(pvr_sync_data.sync_prim_context);
+       OSReleaseBridgeLock();
+err_release_event_object:
+       ReleaseGlobalEventObjectServer(pvr_sync_data.event_object_handle);
+err_release_device_data:
+       PVRSRVReleaseDeviceDataKM(pvr_sync_data.device_cookie);
+err_out:
+
+       return error;
+}
+
+void pvr_sync_deinit(void)
+{
+       DPF("%s", __func__);
+
+       misc_deregister(&pvr_sync_device);
+
+       PVRSRVUnregisterDbgRequestNotify(pvr_sync_data.debug_notify_handle);
+
+       PVRSRVUnregisterCmdCompleteNotify(
+               pvr_sync_data.command_complete_handle);
+
+       /* This will drain the workqueue, so we guarantee that all deferred
+        * syncs are free'd before returning */
+       destroy_workqueue(pvr_sync_data.defer_free_wq);
+       destroy_workqueue(pvr_sync_data.check_status_wq);
+
+       OSAcquireBridgeLock();
+
+       sync_pool_clear();
+
+       SyncPrimContextDestroy(pvr_sync_data.sync_prim_context);
+
+       OSReleaseBridgeLock();
+
+       ReleaseGlobalEventObjectServer(pvr_sync_data.event_object_handle);
+
+       PVRSRVReleaseDeviceDataKM(pvr_sync_data.device_cookie);
+}
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/pvr_sync.h
new file mode 100644 (file)
index 0000000..e921b13
--- /dev/null
@@ -0,0 +1,86 @@
+/*************************************************************************/ /*!
+@File           pvr_sync.h
+@Title          Kernel driver for Android's sync mechanism
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+#ifndef _PVR_SYNC_H
+#define _PVR_SYNC_H
+
+#include "pvr_fd_sync_kernel.h"
+#include "rgx_fwif_shared.h"
+
+/* Services internal interface */
+enum PVRSRV_ERROR pvr_sync_init(void);
+void pvr_sync_deinit(void);
+
+struct pvr_sync_append_data;
+
+enum PVRSRV_ERROR
+pvr_sync_append_fences(
+       const char                      *name,
+       const u32                       nr_check_fences,
+       const s32                       *check_fence_fds,
+       const s32                       update_fence_fd,
+       const u32                       nr_updates,
+       const PRGXFWIF_UFO_ADDR         *update_ufo_addresses,
+       const u32                       *update_values,
+       const u32                       nr_checks,
+       const PRGXFWIF_UFO_ADDR         *check_ufo_addresses,
+       const u32                       *check_values,
+       struct pvr_sync_append_data     **append_sync_data);
+
+void pvr_sync_get_updates(const struct pvr_sync_append_data *sync_data,
+       u32 *nr_fences,
+       PRGXFWIF_UFO_ADDR **ufo_addrs,
+       u32 **values);
+void pvr_sync_get_checks(const struct pvr_sync_append_data *sync_data,
+       u32 *nr_fences,
+       PRGXFWIF_UFO_ADDR **ufo_addrs,
+       u32 **values);
+
+void pvr_sync_rollback_append_fences(
+       struct pvr_sync_append_data     *sync_check_data);
+void pvr_sync_nohw_complete_fences(
+       struct pvr_sync_append_data     *sync_check_data);
+void pvr_sync_free_append_fences_data(
+       struct pvr_sync_append_data     *sync_check_data);
+
+#endif /* _PVR_SYNC_H */
diff --git a/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/services_kernel_client.h b/drivers/gpu/rogue_m/kernel/drivers/staging/imgtec/services_kernel_client.h
new file mode 100644 (file)
index 0000000..74211b5
--- /dev/null
@@ -0,0 +1,152 @@
+/*************************************************************************/ /*!
+@File           services_kernel_client.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* vi: set ts=8: */
+
+/* This file contains a partial redefinition of the PowerVR Services 5
+ * interface for use by components which are checkpatch clean. This
+ * header is included by the unrefined, non-checkpatch clean headers
+ * to ensure that prototype/typedef/macro changes break the build.
+ */
+
+#ifndef __SERVICES_KERNEL_CLIENT__
+#define __SERVICES_KERNEL_CLIENT__
+
+#include "debug_request_ids.h"
+#include "pvrsrv_error.h"
+
+#include <linux/types.h>
+
+#ifndef __pvrsrv_defined_struct_enum__
+
+/* pvrsrv_device_types.h */
+
+enum PVRSRV_DEVICE_TYPE {
+       PVRSRV_DEVICE_TYPE_RGX = 10,
+};
+
+/* sync_external.h */
+
+struct PVRSRV_CLIENT_SYNC_PRIM {
+       volatile __u32 *pui32LinAddr;
+};
+
+struct PVRSRV_CLIENT_SYNC_PRIM_OP {
+       __u32 ui32Flags;
+       struct pvrsrv_sync_prim *psSync;
+       __u32 ui32FenceValue;
+       __u32 ui32UpdateValue;
+};
+
+#else /* __pvrsrv_defined_struct_enum__ */
+
+enum PVRSRV_DEVICE_TYPE;
+struct PVRSRV_CLIENT_SYNC_PRIM;
+struct PVRSRV_CLIENT_SYNC_PRIM_OP;
+
+#endif /* __pvrsrv_defined_struct_enum__ */
+
+struct SYNC_PRIM_CONTEXT;
+
+/* pvrsrv.h */
+
+#define DEBUG_REQUEST_VERBOSITY_LOW    0
+#define DEBUG_REQUEST_VERBOSITY_MEDIUM 1
+#define DEBUG_REQUEST_VERBOSITY_HIGH   2
+#define DEBUG_REQUEST_VERBOSITY_MAX    (DEBUG_REQUEST_VERBOSITY_HIGH)
+
+typedef void (DUMPDEBUG_PRINTF_FUNC)(const char *fmt, ...) __printf(1, 2);
+
+extern DUMPDEBUG_PRINTF_FUNC *g_pfnDumpDebugPrintf;
+
+typedef void (*PFN_CMDCOMP_NOTIFY)(void *hCmdCompHandle);
+enum PVRSRV_ERROR PVRSRVRegisterCmdCompleteNotify(void **phNotify,
+       PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, void *hPrivData);
+enum PVRSRV_ERROR PVRSRVUnregisterCmdCompleteNotify(void *hNotify);
+
+typedef void (*PFN_DBGREQ_NOTIFY) (void *hDebugRequestHandle,
+       __u32 ui32VerbLevel);
+enum PVRSRV_ERROR PVRSRVRegisterDbgRequestNotify(void **phNotify,
+       PFN_DBGREQ_NOTIFY pfnDbgRequestNotify,
+       __u32 ui32RequesterID, void *hDbgReqeustHandle);
+enum PVRSRV_ERROR PVRSRVUnregisterDbgRequestNotify(void *hNotify);
+
+enum PVRSRV_ERROR PVRSRVAcquireDeviceDataKM(__u32 ui32DevIndex,
+       enum PVRSRV_DEVICE_TYPE eDeviceType, void **phDevCookie);
+enum PVRSRV_ERROR PVRSRVReleaseDeviceDataKM(void *hDevCookie);
+void PVRSRVCheckStatus(void *hCmdCompCallerHandle);
+enum PVRSRV_ERROR AcquireGlobalEventObjectServer(void **phGlobalEventObject);
+enum PVRSRV_ERROR ReleaseGlobalEventObjectServer(void *hGlobalEventObject);
+
+/* sync.h */
+
+enum PVRSRV_ERROR SyncPrimContextCreate(void *hBridge, void *hDeviceNode,
+       struct SYNC_PRIM_CONTEXT **phSyncPrimContext);
+void SyncPrimContextDestroy(struct SYNC_PRIM_CONTEXT *hSyncPrimContext);
+
+enum PVRSRV_ERROR SyncPrimAlloc(struct SYNC_PRIM_CONTEXT *hSyncPrimContext,
+       struct PVRSRV_CLIENT_SYNC_PRIM **ppsSync, const char * pszClassName);
+void SyncPrimFree(struct PVRSRV_CLIENT_SYNC_PRIM *psSync);
+__u32 SyncPrimGetFirmwareAddr(struct PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+/* pdump_km.h */
+
+#ifdef PDUMP
+enum PVRSRV_ERROR __printf(1, 2) PDumpComment(char *fmt, ...);
+#else
+static inline enum PVRSRV_ERROR __printf(1, 2) PDumpComment(char *fmt, ...)
+{
+       return PVRSRV_OK;
+}
+#endif
+
+/* osfunc.h */
+
+void OSAcquireBridgeLock(void);
+void OSReleaseBridgeLock(void);
+enum PVRSRV_ERROR OSEventObjectWait(void *hOSEventKM);
+enum PVRSRV_ERROR OSEventObjectOpen(void *hEventObject, void **phOSEventKM);
+enum PVRSRV_ERROR OSEventObjectClose(void *hOSEventKM);
+
+/* srvkm.h */
+
+const char *PVRSRVGetErrorStringKM(enum PVRSRV_ERROR eError);
+
+#endif /* __SERVICES_KERNEL_CLIENT__ */
diff --git a/drivers/gpu/rogue_m/services/include/cache_defines.h b/drivers/gpu/rogue_m/services/include/cache_defines.h
new file mode 100644 (file)
index 0000000..7779e51
--- /dev/null
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _CACHE_DEFINES_H_
+
+#define CACHEFLUSH_GENERIC     1
+#define CACHEFLUSH_X86         2
+
+#if CACHEFLUSH_TYPE == 0
+#error Unknown cache flush type, please addd to cache_defines.h
+#endif
+
+#endif /* _CACHE_DEFINES_H_ */
+
diff --git a/drivers/gpu/rogue_m/services/include/env/linux/ion_sys.h b/drivers/gpu/rogue_m/services/include/env/linux/ion_sys.h
new file mode 100644 (file)
index 0000000..1e5a60d
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************/ /*!
+@File           ion_sys.c
+@Title          System level interface for Ion
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This file defined the API between services and system layer
+                required for Ion integration.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _ION_SYS_H_
+#define _ION_SYS_H_
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include PVR_ANDROID_ION_HEADER
+
+
+PVRSRV_ERROR IonInit(void *phPrivateData);
+
+struct ion_device *IonDevAcquire(IMG_VOID);
+
+IMG_VOID IonDevRelease(struct ion_device *psIonDev);
+
+IMG_UINT32 IonPhysHeapID(IMG_VOID);
+
+#if defined(LMA)
+IMG_DEV_PHYADDR IonCPUPhysToDevPhys(IMG_CPU_PHYADDR sCPUPhysAddr,
+                                                                       IMG_UINT32 ui32Offset);
+#else
+/* This is a no-op for UMA systems. */
+static inline
+IMG_DEV_PHYADDR IonCPUPhysToDevPhys(IMG_CPU_PHYADDR sCPUPhysAddr,
+                                                                       IMG_UINT32 ui32Offset)
+{
+       return (IMG_DEV_PHYADDR){ .uiAddr = sCPUPhysAddr.uiAddr + ui32Offset };
+}
+#endif
+
+IMG_VOID IonDeinit(IMG_VOID);
+
+#endif /* _ION_SYS_H_ */
diff --git a/drivers/gpu/rogue_m/services/include/env/linux/pvr_bridge_io.h b/drivers/gpu/rogue_m/services/include/env/linux/pvr_bridge_io.h
new file mode 100644 (file)
index 0000000..9ee0993
--- /dev/null
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Bridge IO Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the PVR Bridge code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_BRIDGE_IO_H__
+#define __PVR_BRIDGE_IO_H__
+
+#include <linux/ioctl.h>
+
+#define PVRSRV_IOC_GID      'g'
+#define PVRSRV_IOWR(INDEX)  _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
+#define PVRSRV_GET_BRIDGE_ID(X)        _IOC_NR(X)
+
+#endif /* __PVR_BRIDGE_IO_H__ */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/include/mm_common.h b/drivers/gpu/rogue_m/services/include/mm_common.h
new file mode 100644 (file)
index 0000000..8478434
--- /dev/null
@@ -0,0 +1,50 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common memory management definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Common memory management definitions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef MM_COMMON_H
+#define MM_COMMON_H
+
+#define DEVICEMEM_HISTORY_TEXT_BUFSZ 40
+
+#endif
+
diff --git a/drivers/gpu/rogue_m/services/include/pdump.h b/drivers/gpu/rogue_m/services/include/pdump.h
new file mode 100644 (file)
index 0000000..9467c5d
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _SERVICES_PDUMP_H_
+#define _SERVICES_PDUMP_H_
+
+#include "img_types.h"
+
+typedef IMG_UINT32 PDUMP_FLAGS_T;
+
+
+#define PDUMP_FLAGS_DEINIT                 0x20000000UL /*<! Output this entry to the de-initialisation section */
+
+#define PDUMP_FLAGS_POWER              0x08000000UL /*<! Output this entry even when a power transition is ongoing */
+
+#define PDUMP_FLAGS_CONTINUOUS         0x40000000UL /*<! Output this entry always regardless of framed capture range,
+                                                      used by client applications being dumped. */
+#define PDUMP_FLAGS_PERSISTENT         0x80000000UL /*<! Output this entry always regardless of app and range,
+                                                      used by persistent processes e.g. compositor, window mgr etc/ */
+
+#define PDUMP_FLAGS_DEBUG                      0x00010000U  /*<! For internal debugging use */
+
+#define PDUMP_FLAGS_NOHW                       0x00000001U  /* For internal use: Skip sending instructions to the hardware */ 
+
+#define PDUMP_FILEOFFSET_FMTSPEC "0x%08X"
+typedef IMG_UINT32 PDUMP_FILEOFFSET_T;
+
+#define PDUMP_PARAM_CHANNEL_NAME  "ParamChannel2"
+#define PDUMP_SCRIPT_CHANNEL_NAME "ScriptChannel2"
+
+#define PDUMP_CHANNEL_PARAM            0
+#define PDUMP_CHANNEL_SCRIPT   1
+#define PDUMP_NUM_CHANNELS      2
+
+#define PDUMP_PARAM_0_FILE_NAME "%%0%%.prm"
+#define PDUMP_PARAM_N_FILE_NAME "%%0%%_%02u.prm"
+
+
+#endif /* _SERVICES_PDUMP_H_ */
diff --git a/drivers/gpu/rogue_m/services/include/physheap.h b/drivers/gpu/rogue_m/services/include/physheap.h
new file mode 100644 (file)
index 0000000..f600a5b
--- /dev/null
@@ -0,0 +1,124 @@
+/*************************************************************************/ /*!
+@File
+@Title          Physcial heap management header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines the interface for the physical heap management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#ifndef _PHYSHEAP_H_
+#define _PHYSHEAP_H_
+
+typedef struct _PHYS_HEAP_ PHYS_HEAP;
+
+typedef IMG_VOID (*CpuPAddrToDevPAddr)(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr);
+
+typedef IMG_VOID (*DevPAddrToCpuPAddr)(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr);
+
+typedef struct _PHYS_HEAP_FUNCTIONS_
+{
+       /*! Translate CPU physical address to device physical address */
+       CpuPAddrToDevPAddr      pfnCpuPAddrToDevPAddr;
+       /*! Translate device physical address to CPU physical address */
+       DevPAddrToCpuPAddr      pfnDevPAddrToCpuPAddr;
+} PHYS_HEAP_FUNCTIONS;
+
+typedef enum _PHYS_HEAP_TYPE_
+{
+       PHYS_HEAP_TYPE_UNKNOWN = 0,
+       PHYS_HEAP_TYPE_UMA,
+       PHYS_HEAP_TYPE_LMA,
+} PHYS_HEAP_TYPE;
+
+typedef struct _PHYS_HEAP_CONFIG_
+{
+       IMG_UINT32                              ui32PhysHeapID;
+       PHYS_HEAP_TYPE                  eType;
+       /*
+               Note:
+               sStartAddr and uiSize are only required for LMA heaps
+       */
+       IMG_CPU_PHYADDR                 sStartAddr;
+       IMG_UINT64                              uiSize;
+       IMG_CHAR                                *pszPDumpMemspaceName;
+       PHYS_HEAP_FUNCTIONS             *psMemFuncs;
+       IMG_HANDLE                              hPrivData;
+} PHYS_HEAP_CONFIG;
+
+PVRSRV_ERROR PhysHeapRegister(PHYS_HEAP_CONFIG *psConfig,
+                                                         PHYS_HEAP **ppsPhysHeap);
+
+IMG_VOID PhysHeapUnregister(PHYS_HEAP *psPhysHeap);
+
+PVRSRV_ERROR PhysHeapAcquire(IMG_UINT32 ui32PhysHeapID,
+                                                        PHYS_HEAP **ppsPhysHeap);
+
+IMG_VOID PhysHeapRelease(PHYS_HEAP *psPhysHeap);
+
+PHYS_HEAP_TYPE PhysHeapGetType(PHYS_HEAP *psPhysHeap);
+
+PVRSRV_ERROR PhysHeapGetAddress(PHYS_HEAP *psPhysHeap,
+                                                               IMG_CPU_PHYADDR *psCpuPAddr);
+
+PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap,
+                                                    IMG_UINT64 *puiSize);
+
+IMG_VOID PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap,
+                                                                       IMG_UINT32 ui32NumOfAddr,
+                                                                       IMG_DEV_PHYADDR *psDevPAddr,
+                                                                       IMG_CPU_PHYADDR *psCpuPAddr);
+IMG_VOID PhysHeapDevPAddrToCpuPAddr(PHYS_HEAP *psPhysHeap,
+                                                                       IMG_UINT32 ui32NumOfAddr,
+                                                                       IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                       IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap);
+
+PVRSRV_ERROR PhysHeapInit(IMG_VOID);
+PVRSRV_ERROR PhysHeapDeinit(IMG_VOID);
+
+#endif /* _PHYSHEAP_H_ */
diff --git a/drivers/gpu/rogue_m/services/include/pvr_bridge.h b/drivers/gpu/rogue_m/services/include/pvr_bridge.h
new file mode 100644 (file)
index 0000000..4b704f3
--- /dev/null
@@ -0,0 +1,305 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Bridge Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the PVR Bridge code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_BRIDGE_H__
+#define __PVR_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "pvrsrv_error.h"
+#include "cache_defines.h"
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+#include "common_dc_bridge.h"
+#endif
+#include "common_mm_bridge.h"
+#if defined(SUPPORT_MMPLAT_BRIDGE)
+#include "common_mmplat_bridge.h"
+#endif
+#include "common_cmm_bridge.h"
+#include "common_pdumpmm_bridge.h"
+#include "common_pdump_bridge.h"
+#if defined(SUPPORT_ION)
+#include "common_dmabuf_bridge.h"
+#endif
+#include "common_pdumpctrl_bridge.h"
+#include "common_srvcore_bridge.h"
+#include "common_sync_bridge.h"
+#if defined(SUPPORT_INSECURE_EXPORT)
+#include "common_syncexport_bridge.h"
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+#include "common_syncsexport_bridge.h"
+#endif
+#if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
+#include "common_cachegeneric_bridge.h"
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+#include "common_smm_bridge.h"
+#endif
+#include "common_pvrtl_bridge.h"
+#if defined(PVR_RI_DEBUG)
+#include "common_ri_bridge.h"
+#endif
+
+#if defined(SUPPORT_VALIDATION)
+#include "common_validation_bridge.h"
+#endif
+
+#if defined(PVR_TESTING_UTILS)
+#include "common_tutils_bridge.h"
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#include "common_devicememhistory_bridge.h"
+#endif
+
+/* 
+ * Bridge Cmd Ids
+ */
+
+
+/* Note: The pattern
+ *   #define PVRSRV_BRIDGE_FEATURE (PVRSRV_BRIDGE_PREVFEATURE + 1)
+ *   #if defined(SUPPORT_FEATURE)
+ *   #define PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST      (PVRSRV_BRIDGE_PREVFEATURE_DISPATCH_LAST + 1)
+ *   #define PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST       (PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST + PVRSRV_BRIDGE_FEATURE_CMD_LAST)
+ *   #else
+ *   #define PVRSRV_BRIDGE_FEATURE_DISPATCH_FIRST      0
+ *   #define PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST       (PVRSRV_BRIDGE_PREVFEATURE_DISPATCH_LAST)
+ *   #endif
+ * is used in the macro definitions below to make PVRSRV_BRIDGE_FEATURE_*
+ * take up no space in the dispatch table if SUPPORT_FEATURE is disabled.
+ *
+ * Note however that a bridge always defines PVRSRV_BRIDGE_FEATURE, even where 
+ * the feature is not enabled (each bridge group retains its own ioctl number).
+ */
+
+/*   0: CORE functions  */
+#define PVRSRV_BRIDGE_SRVCORE                                  0UL
+#define PVRSRV_BRIDGE_SRVCORE_DISPATCH_FIRST   0UL
+#define PVRSRV_BRIDGE_SRVCORE_DISPATCH_LAST            (PVRSRV_BRIDGE_SRVCORE_DISPATCH_FIRST + PVRSRV_BRIDGE_SRVCORE_CMD_LAST)
+
+/*   1: SYNC functions  */
+#define PVRSRV_BRIDGE_SYNC                                     1UL
+#define PVRSRV_BRIDGE_SYNC_DISPATCH_FIRST      (PVRSRV_BRIDGE_SRVCORE_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_SYNC_DISPATCH_LAST       (PVRSRV_BRIDGE_SYNC_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNC_CMD_LAST)
+
+/*   2: SYNCEXPORT functions  */
+#define PVRSRV_BRIDGE_SYNCEXPORT                       2UL
+#if defined(SUPPORT_INSECURE_EXPORT)
+#define PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_FIRST        (PVRSRV_BRIDGE_SYNC_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_LAST (PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNCEXPORT_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_LAST (PVRSRV_BRIDGE_SYNC_DISPATCH_LAST)
+#endif
+
+/*   3: SYNCSEXPORT functions  */
+#define PVRSRV_BRIDGE_SYNCSEXPORT                  3UL
+#if defined(SUPPORT_SECURE_EXPORT)
+#define PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_FIRST (PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_LAST         (PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_FIRST + PVRSRV_BRIDGE_SYNCSEXPORT_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_LAST         (PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_LAST)
+#endif
+
+/*   4: PDUMP CTRL layer functions*/
+#define PVRSRV_BRIDGE_PDUMPCTRL                                4UL
+#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST (PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_LAST  (PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMPCTRL_CMD_LAST)
+
+/*   5: Memory Management functions */
+#define PVRSRV_BRIDGE_MM                               5UL
+#define PVRSRV_BRIDGE_MM_DISPATCH_FIRST                (PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_MM_DISPATCH_LAST         (PVRSRV_BRIDGE_MM_DISPATCH_FIRST + PVRSRV_BRIDGE_MM_CMD_LAST)
+
+/*   6: Non-Linux Memory Management functions */
+#define PVRSRV_BRIDGE_MMPLAT                   6UL
+#if defined(SUPPORT_MMPLAT_BRIDGE)
+#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST    (PVRSRV_BRIDGE_MM_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST     (PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST + PVRSRV_BRIDGE_MMPLAT_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST     (PVRSRV_BRIDGE_MM_DISPATCH_LAST)
+#endif
+
+/*   7: Context Memory Management functions */
+#define PVRSRV_BRIDGE_CMM                                      7UL
+#define PVRSRV_BRIDGE_CMM_DISPATCH_FIRST       (PVRSRV_BRIDGE_MMPLAT_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_CMM_DISPATCH_LAST                (PVRSRV_BRIDGE_CMM_DISPATCH_FIRST + PVRSRV_BRIDGE_CMM_CMD_LAST)
+
+/*   8: PDUMP Memory Management functions */
+#define PVRSRV_BRIDGE_PDUMPMM                          8UL
+#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST (PVRSRV_BRIDGE_CMM_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST     (PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMPMM_CMD_LAST)
+
+/*   9: PDUMP functions */
+#define PVRSRV_BRIDGE_PDUMP                            9UL
+#define PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST (PVRSRV_BRIDGE_PDUMPMM_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST      (PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST + PVRSRV_BRIDGE_PDUMP_CMD_LAST)
+
+/*  10: DMABUF functions */
+#define PVRSRV_BRIDGE_DMABUF                                   10UL
+#if defined(SUPPORT_ION)
+#define PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST (PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST     (PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST + PVRSRV_BRIDGE_DMABUF_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST     (PVRSRV_BRIDGE_PDUMP_DISPATCH_LAST)
+#endif
+
+/*  11: Display Class functions */
+#define PVRSRV_BRIDGE_DC                                               11UL
+#if defined(SUPPORT_DISPLAY_CLASS)
+#define PVRSRV_BRIDGE_DC_DISPATCH_FIRST     (PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_DC_DISPATCH_LAST         (PVRSRV_BRIDGE_DC_DISPATCH_FIRST + PVRSRV_BRIDGE_DC_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_DC_DISPATCH_FIRST     0
+#define PVRSRV_BRIDGE_DC_DISPATCH_LAST         (PVRSRV_BRIDGE_DMABUF_DISPATCH_LAST)
+#endif
+
+/*  12: Generic cache interface functions*/
+#define PVRSRV_BRIDGE_CACHEGENERIC                     12UL
+#if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
+#define PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_FIRST (PVRSRV_BRIDGE_DC_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_LAST  (PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_FIRST + PVRSRV_BRIDGE_CACHEGENERIC_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_LAST  (PVRSRV_BRIDGE_DC_DISPATCH_LAST)
+#endif
+
+/*  13: Secure Memory Management functions*/
+#define PVRSRV_BRIDGE_SMM                                      13UL
+#if defined(SUPPORT_SECURE_EXPORT)
+#define PVRSRV_BRIDGE_SMM_DISPATCH_FIRST   (PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_SMM_DISPATCH_LAST        (PVRSRV_BRIDGE_SMM_DISPATCH_FIRST + PVRSRV_BRIDGE_SMM_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_SMM_DISPATCH_FIRST   0
+#define PVRSRV_BRIDGE_SMM_DISPATCH_LAST        (PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_LAST)
+#endif
+
+/*  14: Transport Layer interface functions */
+#define PVRSRV_BRIDGE_PVRTL                                    14UL
+#define PVRSRV_BRIDGE_PVRTL_DISPATCH_FIRST  (PVRSRV_BRIDGE_SMM_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST      (PVRSRV_BRIDGE_PVRTL_DISPATCH_FIRST + PVRSRV_BRIDGE_PVRTL_CMD_LAST)
+
+/*  15: Resource Information (RI) interface functions */
+#define PVRSRV_BRIDGE_RI                                               15UL
+#if defined(PVR_RI_DEBUG)
+#define PVRSRV_BRIDGE_RI_DISPATCH_FIRST     (PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_RI_DISPATCH_LAST         (PVRSRV_BRIDGE_RI_DISPATCH_FIRST + PVRSRV_BRIDGE_RI_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_RI_DISPATCH_FIRST     0
+#define PVRSRV_BRIDGE_RI_DISPATCH_LAST         (PVRSRV_BRIDGE_PVRTL_DISPATCH_LAST)
+#endif
+
+/*  16: Validation interface functions */
+#define PVRSRV_BRIDGE_VALIDATION                               16UL
+#if defined(SUPPORT_VALIDATION)
+#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST (PVRSRV_BRIDGE_RI_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST  (PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST + PVRSRV_BRIDGE_VALIDATION_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST 0 
+#define PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST  (PVRSRV_BRIDGE_RI_DISPATCH_LAST)
+#endif
+
+/*  17: TUTILS interface functions */
+#define PVRSRV_BRIDGE_TUTILS                                   17UL
+#if defined(PVR_TESTING_UTILS)
+#define PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST (PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST  (PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST + PVRSRV_BRIDGE_TUTILS_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST  (PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST)
+#endif
+
+/*  18: DevMem history interface functions */
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY         18UL
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST (PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST  (PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST + PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST 0
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST  (PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST)
+#endif
+
+/* NB PVRSRV_BRIDGE_LAST below must be the last bridge group defined above (PVRSRV_BRIDGE_FEATURE) */
+#define PVRSRV_BRIDGE_LAST                             (PVRSRV_BRIDGE_DEVICEMEMHISTORY)
+/* NB PVRSRV_BRIDGE_DISPATCH LAST below must be the last dispatch entry defined above (PVRSRV_BRIDGE_FEATURE_DISPATCH_LAST) */
+#define PVRSRV_BRIDGE_DISPATCH_LAST                    (PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST)
+
+
+/******************************************************************************
+ * Generic bridge structures 
+ *****************************************************************************/
+
+
+/******************************************************************************
+ *     bridge packaging structure
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
+{
+       IMG_UINT32                              ui32BridgeID;                   /*!< ioctl bridge group */
+       IMG_UINT32                              ui32FunctionID;         /*!< ioctl function index */
+       IMG_UINT32                              ui32Size;                               /*!< size of structure */
+       IMG_VOID                                *pvParamIn;                             /*!< input data buffer */ 
+       IMG_UINT32                              ui32InBufferSize;               /*!< size of input data buffer */
+       IMG_VOID                                *pvParamOut;                    /*!< output data buffer */
+       IMG_UINT32                              ui32OutBufferSize;              /*!< size of output data buffer */
+}PVRSRV_BRIDGE_PACKAGE;
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_BRIDGE_H__ */
+
+/******************************************************************************
+ End of file (pvr_bridge.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/include/pvr_bridge_client.h b/drivers/gpu/rogue_m/services/include/pvr_bridge_client.h
new file mode 100644 (file)
index 0000000..072b01d
--- /dev/null
@@ -0,0 +1,81 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Bridge Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the PVR Bridge code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_BRIDGE_U_H__
+#define __PVR_BRIDGE_U_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+
+/******************************************************************************
+ * Function prototypes 
+ *****************************************************************************/
+#if(__SIZEOF_POINTER__ == 4)
+IMG_EXPORT IMG_BOOL PVRSRVIsKernel64Bit(void);
+#endif
+
+PVRSRV_ERROR OpenServices(IMG_HANDLE *phServices, IMG_UINT32 ui32SrvFlags);
+PVRSRV_ERROR CloseServices(IMG_HANDLE hServices);
+PVRSRV_ERROR PVRSRVBridgeCall(IMG_HANDLE hServices,
+                                                         IMG_UINT8     ui8BridgeGroup,
+                                                         IMG_UINT32 ui32FunctionID,
+                                                         IMG_VOID *pvParamIn,
+                                                         IMG_UINT32 ui32InBufferSize,
+                                                         IMG_VOID *pvParamOut,
+                                                         IMG_UINT32 ui32OutBufferSize);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __PVR_BRIDGE_U_H__ */
+
+/******************************************************************************
+ End of file (pvr_bridge_u.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/include/pvr_tl.h b/drivers/gpu/rogue_m/services/include/pvr_tl.h
new file mode 100644 (file)
index 0000000..8e9e7d8
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services Transport Layer UM Client API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    User mode Transport layer API for clients.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __PVR_TL_H__
+#define __PVR_TL_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "services.h"
+
+#include "pvr_tlcommon.h"
+
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLConnect
+ @Description  Initialise connection to Services kernel server transport layer
+ @Output               ppsConnection   Address of a pointer to a connection object
+ @Return        PVRSRV_ERROR:  for system error codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLConnect(PVRSRV_CONNECTION **ppsConnection);
+
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLDisconnect
+ @Description  Disconnect from the Services kernel server transport layer
+ @Input                        psConnection    Pointer to connection object as returned from
+                                                               PVRSRVTLConnect()
+ @Return        PVRSRV_ERROR:  for system error codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLDisconnect(PVRSRV_CONNECTION* psConnection);
+
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLOpenStream
+ @Description  Open a descriptor onto an existing PVR transport stream. If
+                               the stream does not exist it returns a NOT_FOUND error unless
+                               the OPEN_WAIT flag is supplied. In this case it will wait for
+                               the stream to be created. If it is not created in the wait
+                               period a TIMEOUT error is returned.
+ @Input                        psConnection    Address of a pointer to a connection object
+ @Input                        pszName                 Address of the stream name string, no longer
+                                                               than PRVSRVTL_MAX_STREAM_NAME_SIZE.
+ @Input                        ui32Mode    Flags defined in pvr_tlcommon.h
+                                                       ACQUIRE_NONBLOCKING: Results in non-blocking reads
+                                                           on stream. Reads are blocking by default
+                            OPEN_WAIT: Causes open to wait for a brief moment
+                                if the stream does not exist
+ @Output               phSD            Address of a pointer to an stream object
+ @Return               PVRSRV_ERROR_NOT_FOUND:        when named stream not found
+ @Return               PVRSRV_ERROR_ALREADY_OPEN:     stream already open by another
+ @Return               PVRSRV_ERROR_STREAM_ERROR:     internal driver state error
+ @Return        PVRSRV_ERROR_TIMEOUT:          block timed out, stream not found
+ @Return               PVRSRV_ERROR:                          for other system codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLOpenStream(PVRSRV_CONNECTION* psConnection,
+               IMG_PCHAR    pszName,
+               IMG_UINT32   ui32Mode,
+               PVRSRVTL_SD* phSD);
+
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLCloseStream
+ @Description  Close and release the stream connection to Services kernel
+                               server transport layer. Any outstanding Acquire will be
+                               released.
+ @Input                        psConnection    Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to close
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND: when SD handle is not known
+ @Return               PVRSRV_ERROR_STREAM_ERROR:        internal driver state error
+ @Return               PVRSRV_ERROR:                             for system codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLCloseStream(PVRSRV_CONNECTION* psConnection,
+               PVRSRVTL_SD hSD);
+
+
+
+/****************************************************************************
+ * Stream Buffer Data retrieval API(s)
+ * 
+ * The client must ensure their use of this acquire/release API for a single 
+ * connection/stream must not be shared with multiple execution contexts e.g.
+ * between a kernel thread and an ISR handler. It is the client’s
+ * responsibility to ensure this API is not interrupted by a high priority
+ * thread/ISR
+ ****************************************************************************/
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLAcquireData
+ @Description  When there is data available in the stream buffer this call
+                               returns with the address and length of the data buffer the
+                               client can safely read. This buffer may contain one or more
+                               packets of data.
+                               If no data is available then this call blocks until it becomes
+                               available. However if the stream has been destroyed while
+                               waiting then a resource unavailable error will be returned
+                               to the caller. Clients must pair this call with a
+                               ReleaseData call.
+ @Input                        psConnection    Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to read
+ @Output               ppPacketBuf             Address of a pointer to an byte buffer. On exit
+                                                               pointer contains address of buffer to read from
+ @Output               puiBufLen               Pointer to an integer. On exit it is the size
+                                                               of the data to read from the packet buffer
+ @Return               PVRSRV_ERROR_RESOURCE_UNAVAILABLE: when stream no longer exists
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND:     when SD handle not known
+ @Return               PVRSRV_ERROR_STREAM_ERROR:             internal driver state error
+ @Return               PVRSRV_ERROR_RETRY:                                release not called beforehand
+ @Return        PVRSRV_ERROR_TIMEOUT:              block timed out, no data
+ @Return               PVRSRV_ERROR:                                      for other system codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLAcquireData(PVRSRV_CONNECTION* psConnection,
+               PVRSRVTL_SD hSD,
+               IMG_PBYTE*  ppPacketBuf,
+               IMG_UINT32* puiBufLen);
+
+
+/**************************************************************************/ /*!
+ @Function             PVRSRVTLReleaseData
+ @Description  Called after client has read the stream data out of the buffer
+                               The data is subsequently flushed from the stream buffer to make
+                               room for more data packets from the stream source.
+ @Input                        psConnection    Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to read
+ @Return               PVRSRV_ERROR_RESOURCE_UNAVAILABLE: when stream no longer exists
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND:   when SD handle not known to TL
+ @Return               PVRSRV_ERROR_STREAM_ERROR:           internal driver state error
+ @Return               PVRSRV_ERROR_RETRY:                              acquire not called beforehand
+ @Return               PVRSRV_ERROR:                    for system codes
+*/ /***************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVTLReleaseData(PVRSRV_CONNECTION* psConnection,
+               PVRSRVTL_SD hSD);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_TL_H__ */
+
+/******************************************************************************
+ End of file (pvr_tl.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/include/pvr_tlcommon.h b/drivers/gpu/rogue_m/services/include/pvr_tlcommon.h
new file mode 100644 (file)
index 0000000..63c31b2
--- /dev/null
@@ -0,0 +1,193 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services Transport Layer common types and definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport layer common types and definitions included into
+                both user mode and kernel mode source.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __PVR_TLCOMMON_H__
+#define __PVR_TLCOMMON_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+
+
+/*! Handle type for stream descriptor objects as created by this API */
+typedef IMG_HANDLE PVRSRVTL_SD;
+
+
+/*! Maximum stream name length including the null byte */
+#define PRVSRVTL_MAX_STREAM_NAME_SIZE  20U
+
+/*! Packet lengths are always rounded up to a multiple of 4 bytes */
+#define PVRSRVTL_PACKET_ALIGNMENT              4U
+#define PVRSRVTL_ALIGN(x)                              ((x+PVRSRVTL_PACKET_ALIGNMENT-1) & ~(PVRSRVTL_PACKET_ALIGNMENT-1))
+
+
+/*! A packet is made up of a header structure followed by the data bytes.
+ * There are 3 types of packet: normal (has data), data lost and padding,
+ * see packet flags. Header kept small to reduce data overhead.
+ *
+ * if the ORDER of the structure members is changed, please UPDATE the 
+ *   PVRSRVTL_PACKET_FLAG_OFFSET macro.
+ */
+typedef struct _PVRSRVTL_PACKETHDR_
+{
+       IMG_UINT16 uiDataLen;   /*!< Number of bytes following header */
+       IMG_UINT16 uiFlags;             /*!< Packet flag word */
+
+       /* First bytes of data ... */
+       //IMG_UINT32 ui32Data;  // ... variable length data array
+
+} PVRSRVTL_PACKETHDR, *PVRSRVTL_PPACKETHDR;
+
+/* Structure must always be a size multiple of 4 as stream buffer
+ * still an array of IMG_UINT32s.
+ */
+BLD_ASSERT((sizeof(PVRSRVTL_PACKETHDR)&3)==0, pvr_tlcommon_h)
+
+/*! Packet header mask used to extract the type from the uiFlags member.
+ * Do not use directly, \see TEST_PACKET_FLAG
+ */
+#define PVRSRVTL_PACKETHDR_TYPE_MASK                   0x000f
+
+/*! Packet header mask used to extract the flags from the uiFlags member.
+ * Do not use directly, \see GET_PACKET_TYPE
+ */
+#define PVRSRVTL_PACKETHDR_FLAG_MASK                   0xfff0
+
+/*! Packet type enumeration.
+ */
+typedef enum _PVRSRVTL_PACKETTYPE_
+{
+       /*! Undefined packet */
+       PVRSRVTL_PACKETTYPE_UNDEF = 0,
+
+       /*! Normal packet type. Indicates data follows the header.
+        */
+       PVRSRVTL_PACKETTYPE_DATA = 1,
+
+       /*! When seen this packet type indicates that at this moment in the stream
+        * packet(s) were not able to be accepted due to space constraints and that
+        * recent data may be lost - depends on how the producer handles the
+        * error. Such packets have no data, data length is 0.
+        */
+       PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED = 2,
+
+       /*! Packets with this type set are padding packets that contain undefined
+        * data and must be ignored/skipped by the client. They are used when the
+        * circular stream buffer wraps around and there is not enough space for
+        * the data at the end of the buffer. Such packets have a length of 0 or
+        * more.
+        */
+       PVRSRVTL_PACKETTYPE_PADDING = 3,
+
+       /*! This packet type conveys to the stream consumer that the stream producer
+        * has reached the end of data for that data sequence. The TLDaemon
+        * has several options for processing these packets that can be selected
+        * on a per stream basis.
+        */
+       PVRSRVTL_PACKETTYPE_MARKER_EOS = 4,
+
+       PVRSRVTL_PACKETTYPE_LAST = PVRSRVTL_PACKETTYPE_MARKER_EOS
+} PVRSRVTL_PACKETTYPE;
+
+/* The SET_PACKET_* macros rely on the order the PVRSRVTL_PACKETHDR members are declared:
+ * uiFlags is the upper half of a structure consisting of 2 uint16 quantities.
+ */
+#define PVRSRVTL_PACKET_FLAG_OFFSET            (8 * sizeof( ((PVRSRVTL_PACKETHDR *)NULL)->uiDataLen ))
+#define PVRSRVTL_SET_PACKET_DATA(len)          (len) | (PVRSRVTL_PACKETTYPE_DATA                  <<PVRSRVTL_PACKET_FLAG_OFFSET)
+#define PVRSRVTL_SET_PACKET_PADDING(len)       (len) | (PVRSRVTL_PACKETTYPE_PADDING               <<PVRSRVTL_PACKET_FLAG_OFFSET)
+#define PVRSRVTL_SET_PACKET_HDR(len,type)      (len) | ((type)                                                        <<PVRSRVTL_PACKET_FLAG_OFFSET)
+#define PVRSRVTL_SET_PACKET_WRITE_FAILED           (PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED <<PVRSRVTL_PACKET_FLAG_OFFSET)
+
+/*! Returns the number of bytes of data in the packet. p may be any address type
+ * */
+#define GET_PACKET_DATA_LEN(p) \
+       ((IMG_UINT32) ((PVRSRVTL_PPACKETHDR)(p))->uiDataLen )
+
+/*! Returns a IMG_BYTE* pointer to the first byte of data in the packet */
+#define GET_PACKET_DATA_PTR(p) \
+       ((IMG_PBYTE) ( ((IMG_SIZE_T)p) + sizeof(PVRSRVTL_PACKETHDR)) )
+
+/*! Given a PVRSRVTL_PPACKETHDR address, return the address of the next pack
+ *  It is up to the caller to determine if the new address is within the packet
+ *  buffer.
+ */
+#define GET_NEXT_PACKET_ADDR(p) \
+       ((PVRSRVTL_PPACKETHDR) ( ((IMG_UINT8 *)p) + sizeof(PVRSRVTL_PACKETHDR) + \
+       (((((PVRSRVTL_PPACKETHDR)p)->uiDataLen) + \
+       (PVRSRVTL_PACKET_ALIGNMENT-1)) & (~(PVRSRVTL_PACKET_ALIGNMENT-1)) ) ))
+
+/*! Turns the packet address p into a PVRSRVTL_PPACKETHDR pointer type
+ */
+#define GET_PACKET_HDR(p)              ((PVRSRVTL_PPACKETHDR)(p))
+
+/*! Get the type of the packet. p is of type PVRSRVTL_PPACKETHDR
+ */
+#define GET_PACKET_TYPE(p)             (((p)->uiFlags & PVRSRVTL_PACKETHDR_TYPE_MASK))
+
+/*! Tests if a packet flag is set or not. p is of type PVRSRVTL_PPACKETHDR and
+ *  f is one of the flags
+ */
+#define TEST_PACKET_FLAG(p, f) ((p->uiFlags & (f)) ? IMG_TRUE : IMG_FALSE)
+
+
+/*! Flags for use with PVRSRVTLOpenStream
+ * 0x01 - Do not block in PVRSRVTLAcquireData() when no bytes are available
+ * 0x02 - When the stream does not exist wait for a bit (2s) in
+ *        PVRSRVTLOpenStream() and then exit with a timeout error if it still
+ *        does not exist.
+ */
+#define PVRSRV_STREAM_FLAG_NONE                 (1U<<0)
+#define PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING  (1U<<1)
+#define PVRSRV_STREAM_FLAG_OPEN_WAIT            (1U<<2)
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_TLCOMMON_H__ */
+/******************************************************************************
+ End of file (pvr_tlcommon.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_bridge.h b/drivers/gpu/rogue_m/services/include/rgx_bridge.h
new file mode 100644 (file)
index 0000000..d26d4fd
--- /dev/null
@@ -0,0 +1,156 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Bridge Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the rgx Bridge code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGX_BRIDGE_H__)
+#define __RGX_BRIDGE_H__
+
+#include "pvr_bridge.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "common_rgxinit_bridge.h"
+#include "common_rgxta3d_bridge.h"
+#include "common_rgxcmp_bridge.h"
+#include "common_rgxtq_bridge.h"
+#include "common_breakpoint_bridge.h"
+#include "common_debugmisc_bridge.h"
+#include "common_rgxpdump_bridge.h"
+#include "common_rgxhwperf_bridge.h"
+#if defined(RGX_FEATURE_RAY_TRACING)
+#include "common_rgxray_bridge.h"
+#endif
+#include "common_regconfig_bridge.h"
+#include "common_timerquery_bridge.h"
+
+/* 
+ * Bridge Cmd Ids
+ */
+
+/* *REMEMBER* to update PVRSRV_BRIDGE_RGX_LAST if you add/remove a bridge
+ * group! 
+ * Also you need to ensure all PVRSRV_BRIDGE_RGX_xxx_DISPATCH_FIRST
+ * offsets follow on from the previous bridge group's commands!
+ *
+ * If a bridge group is optional, ensure you *ALWAYS* define its index
+ * (e.g. PVRSRV_BRIDGE_RGXCMP is always 151, even is the feature is
+ * not defined). If an optional bridge group is not defined you must
+ * still define PVRSRV_BRIDGE_RGX_xxx_DISPATCH_FIRST for it with an
+ * assigned value of 0.
+ */
+
+/* The RGX bridge groups start at 128 rather than follow-on from the other
+ * non-device bridge groups (meaning that they then won't be displaced if
+ * other non-device bridge groups are added)
+ */
+
+/* 128: RGX TQ interface functions */
+#define PVRSRV_BRIDGE_RGXTQ                      128UL
+#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST       (PVRSRV_BRIDGE_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST        (PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTQ_CMD_LAST)
+
+/* 129: RGX Compute interface functions */
+#define PVRSRV_BRIDGE_RGXCMP                     129UL
+#define PVRSRV_BRIDGE_RGXCMP_DISPATCH_FIRST   (PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST    (PVRSRV_BRIDGE_RGXCMP_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXCMP_CMD_LAST)
+
+/* 130: RGX Initialisation interface functions */
+#define PVRSRV_BRIDGE_RGXINIT                    130UL
+#define PVRSRV_BRIDGE_RGXINIT_DISPATCH_FIRST     (PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST +1)
+#define PVRSRV_BRIDGE_RGXINIT_DISPATCH_LAST      (PVRSRV_BRIDGE_RGXINIT_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXINIT_CMD_LAST)
+
+/* 131: RGX TA/3D interface functions */
+#define PVRSRV_BRIDGE_RGXTA3D                    131UL
+#define PVRSRV_BRIDGE_RGXTA3D_DISPATCH_FIRST     (PVRSRV_BRIDGE_RGXINIT_DISPATCH_LAST +1)
+#define PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST      (PVRSRV_BRIDGE_RGXTA3D_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXTA3D_CMD_LAST)
+
+/* 132: RGX Breakpoint interface functions */
+#define PVRSRV_BRIDGE_BREAKPOINT                 132UL
+#define PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_FIRST  (PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_LAST   (PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_FIRST + PVRSRV_BRIDGE_BREAKPOINT_CMD_LAST)
+
+/* 133: RGX Debug/Misc interface functions */
+#define PVRSRV_BRIDGE_DEBUGMISC                  133UL
+#define PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_FIRST   (PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_LAST    (PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_FIRST + PVRSRV_BRIDGE_DEBUGMISC_CMD_LAST)
+
+/* 134: RGX PDump interface functions */
+#define PVRSRV_BRIDGE_RGXPDUMP                   134UL
+#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST    (PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_LAST +1)
+#define PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST     (PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXPDUMP_CMD_LAST)
+
+/* 135: RGX HWPerf interface functions */
+#define PVRSRV_BRIDGE_RGXHWPERF                  135UL
+#define PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_FIRST   (PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST    (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXHWPERF_CMD_LAST)
+
+/* 136: RGX Ray Tracing interface functions */
+#define PVRSRV_BRIDGE_RGXRAY                     136UL
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST      (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST       (PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST + PVRSRV_BRIDGE_RGXRAY_CMD_LAST)
+#else
+#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST      0
+#define PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST       (PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST)
+#endif
+
+/* 137: RGX Register Configuration interface functions */
+#define PVRSRV_BRIDGE_REGCONFIG                  137UL
+#define PVRSRV_BRIDGE_REGCONFIG_DISPATCH_FIRST   (PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_REGCONFIG_DISPATCH_LAST    (PVRSRV_BRIDGE_REGCONFIG_DISPATCH_FIRST + PVRSRV_BRIDGE_REGCONFIG_CMD_LAST)
+
+/* 138: RGX Timer Query interface functions */
+#define PVRSRV_BRIDGE_TIMERQUERY                 138UL
+#define PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_FIRST  (PVRSRV_BRIDGE_REGCONFIG_DISPATCH_LAST + 1)
+#define PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_LAST   (PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_FIRST + PVRSRV_BRIDGE_TIMERQUERY_CMD_LAST)
+
+#define PVRSRV_BRIDGE_RGX_LAST                   (PVRSRV_BRIDGE_TIMERQUERY)
+#define PVRSRV_BRIDGE_RGX_DISPATCH_LAST          (PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_LAST)
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __RGX_BRIDGE_H__ */
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_fwif.h b/drivers/gpu/rogue_m/services/include/rgx_fwif.h
new file mode 100644 (file)
index 0000000..3e46d1a
--- /dev/null
@@ -0,0 +1,474 @@
+/*************************************************************************/ /*!
+@File                  rgx_fwif.h
+@Title          RGX firmware interface structures
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX firmware interface structures used by srvinit and server
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_FWIF_H__)
+#define __RGX_FWIF_H__
+
+#include "rgx_meta.h"
+#include "rgx_fwif_shared.h"
+
+#include "pvr_tlcommon.h"
+
+/*************************************************************************/ /*!
+ Logging type
+*/ /**************************************************************************/
+#define RGXFWIF_LOG_TYPE_NONE                  0x00000000
+#define RGXFWIF_LOG_TYPE_TRACE                 0x00000001
+#define RGXFWIF_LOG_TYPE_GROUP_MAIN            0x00000002
+#define RGXFWIF_LOG_TYPE_GROUP_MTS             0x00000004
+#define RGXFWIF_LOG_TYPE_GROUP_CLEANUP 0x00000008
+#define RGXFWIF_LOG_TYPE_GROUP_CSW             0x00000010
+#define RGXFWIF_LOG_TYPE_GROUP_BIF             0x00000020
+#define RGXFWIF_LOG_TYPE_GROUP_PM              0x00000040
+#define RGXFWIF_LOG_TYPE_GROUP_RTD             0x00000080
+#define RGXFWIF_LOG_TYPE_GROUP_SPM             0x00000100
+#define RGXFWIF_LOG_TYPE_GROUP_POW             0x00000200
+#define RGXFWIF_LOG_TYPE_GROUP_HWR             0x00000400
+#define RGXFWIF_LOG_TYPE_GROUP_HWP             0x00000800
+#define RGXFWIF_LOG_TYPE_GROUP_RPM             0x00001000
+#define RGXFWIF_LOG_TYPE_GROUP_DMA             0x00002000
+#define RGXFWIF_LOG_TYPE_GROUP_DEBUG   0x80000000
+#define RGXFWIF_LOG_TYPE_GROUP_MASK            0x80003FFE
+#define RGXFWIF_LOG_TYPE_MASK                  0x80003FFF
+
+/* String used in pvrdebug -h output */
+#define RGXFWIF_LOG_GROUPS_STRING_LIST   "main,mts,cleanup,csw,bif,pm,rtd,spm,pow,hwr,hwp"
+
+/* Table entry to map log group strings to log type value */
+typedef struct {
+       const IMG_CHAR* pszLogGroupName;
+       IMG_UINT32      ui32LogGroupType;
+} RGXFWIF_LOG_GROUP_MAP_ENTRY;
+
+/*
+  Macro for use with the RGXFWIF_LOG_GROUP_MAP_ENTRY type to create a lookup
+  table where needed. Keep log group names short, no more than 20 chars.
+*/
+#define RGXFWIF_LOG_GROUP_NAME_VALUE_MAP { "main",    RGXFWIF_LOG_TYPE_GROUP_MAIN }, \
+                                         { "mts",     RGXFWIF_LOG_TYPE_GROUP_MTS }, \
+                                         { "cleanup", RGXFWIF_LOG_TYPE_GROUP_CLEANUP }, \
+                                         { "csw",     RGXFWIF_LOG_TYPE_GROUP_CSW }, \
+                                         { "bif",     RGXFWIF_LOG_TYPE_GROUP_BIF }, \
+                                         { "pm",      RGXFWIF_LOG_TYPE_GROUP_PM }, \
+                                         { "rtd",     RGXFWIF_LOG_TYPE_GROUP_RTD }, \
+                                         { "spm",     RGXFWIF_LOG_TYPE_GROUP_SPM }, \
+                                         { "pow",     RGXFWIF_LOG_TYPE_GROUP_POW }, \
+                                         { "hwr",     RGXFWIF_LOG_TYPE_GROUP_HWR }, \
+                                         { "hwp",     RGXFWIF_LOG_TYPE_GROUP_HWP }, \
+                                         { "rpm",        RGXFWIF_LOG_TYPE_GROUP_RPM }, \
+                                         { "dma",     RGXFWIF_LOG_TYPE_GROUP_DMA }, \
+                                         { "debug",   RGXFWIF_LOG_TYPE_GROUP_DEBUG }
+
+
+/* Used in print statements to display log group state, one %s per group defined */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC  "%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+
+/* Used in a print statement to display log group state, one per group */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST(types)  (((types) & RGXFWIF_LOG_TYPE_GROUP_MAIN)       ?("main ")              :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_MTS)                ?("mts ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_CLEANUP)    ?("cleanup ")   :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_CSW)                ?("csw ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_BIF)                ?("bif ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_PM)         ?("pm ")                :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_RTD)                ?("rtd ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_SPM)                ?("spm ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_POW)                ?("pow ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_HWR)                ?("hwr ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_HWP)                ?("hwp ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_RPM)                ?("rpm ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_DMA)                ?("dma ")               :("")),         \
+                                                (((types) & RGXFWIF_LOG_TYPE_GROUP_DEBUG)      ?("debug ")             :(""))
+
+
+/*! Logging function */
+typedef IMG_VOID (*PFN_RGXFW_LOG) (const IMG_CHAR* pszFmt, ...);
+
+
+/*!
+ ******************************************************************************
+ * HWPERF
+ *****************************************************************************/
+/* Size of the Firmware L1 HWPERF buffer in bytes (256KB). Accessed by the
+ * Firmware and host driver. */
+#define RGXFW_HWPERF_L1_SIZE_MIN               (0x004000)
+#define RGXFW_HWPERF_L1_SIZE_DEFAULT    (0x040000)
+#define RGXFW_HWPERF_L1_SIZE_MAX        (0xC00000)
+/* This padding value must always be greater than or equal to
+ * RGX_HWPERF_V2_MAX_PACKET_SIZE for all valid BVNCs. This is asserted in
+ * rgxsrvinit.c. This macro is defined with a constant to avoid a KM
+ * dependency */
+#define RGXFW_HWPERF_L1_PADDING_DEFAULT (0x800)
+
+
+/*!
+ ******************************************************************************
+ * Trace Buffer
+ *****************************************************************************/
+
+/*! Number of elements on each line when dumping the trace buffer */
+#define RGXFW_TRACE_BUFFER_LINESIZE    (30)
+
+/*! Total size of RGXFWIF_TRACEBUF dword (needs to be a multiple of RGXFW_TRACE_BUFFER_LINESIZE) */
+#define RGXFW_TRACE_BUFFER_SIZE                (400*RGXFW_TRACE_BUFFER_LINESIZE)
+#define RGXFW_TRACE_BUFFER_ASSERT_SIZE 200
+#define RGXFW_THREAD_NUM 1
+
+#define RGXFW_POLL_TYPE_SET 0x80000000
+
+typedef struct _RGXFWIF_ASSERTBUF_
+{
+       IMG_CHAR        szPath[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+       IMG_CHAR        szInfo[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+       IMG_UINT32      ui32LineNum;
+} UNCACHED_ALIGN RGXFWIF_ASSERTBUF;
+
+typedef struct _RGXFWIF_TRACEBUF_SPACE_
+{
+       IMG_UINT32                      ui32TracePointer;
+       IMG_UINT32                      aui32TraceBuffer[RGXFW_TRACE_BUFFER_SIZE];
+       RGXFWIF_ASSERTBUF       sAssertBuf;
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF_SPACE;
+
+#define RGXFWIF_POW_STATES \
+  X(RGXFWIF_POW_OFF)                   /* idle and handshaked with the host (ready to full power down) */ \
+  X(RGXFWIF_POW_ON)                            /* running HW mds */ \
+  X(RGXFWIF_POW_FORCED_IDLE)   /* forced idle */ \
+  X(RGXFWIF_POW_IDLE)                  /* idle waiting for host handshake */
+
+typedef enum _RGXFWIF_POW_STATE_
+{
+#define X(NAME) NAME,
+       RGXFWIF_POW_STATES
+#undef X
+} RGXFWIF_POW_STATE;
+
+/* Firmware HWR states */
+#define RGXFWIF_HWR_HARDWARE_OK                (0x1 << 0)      /*!< Tells if the HW state is ok or locked up */
+#define RGXFWIF_HWR_FREELIST_OK                (0x1 << 1)      /*!< Tells if the freelists are ok or being reconstructed */
+#define RGXFWIF_HWR_ANALYSIS_DONE      (0x1 << 2)      /*!< Tells if the analysis of a GPU lockup has already been performed */
+#define RGXFWIF_HWR_GENERAL_LOCKUP     (0x1 << 3)      /*!< Tells if a DM unrelated lockup has been detected */
+typedef IMG_UINT32 RGXFWIF_HWR_STATEFLAGS;
+
+/* Firmware per-DM HWR states */
+#define RGXFWIF_DM_STATE_WORKING                                       (0x00)          /*!< DM is working if all flags are cleared */
+#define RGXFWIF_DM_STATE_READY_FOR_HWR                                 (0x1 << 0)      /*!< DM is idle and ready for HWR */
+#define RGXFWIF_DM_STATE_NEEDS_FL_RECONSTRUCTION       (0x1 << 1)      /*!< DM need FL reconstruction before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_SKIP                                    (0x1 << 2)      /*!< DM need to skip to next cmd before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_PR_CLEANUP                      (0x1 << 3)      /*!< DM need partial render cleanup before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_TRACE_CLEAR                     (0x1 << 4)      /*!< DM need to increment Recovery Count once fully recovered */
+#define RGXFWIF_DM_STATE_GUILTY_LOCKUP                         (0x1 << 5)      /*!< DM was identified as locking up and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_LOCKUP                       (0x1 << 6)      /*!< DM was innocently affected by another lockup which caused HWR */
+#define RGXFWIF_DM_STATE_GUILTY_OVERRUNING                     (0x1 << 7)      /*!< DM was identified as over-running and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_OVERRUNING           (0x1 << 8)      /*!< DM was innocently affected by another DM over-running which caused HWR */
+typedef IMG_UINT32 RGXFWIF_HWR_RECOVERYFLAGS;
+
+typedef struct _RGXFWIF_TRACEBUF_
+{
+    IMG_UINT32                         ui32LogType;
+       RGXFWIF_POW_STATE               ePowState;
+       RGXFWIF_TRACEBUF_SPACE  sTraceBuf[RGXFW_THREAD_NUM];
+
+       IMG_UINT16                              aui16HwrDmLockedUpCount[RGXFWIF_DM_MAX];
+       IMG_UINT16                              aui16HwrDmOverranCount[RGXFWIF_DM_MAX];
+       IMG_UINT16                              aui16HwrDmRecoveredCount[RGXFWIF_DM_MAX];
+       IMG_UINT16                              aui16HwrDmFalseDetectCount[RGXFWIF_DM_MAX];
+       IMG_UINT32                              ui32HwrCounter;
+       RGXFWIF_DEV_VIRTADDR    apsHwrDmFWCommonContext[RGXFWIF_DM_MAX];
+
+       IMG_UINT32                              aui32CrPollAddr[RGXFW_THREAD_NUM];
+       IMG_UINT32                              aui32CrPollMask[RGXFW_THREAD_NUM];
+
+       RGXFWIF_HWR_STATEFLAGS          ui32HWRStateFlags;
+       RGXFWIF_HWR_RECOVERYFLAGS       aui32HWRRecoveryFlags[RGXFWIF_HWDM_MAX];
+
+       volatile IMG_UINT32             ui32HWPerfRIdx;
+       volatile IMG_UINT32             ui32HWPerfWIdx;
+       volatile IMG_UINT32             ui32HWPerfWrapCount;
+       IMG_UINT32                              ui32HWPerfSize;      /* Constant after setup, needed in FW */
+       IMG_UINT32                              ui32HWPerfDropCount; /* The number of times the FW drops a packet due to buffer full */
+       
+       /* These next three items are only valid at runtime when the FW is built
+        * with RGX_HWPERF_UTILIZATION defined in rgxfw_hwperf.c */
+       IMG_UINT32                              ui32HWPerfUt;        /* Buffer utilisation, high watermark of bytes in use */
+       IMG_UINT32                              ui32FirstDropOrdinal;/* The ordinal of the first packet the FW dropped */
+       IMG_UINT32              ui32LastDropOrdinal; /* The ordinal of the last packet the FW dropped */
+
+       IMG_UINT32                              ui32InterruptCount;
+       IMG_UINT32                              ui32KCCBCmdsExecuted;
+       IMG_UINT64 RGXFW_ALIGN                  ui64StartIdleTime;
+       IMG_UINT32                              ui32PowMonEnergy;       /* Non-volatile power monitor energy count */
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF;
+
+
+/*!
+ ******************************************************************************
+ * GPU Utilisation
+ *****************************************************************************/
+#define RGXFWIF_GPU_STATS_MAX_VALUE_OF_STATE  10000
+
+#define RGXFWIF_GPU_UTIL_STATE_ACTIVE_LOW     (0U)
+#define RGXFWIF_GPU_UTIL_STATE_IDLE           (1U)
+#define RGXFWIF_GPU_UTIL_STATE_ACTIVE_HIGH    (2U)
+#define RGXFWIF_GPU_UTIL_STATE_BLOCKED        (3U)
+#define RGXFWIF_GPU_UTIL_STATE_NUM            (4U)
+
+#define RGXFWIF_GPU_UTIL_TIME_MASK            IMG_UINT64_C(0xFFFFFFFFFFFFFFFC)
+#define RGXFWIF_GPU_UTIL_STATE_MASK           IMG_UINT64_C(0x0000000000000003)
+
+#define RGXFWIF_GPU_UTIL_GET_TIME(word)       ((word) & RGXFWIF_GPU_UTIL_TIME_MASK)
+#define RGXFWIF_GPU_UTIL_GET_STATE(word)      ((word) & RGXFWIF_GPU_UTIL_STATE_MASK)
+
+/* The OS timestamps computed by the FW are approximations of the real time,
+ * which means they could be slightly behind or ahead the real timer on the Host.
+ * In some cases we can perform subtractions between FW approximated
+ * timestamps and real OS timestamps, so we need a form of protection against
+ * negative results if for instance the FW one is a bit ahead of time.
+ */
+#define RGXFWIF_GPU_UTIL_GET_PERIOD(newtime,oldtime) \
+       ((newtime) > (oldtime) ? ((newtime) - (oldtime)) : 0)
+
+#define RGXFWIF_GPU_UTIL_MAKE_WORD(time,state) \
+       (RGXFWIF_GPU_UTIL_GET_TIME(time) | RGXFWIF_GPU_UTIL_GET_STATE(state))
+
+
+/* The timer correlation array must be big enough to ensure old entries won't be
+ * overwritten before all the HWPerf events linked to those entries are processed
+ * by the MISR. The update frequency of this array depends on how fast the system
+ * can change state (basically how small the APM latency is) and perform DVFS transitions.
+ *
+ * The minimum size is 2 (not 1) to avoid race conditions between the FW reading
+ * an entry while the Host is updating it. With 2 entries in the worst case the FW
+ * will read old data, which is still quite ok if the Host is updating the timer
+ * correlation at that time.
+ */
+#define RGXFWIF_TIME_CORR_ARRAY_SIZE            256
+#define RGXFWIF_TIME_CORR_CURR_INDEX(seqcount)  ((seqcount) % RGXFWIF_TIME_CORR_ARRAY_SIZE)
+
+/* Make sure the timer correlation array size is a power of 2 */
+BLD_ASSERT(((RGXFWIF_TIME_CORR_ARRAY_SIZE & (RGXFWIF_TIME_CORR_ARRAY_SIZE - 1)) == 0), rgx_fwif_h)
+
+typedef struct _RGXFWIF_GPU_UTIL_FWCB_
+{
+       RGXFWIF_TIME_CORR sTimeCorr[RGXFWIF_TIME_CORR_ARRAY_SIZE];
+       IMG_UINT32        ui32TimeCorrSeqCount;
+
+       /* Last GPU state + OS time of the last state update */
+       IMG_UINT64 RGXFW_ALIGN ui64LastWord;
+
+       /* Counters for the amount of time the GPU was active/idle/blocked */
+       IMG_UINT64 RGXFW_ALIGN aui64StatsCounters[RGXFWIF_GPU_UTIL_STATE_NUM];
+} UNCACHED_ALIGN RGXFWIF_GPU_UTIL_FWCB;
+
+
+/*!
+ ******************************************************************************
+ * HWR Data
+ *****************************************************************************/
+typedef enum _RGX_HWRTYPE_
+{
+       RGX_HWRTYPE_UNKNOWNFAILURE  = 0,
+       RGX_HWRTYPE_OVERRUN         = 1,
+       RGX_HWRTYPE_POLLFAILURE     = 2,
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+       RGX_HWRTYPE_BIF0FAULT       = 3,
+       RGX_HWRTYPE_BIF1FAULT       = 4,
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+       RGX_HWRTYPE_TEXASBIF0FAULT      = 5,
+#endif
+#if defined(RGX_FEATURE_RAY_TRACING)
+       RGX_HWRTYPE_DPXMMUFAULT         = 6,
+#endif
+#else
+       RGX_HWRTYPE_MMUFAULT        = 7,
+       RGX_HWRTYPE_MMUMETAFAULT    = 8,
+#endif
+} RGX_HWRTYPE;
+
+#define RGXFWIF_BIFFAULTBIT_GET(ui32BIFMMUStatus) \
+               ((ui32BIFMMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_CLRMSK) >> RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_SHIFT)
+#define RGXFWIF_MMUFAULTBIT_GET(ui32BIFMMUStatus) \
+               ((ui32BIFMMUStatus & ~RGX_CR_MMU_FAULT_STATUS_FAULT_CLRMSK) >> RGX_CR_MMU_FAULT_STATUS_FAULT_SHIFT)
+
+#define RGXFWIF_HWRTYPE_BIF_BANK_GET(eHWRType) ((eHWRType == RGX_HWRTYPE_BIF0FAULT) ? 0 : 1 )
+
+typedef struct _RGX_BIFINFO_
+{
+       IMG_UINT64      RGXFW_ALIGN             ui64BIFReqStatus;
+       IMG_UINT64      RGXFW_ALIGN             ui64BIFMMUStatus;
+       IMG_UINT64      RGXFW_ALIGN             ui64PCAddress; /*!< phys address of the page catalogue */
+} RGX_BIFINFO;
+
+typedef struct _RGX_MMUINFO_
+{
+       IMG_UINT64      RGXFW_ALIGN             ui64MMUStatus;
+} RGX_MMUINFO;
+
+typedef struct _RGX_POLLINFO_
+{
+       IMG_UINT32      ui32ThreadNum;
+       IMG_UINT32      ui32CrPollAddr;
+       IMG_UINT32      ui32CrPollMask;
+} UNCACHED_ALIGN RGX_POLLINFO;
+
+typedef struct _RGX_HWRINFO_
+{
+       union
+       {
+               RGX_BIFINFO             sBIFInfo;
+               RGX_MMUINFO             sMMUInfo;
+               RGX_POLLINFO    sPollInfo;
+       } uHWRData;
+
+       IMG_UINT64      RGXFW_ALIGN             ui64CRTimer;
+       IMG_UINT32                                      ui32FrameNum;
+       IMG_UINT32                                      ui32PID;
+       IMG_UINT32                                      ui32ActiveHWRTData;
+       IMG_UINT32                                      ui32HWRNumber;
+       IMG_UINT32                                      ui32EventStatus;
+       IMG_UINT32                                      ui32HWRRecoveryFlags;
+       RGX_HWRTYPE                             eHWRType;
+       RGXFWIF_TIME_CORR                       sTimeCorr;
+
+       RGXFWIF_DM                                      eDM;
+} UNCACHED_ALIGN RGX_HWRINFO;
+
+#define RGXFWIF_HWINFO_MAX_FIRST 8                                                     /* Number of first HWR logs recorded (never overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX_LAST 8                                                      /* Number of latest HWR logs (older logs are overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX (RGXFWIF_HWINFO_MAX_FIRST + RGXFWIF_HWINFO_MAX_LAST)        /* Total number of HWR logs stored in a buffer */
+#define RGXFWIF_HWINFO_LAST_INDEX (RGXFWIF_HWINFO_MAX - 1)     /* Index of the last log in the HWR log buffer */
+typedef struct _RGXFWIF_HWRINFOBUF_
+{
+       RGX_HWRINFO sHWRInfo[RGXFWIF_HWINFO_MAX];
+
+       IMG_UINT32      ui32FirstCrPollAddr[RGXFW_THREAD_NUM];
+       IMG_UINT32      ui32FirstCrPollMask[RGXFW_THREAD_NUM];
+       IMG_UINT32      ui32WriteIndex;
+       IMG_UINT32      ui32DDReqCount;
+} UNCACHED_ALIGN RGXFWIF_HWRINFOBUF;
+
+
+/*!
+ ******************************************************************************
+ * RGX firmware Init Config Data
+ *****************************************************************************/
+#define RGXFWIF_INICFG_CTXSWITCH_TA_EN         (0x1 << 0)
+#define RGXFWIF_INICFG_CTXSWITCH_3D_EN         (0x1 << 1)
+#define RGXFWIF_INICFG_CTXSWITCH_CDM_EN                (0x1 << 2)
+#define RGXFWIF_INICFG_CTXSWITCH_MODE_RAND     (0x1 << 3)
+#define RGXFWIF_INICFG_CTXSWITCH_SRESET_EN     (0x1 << 4)
+#define RGXFWIF_INICFG_RSVD                                    (0x1 << 5)
+#define RGXFWIF_INICFG_POW_RASCALDUST          (0x1 << 6)
+#define RGXFWIF_INICFG_HWPERF_EN                       (0x1 << 7)
+#define RGXFWIF_INICFG_HWR_EN                          (0x1 << 8)
+#define RGXFWIF_INICFG_CHECK_MLIST_EN          (0x1 << 9)
+#define RGXFWIF_INICFG_DISABLE_CLKGATING_EN (0x1 << 10)
+#define RGXFWIF_INICFG_POLL_COUNTERS_EN                (0x1 << 11)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX                (RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INDEX << 12)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INSTANCE     (RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INSTANCE << 12)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_LIST         (RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_LIST << 12)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_CLRMSK       (0xFFFFCFFFU)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_SHIFT                (12)
+#define RGXFWIF_INICFG_SHG_BYPASS_EN           (0x1 << 14)
+#define RGXFWIF_INICFG_RTU_BYPASS_EN           (0x1 << 15)
+#define RGXFWIF_INICFG_REGCONFIG_EN            (0x1 << 16)
+#define RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY   (0x1 << 17)
+#define RGXFWIF_INICFG_HWP_DISABLE_FILTER      (0x1 << 18)
+#define RGXFWIF_INICFG_CUSTOM_PERF_TIMER_EN    (0x1 << 19)
+#define RGXFWIF_INICFG_CDM_KILL_MODE_RAND_EN   (0x1 << 20)
+#define RGXFWIF_INICFG_DISABLE_DM_OVERLAP      (0x1 << 21)
+#define RGXFWIF_INICFG_ALL                                     (0x003FFFDFU)
+#define RGXFWIF_SRVCFG_DISABLE_PDP_EN          (0x1 << 31)
+#define RGXFWIF_SRVCFG_ALL                                     (0x80000000U)
+#define RGXFWIF_FILTCFG_TRUNCATE_HALF          (0x1 << 3)
+#define RGXFWIF_FILTCFG_TRUNCATE_INT           (0x1 << 2)
+#define RGXFWIF_FILTCFG_NEW_FILTER_MODE                (0x1 << 1)
+
+#define RGXFWIF_INICFG_CTXSWITCH_DM_ALL                (RGXFWIF_INICFG_CTXSWITCH_TA_EN | \
+                                                                                        RGXFWIF_INICFG_CTXSWITCH_3D_EN | \
+                                                                                        RGXFWIF_INICFG_CTXSWITCH_CDM_EN)
+
+#define RGXFWIF_INICFG_CTXSWITCH_CLRMSK                ~(RGXFWIF_INICFG_CTXSWITCH_DM_ALL | \
+                                                                                        RGXFWIF_INICFG_CTXSWITCH_MODE_RAND | \
+                                                                                        RGXFWIF_INICFG_CTXSWITCH_SRESET_EN)
+
+typedef enum
+{
+       RGX_ACTIVEPM_FORCE_OFF = 0,
+       RGX_ACTIVEPM_FORCE_ON = 1,
+       RGX_ACTIVEPM_DEFAULT = 2
+} RGX_ACTIVEPM_CONF;
+
+typedef enum
+{
+       RGX_RD_POWER_ISLAND_FORCE_OFF = 0,
+       RGX_RD_POWER_ISLAND_FORCE_ON = 1,
+       RGX_RD_POWER_ISLAND_DEFAULT = 2
+} RGX_RD_POWER_ISLAND_CONF;
+
+
+/*!
+ ******************************************************************************
+ * Querying DM state
+ *****************************************************************************/
+
+typedef enum _RGXFWIF_DM_STATE_
+{
+       RGXFWIF_DM_STATE_NORMAL                 = 0,
+       RGXFWIF_DM_STATE_LOCKEDUP               = 1,
+
+} RGXFWIF_DM_STATE;
+
+typedef struct
+{
+       IMG_UINT16  ui16RegNum;                         /*!< Register number */
+       IMG_UINT16  ui16IndirectRegNum;         /*!< Indirect register number (or 0 if not used) */
+       IMG_UINT16  ui16IndirectStartVal;       /*!< Start value for indirect register */
+       IMG_UINT16  ui16IndirectEndVal;         /*!< End value for indirect register */
+} RGXFW_REGISTER_LIST;
+
+#endif /*  __RGX_FWIF_H__ */
+
+/******************************************************************************
+ End of file (rgx_fwif.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_fwif_alignchecks_km.h b/drivers/gpu/rogue_m/services/include/rgx_fwif_alignchecks_km.h
new file mode 100644 (file)
index 0000000..158abba
--- /dev/null
@@ -0,0 +1,86 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX fw interface alignment checks
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Checks to avoid disalignment in RGX fw data structures shared with the host
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_FWIF_ALIGNCHECKS_KM_H__)
+#define __RGX_FWIF_ALIGNCHECKS_KM_H__
+
+/* for the offsetof macro */
+#include <stddef.h> 
+
+/*!
+ ******************************************************************************
+ * Alignment checks array
+ *****************************************************************************/
+
+#define RGXFW_ALIGN_CHECKS_INIT_KM                                                     \
+               sizeof(RGXFWIF_INIT),                                                           \
+               offsetof(RGXFWIF_INIT, sFaultPhysAddr),                 \
+               offsetof(RGXFWIF_INIT, sPDSExecBase),                           \
+               offsetof(RGXFWIF_INIT, sUSCExecBase),                           \
+               offsetof(RGXFWIF_INIT, psKernelCCBCtl),                         \
+               offsetof(RGXFWIF_INIT, psKernelCCB),                            \
+               offsetof(RGXFWIF_INIT, psFirmwareCCBCtl),                       \
+               offsetof(RGXFWIF_INIT, psFirmwareCCB),                          \
+               offsetof(RGXFWIF_INIT, eDM),                                            \
+               offsetof(RGXFWIF_INIT, asSigBufCtl),                            \
+               offsetof(RGXFWIF_INIT, psTraceBufCtl),                          \
+               offsetof(RGXFWIF_INIT, sRGXCompChecks),                         \
+                                                                                                                       \
+               /* RGXFWIF_FWRENDERCONTEXT checks */                            \
+               sizeof(RGXFWIF_FWRENDERCONTEXT),                                        \
+               offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext),          \
+               offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext),          \
+                                                                                                                       \
+               sizeof(RGXFWIF_FWCOMMONCONTEXT),                                        \
+               offsetof(RGXFWIF_FWCOMMONCONTEXT, psFWMemContext),      \
+               offsetof(RGXFWIF_FWCOMMONCONTEXT, sRunNode),            \
+               offsetof(RGXFWIF_FWCOMMONCONTEXT, psCCB),                       \
+               offsetof(RGXFWIF_FWCOMMONCONTEXT, ui64MCUFenceAddr)
+
+#endif /*  __RGX_FWIF_ALIGNCHECKS_KM_H__ */
+
+/******************************************************************************
+ End of file (rgx_fwif_alignchecks_km.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_fwif_km.h b/drivers/gpu/rogue_m/services/include/rgx_fwif_km.h
new file mode 100644 (file)
index 0000000..c871e34
--- /dev/null
@@ -0,0 +1,860 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX firmware interface structures used by pvrsrvkm
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX firmware interface structures used by pvrsrvkm
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_FWIF_KM_H__)
+#define __RGX_FWIF_KM_H__
+
+#include "img_types.h"
+#include "rgx_fwif_shared.h"
+#include "rgxdefs_km.h"
+#include "pvr_debug.h"
+#include "dllist.h"
+
+#if defined(RGX_FIRMWARE)
+/* Compiling the actual firmware - use a fully typed pointer */
+typedef struct _RGXFWIF_HOST_CTL_                      *PRGXFWIF_HOST_CTL;
+typedef struct _RGXFWIF_CCB_CTL_                       *PRGXFWIF_CCB_CTL;
+typedef IMG_UINT8                                                      *PRGXFWIF_CCB;
+typedef struct _RGXFWIF_FWMEMCONTEXT_          *PRGXFWIF_FWMEMCONTEXT;
+typedef struct _RGXFWIF_FWRENDERCONTEXT_       *PRGXFWIF_FWRENDERCONTEXT;
+typedef struct _RGXFWIF_FWTQ2DCONTEXT_         *PRGXFWIF_FWTQ2DCONTEXT;
+typedef struct _RGXFWIF_FWTQ3DCONTEXT_         *PRGXFWIF_FWTQ3DCONTEXT;
+typedef struct _RGXFWIF_FWCOMPUTECONTEXT_      *PRGXFWIF_FWCOMPUTECONTEXT;
+typedef struct _RGXFWIF_FWCOMMONCONTEXT_       *PRGXFWIF_FWCOMMONCONTEXT;
+typedef struct _RGXFWIF_ZSBUFFER_                      *PRGXFWIF_ZSBUFFER;
+typedef IMG_UINT32                                                     *PRGXFWIF_SIGBUFFER;
+typedef struct _RGXFWIF_INIT_                          *PRGXFWIF_INIT;
+typedef struct _RGXFWIF_RUNTIME_CFG                    *PRGXFWIF_RUNTIME_CFG;
+typedef struct _RGXFW_UNITTESTS_                       *PRGXFW_UNITTESTS;
+typedef struct _RGXFWIF_TRACEBUF_                      *PRGXFWIF_TRACEBUF;
+typedef IMG_UINT8                                                      *PRGXFWIF_HWPERFINFO;
+typedef struct _RGXFWIF_HWRINFOBUF_                    *PRGXFWIF_HWRINFOBUF;
+typedef struct _RGXFWIF_GPU_UTIL_FWCB_         *PRGXFWIF_GPU_UTIL_FWCB;
+typedef struct _RGXFWIF_REG_CFG_               *PRGXFWIF_REG_CFG;
+typedef IMG_UINT8                                                      *PRGXFWIF_COMMONCTX_STATE;
+typedef struct _RGXFWIF_TACTX_STATE_           *PRGXFWIF_TACTX_STATE;
+typedef struct _RGXFWIF_3DCTX_STATE_           *PRGXFWIF_3DCTX_STATE;
+typedef struct _RGXFWIF_COMPUTECTX_STATE_      *PRGXFWIF_COMPUTECTX_STATE;
+typedef struct _RGXFWIF_VRDMCTX_STATE_         *PRGXFWIF_VRDMCTX_STATE;
+typedef IMG_UINT8                                                      *PRGXFWIF_RF_CMD;
+typedef struct _RGXFWIF_COMPCHECKS_                    *PRGXFWIF_COMPCHECKS;
+typedef struct _RGX_HWPERF_CONFIG_CNTBLK_      *PRGX_HWPERF_CONFIG_CNTBLK;
+typedef IMG_UINT32                          *PRGX_HWPERF_SELECT_CUSTOM_CNTRS;
+typedef DLLIST_NODE                                                    RGXFWIF_DLLIST_NODE;
+typedef struct _RGXFWIF_HWPERF_CTL_                    *PRGXFWIF_HWPERF_CTL;
+#else
+/* Compiling the host driver - use a firmware device virtual pointer */
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_HOST_CTL;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_CCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_CCB;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWMEMCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWRENDERCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWTQ2DCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWTQ3DCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWCOMPUTECONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_FWCOMMONCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_ZSBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_SIGBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_INIT;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_RUNTIME_CFG;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFW_UNITTESTS;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_TRACEBUF;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_HWPERFINFO;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_HWRINFOBUF;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_GPU_UTIL_FWCB;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_REG_CFG;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_COMMONCTX_STATE;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_RF_CMD;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_COMPCHECKS;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGX_HWPERF_CONFIG_CNTBLK;
+typedef RGXFWIF_DEV_VIRTADDR                PRGX_HWPERF_SELECT_CUSTOM_CNTRS;
+typedef struct {RGXFWIF_DEV_VIRTADDR p;
+                                 RGXFWIF_DEV_VIRTADDR n;}      RGXFWIF_DLLIST_NODE;
+typedef RGXFWIF_DEV_VIRTADDR                           PRGXFWIF_HWPERF_CTL;
+#endif /* RGX_FIRMWARE */
+
+/*!
+ * This number is used to represent an invalid page catalogue physical address
+ */
+#define RGXFWIF_INVALID_PC_PHYADDR 0xFFFFFFFFFFFFFFFFLLU
+
+/*!
+       Firmware memory context.
+*/
+typedef struct _RGXFWIF_FWMEMCONTEXT_
+{
+       IMG_DEV_PHYADDR                 RGXFW_ALIGN sPCDevPAddr;        /*!< device physical address of context's page catalogue */
+       IMG_INT32                               uiPageCatBaseRegID;     /*!< associated page catalog base register (-1 == unallocated) */
+       IMG_UINT32                              uiBreakpointAddr; /*!< breakpoint address */
+       IMG_UINT32                              uiBPHandlerAddr;  /*!< breakpoint handler address */
+       IMG_UINT32                              uiBreakpointCtl; /*!< DM and enable control for BP */
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+    IMG_UINT32              ui32OSid;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_FWMEMCONTEXT;
+
+
+/*!
+ *     FW context state flags
+ */
+#define        RGXFWIF_CONTEXT_TAFLAGS_NEED_RESUME                     (0x00000001)
+#define        RGXFWIF_CONTEXT_RENDERFLAGS_NEED_RESUME         (0x00000002)
+#define RGXFWIF_CONTEXT_CDMFLAGS_NEED_RESUME           (0x00000004)
+#define RGXFWIF_CONTEXT_SHGFLAGS_NEED_RESUME           (0x00000008)
+#define RGXFWIF_CONTEXT_ALLFLAGS_NEED_RESUME           (0x0000000F)
+
+
+typedef struct _RGXFWIF_TACTX_STATE_
+{
+       /* FW-accessible TA state which must be written out to memory on context store */
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER;               /* To store in mid-TA */
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER_Init;  /* Initial value (in case is 'lost' due to a lock-up */
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VDM_BATCH;   
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VBS_SO_PRIM0;
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VBS_SO_PRIM1;
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VBS_SO_PRIM2;
+       IMG_UINT64      RGXFW_ALIGN uTAReg_VBS_SO_PRIM3;
+} UNCACHED_ALIGN RGXFWIF_TACTX_STATE;
+
+
+typedef struct _RGXFWIF_3DCTX_STATE_
+{
+       /* FW-accessible ISP state which must be written out to memory on context store */
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+       IMG_UINT32      RGXFW_ALIGN au3DReg_ISP_STORE[8];
+#else
+       IMG_UINT32      RGXFW_ALIGN au3DReg_ISP_STORE[32];
+#endif
+       IMG_UINT64      RGXFW_ALIGN u3DReg_PM_DEALLOCATED_MASK_STATUS;
+       IMG_UINT64      RGXFW_ALIGN u3DReg_PM_PDS_MTILEFREE_STATUS;
+} UNCACHED_ALIGN RGXFWIF_3DCTX_STATE;
+
+
+
+typedef struct _RGXFWIF_COMPUTECTX_STATE_
+{
+       IMG_UINT64      RGXFW_ALIGN     ui64Padding;
+} RGXFWIF_COMPUTECTX_STATE;
+
+
+typedef struct _RGXFWIF_VRDMCTX_STATE_
+{
+       /* FW-accessible TA state which must be written out to memory on context store */
+       IMG_UINT64      RGXFW_ALIGN uVRDMReg_VRM_CALL_STACK_POINTER;
+       IMG_UINT64      RGXFW_ALIGN uVRDMReg_VRM_BATCH;
+       
+       /* Number of kicks on this context */
+       IMG_UINT32  ui32NumKicks;
+} UNCACHED_ALIGN RGXFWIF_VRDMCTX_STATE;
+
+
+typedef struct _RGXFWIF_FWCOMMONCONTEXT_
+{
+       /*
+               Used by bg and irq context
+       */
+       /* CCB details for this firmware context */
+       PRGXFWIF_CCCB_CTL               psCCBCtl;                               /*!< CCB control */
+       PRGXFWIF_CCCB                   psCCB;                                  /*!< CCB base */
+
+       /*
+               Used by the bg context only
+       */
+       RGXFWIF_DLLIST_NODE             RGXFW_ALIGN sWaitingNode;                       /*!< List entry for the waiting list */
+
+       /*
+               Used by the irq context only
+       */
+       RGXFWIF_DLLIST_NODE             sRunNode;                               /*!< List entry for the run list */
+       
+       PRGXFWIF_FWMEMCONTEXT   psFWMemContext;                 /*!< Memory context */
+
+       /* Context suspend state */
+       PRGXFWIF_COMMONCTX_STATE        RGXFW_ALIGN psContextState;             /*!< TA/3D context suspend state, read/written by FW */
+       
+       /* Framework state
+        */
+       PRGXFWIF_RF_CMD         RGXFW_ALIGN psRFCmd;            /*!< Register updates for Framework */
+       
+       /*
+        *      Flags e.g. for context switching
+        */
+       IMG_UINT32                              ui32Flags;
+       IMG_UINT32                              ui32Priority;
+       IMG_UINT32                              ui32PrioritySeqNum;
+       IMG_UINT64              RGXFW_ALIGN     ui64MCUFenceAddr;
+
+       /* References to the host side originators */
+       IMG_UINT32                              ui32ServerCommonContextID;                      /*!< the Server Common Context */
+       IMG_UINT32                              ui32PID;                                                        /*!< associated process ID */
+       
+       /* Statistic updates waiting to be passed back to the host... */
+       IMG_BOOL                                bStatsPending;                                          /*!< True when some stats are pending */
+       IMG_INT32                               i32StatsNumStores;                                      /*!< Number of stores on this context since last update */
+       IMG_INT32                               i32StatsNumOutOfMemory;                         /*!< Number of OOMs on this context since last update */
+       IMG_INT32                               i32StatsNumPartialRenders;                      /*!< Number of PRs on this context since last update */
+} UNCACHED_ALIGN RGXFWIF_FWCOMMONCONTEXT;
+
+/*!
+       Firmware render context.
+*/
+typedef struct _RGXFWIF_FWRENDERCONTEXT_
+{
+       RGXFWIF_FWCOMMONCONTEXT sTAContext;                             /*!< Firmware context for the TA */
+       RGXFWIF_FWCOMMONCONTEXT s3DContext;                             /*!< Firmware context for the 3D */
+
+       /*
+        * Note: The following fields keep track of OOM and partial render statistics.
+        * Because these data structures are allocated cache-incoherent,
+        * and because these fields are updated by the firmware, 
+        * the host will read valid values only after an SLC flush/inval.
+        * This is only guaranteed to happen while destroying the render-context.
+        */
+       IMG_UINT32                      ui32TotalNumPartialRenders; /*!< Total number of partial renders */
+       IMG_UINT32                      ui32TotalNumOutOfMemory;        /*!< Total number of OOMs */
+
+} UNCACHED_ALIGN RGXFWIF_FWRENDERCONTEXT;
+
+/*!
+       Firmware render context.
+*/
+typedef struct _RGXFWIF_FWRAYCONTEXT_
+{
+       RGXFWIF_FWCOMMONCONTEXT sSHGContext;                            /*!< Firmware context for the SHG */
+       RGXFWIF_FWCOMMONCONTEXT sRTUContext;                            /*!< Firmware context for the RTU */
+       PRGXFWIF_CCCB_CTL               psCCBCtl[DPX_MAX_RAY_CONTEXTS];
+       PRGXFWIF_CCCB                   psCCB[DPX_MAX_RAY_CONTEXTS];
+       IMG_UINT32                              ui32NextFC;
+       IMG_UINT32                              ui32ActiveFCMask;
+} UNCACHED_ALIGN RGXFWIF_FWRAYCONTEXT;
+
+#define RGXFWIF_INVALID_FRAME_CONTEXT (0xFFFFFFFF)
+
+/*!
+    BIF requester selection
+*/
+typedef enum _RGXFWIF_BIFREQ_
+{
+       RGXFWIF_BIFREQ_TA               = 0,
+       RGXFWIF_BIFREQ_3D               = 1,
+       RGXFWIF_BIFREQ_CDM              = 2,
+       RGXFWIF_BIFREQ_2D               = 3,
+       RGXFWIF_BIFREQ_HOST             = 4,
+       RGXFWIF_BIFREQ_RTU              = 5,
+       RGXFWIF_BIFREQ_SHG              = 6,
+       RGXFWIF_BIFREQ_MAX              = 7
+} RGXFWIF_BIFREQ;
+
+typedef enum _RGXFWIF_PM_DM_
+{
+       RGXFWIF_PM_DM_TA        = 0,
+       RGXFWIF_PM_DM_3D        = 1,
+} RGXFWIF_PM_DM;
+
+typedef enum _RGXFWIF_RPM_DM_
+{
+       RGXFWIF_RPM_DM_SHF      = 0,
+       RGXFWIF_RPM_DM_SHG      = 1,
+       RGXFWIF_RPM_DM_MAX,
+} RGXFWIF_RPM_DM;
+
+/*!
+ ******************************************************************************
+ * Kernel CCB control for RGX
+ *****************************************************************************/
+typedef struct _RGXFWIF_CCB_CTL_
+{
+       volatile IMG_UINT32             ui32WriteOffset;                /*!< write offset into array of commands (MUST be aligned to 16 bytes!) */
+       volatile IMG_UINT32             ui32ReadOffset;                 /*!< read offset into array of commands */
+       IMG_UINT32                              ui32WrapMask;                   /*!< Offset wrapping mask (Total capacity of the CCB - 1) */
+       IMG_UINT32                              ui32CmdSize;                    /*!< size of each command in bytes */
+} UNCACHED_ALIGN RGXFWIF_CCB_CTL;
+
+/*!
+ ******************************************************************************
+ * Kernel CCB command structure for RGX
+ *****************************************************************************/
+#if !defined(RGX_FEATURE_SLC_VIVT)
+
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PT      (0x1) /* BIF_CTRL_INVAL_PT_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PD      (0x2) /* BIF_CTRL_INVAL_PD_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PC      (0x4) /* BIF_CTRL_INVAL_PC_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB   (0x10) /* can't use PM_TLB0 bit from BIFPM_CTRL reg because it collides with PT bit from BIF_CTRL reg */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB     (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB | 0x8) /* BIF_CTRL_INVAL_TLB1_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX(C)  (0x0) /* not used */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x0) /* not used */
+
+#else /* RGX_FEATURE_SLC_VIVT */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PT      (0x1) /* MMU_CTRL_INVAL_PT_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PD      (0x2) /* MMU_CTRL_INVAL_PD_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PC      (0x4) /* MMU_CTRL_INVAL_PC_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB   (0x0) /* not used */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB     (0x0) /* not used */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX(C)  ((C) << 0x3) /* MMU_CTRL_INVAL_CONTEXT_SHIFT */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */
+#endif
+
+typedef struct _RGXFWIF_MMUCACHEDATA_
+{
+       PRGXFWIF_FWMEMCONTEXT           psMemoryContext;
+       IMG_UINT32                                      ui32Flags;
+       IMG_UINT32                                      ui32CacheSequenceNum;
+} RGXFWIF_MMUCACHEDATA;
+
+typedef struct _RGXFWIF_SLCBPCTLDATA_
+{
+       IMG_BOOL               bSetBypassed;        /*!< Should SLC be/not be bypassed for indicated units? */
+       IMG_UINT32             uiFlags;             /*!< Units to enable/disable */
+} RGXFWIF_SLCBPCTLDATA;
+
+#define RGXFWIF_BPDATA_FLAGS_WRITE     (1 << 0)
+#define RGXFWIF_BPDATA_FLAGS_CTL       (1 << 1)
+#define RGXFWIF_BPDATA_FLAGS_REGS      (1 << 2)
+
+typedef struct _RGXFWIF_FWBPDATA_
+{
+       PRGXFWIF_FWMEMCONTEXT   psFWMemContext;                 /*!< Memory context */
+       IMG_UINT32              ui32BPAddr;                     /*!< Breakpoint address */
+       IMG_UINT32              ui32HandlerAddr;                /*!< Breakpoint handler */
+       IMG_UINT32              ui32BPDM;                       /*!< Breakpoint control */
+       IMG_BOOL                bEnable;
+       IMG_UINT32              ui32Flags;
+       IMG_UINT32              ui32TempRegs;           /*!< Number of temporary registers to overallocate */
+       IMG_UINT32              ui32SharedRegs;         /*!< Number of shared registers to overallocate */
+} RGXFWIF_BPDATA;
+
+#define RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS 4
+
+typedef struct _RGXFWIF_KCCB_CMD_KICK_DATA_
+{
+       PRGXFWIF_FWCOMMONCONTEXT        psContext;                      /*!< address of the firmware context */
+       IMG_UINT32                                      ui32CWoffUpdate;        /*!< Client CCB woff update */
+       IMG_UINT32              ui32NumCleanupCtl;              /*!< number of CleanupCtl pointers attached */
+       PRGXFWIF_CLEANUP_CTL    apsCleanupCtl[RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS]; /*!< CleanupCtl structures associated with command */
+} RGXFWIF_KCCB_CMD_KICK_DATA;
+
+typedef struct _RGXFWIF_KCCB_CMD_FENCE_DATA_
+{
+       IMG_UINT32 uiSyncObjDevVAddr;
+       IMG_UINT32 uiUpdateVal;
+} RGXFWIF_KCCB_CMD_SYNC_DATA;
+
+typedef enum _RGXFWIF_CLEANUP_TYPE_
+{
+       RGXFWIF_CLEANUP_FWCOMMONCONTEXT,                /*!< FW common context cleanup */
+       RGXFWIF_CLEANUP_HWRTDATA,                               /*!< FW HW RT data cleanup */
+       RGXFWIF_CLEANUP_FREELIST,                               /*!< FW freelist cleanup */
+       RGXFWIF_CLEANUP_ZSBUFFER,                               /*!< FW ZS Buffer cleanup */
+       RGXFWIF_CLEANUP_HWFRAMEDATA,                    /*!< FW RPM/RTU frame data */
+       RGXFWIF_CLEANUP_RPM_FREELIST,                   /*!< FW RPM freelist */
+} RGXFWIF_CLEANUP_TYPE;
+
+#define RGXFWIF_CLEANUP_RUN            (1 << 0)        /*!< The requested cleanup command has run on the FW */
+#define RGXFWIF_CLEANUP_BUSY   (1 << 1)        /*!< The requested resource is busy */
+
+typedef struct _RGXFWIF_CLEANUP_REQUEST_
+{
+       RGXFWIF_CLEANUP_TYPE                    eCleanupType;                   /*!< Cleanup type */
+       union {
+               PRGXFWIF_FWCOMMONCONTEXT        psContext;                              /*!< FW common context to cleanup */
+               PRGXFWIF_HWRTDATA                       psHWRTData;                             /*!< HW RT to cleanup */
+               PRGXFWIF_FREELIST                       psFreelist;                             /*!< Freelist to cleanup */
+               PRGXFWIF_ZSBUFFER                       psZSBuffer;                             /*!< ZS Buffer to cleanup */
+#if defined(RGX_FEATURE_RAY_TRACING)
+               PRGXFWIF_RAY_FRAME_DATA         psHWFrameData;                  /*!< RPM/RTU frame data to cleanup */
+               PRGXFWIF_RPM_FREELIST           psRPMFreelist;                  /*!< RPM Freelist to cleanup */
+#endif
+       } uCleanupData;
+       IMG_UINT32                                              uiSyncObjDevVAddr;              /*!< sync primitive used to indicate state of the request */
+} RGXFWIF_CLEANUP_REQUEST;
+
+typedef enum _RGXFWIF_POWER_TYPE_
+{
+       RGXFWIF_POW_OFF_REQ = 1,
+       RGXFWIF_POW_FORCED_IDLE_REQ,
+       RGXFWIF_POW_NUMDUST_CHANGE,
+       RGXFWIF_POW_APM_LATENCY_CHANGE
+} RGXFWIF_POWER_TYPE;
+
+typedef struct _RGXFWIF_POWER_REQUEST_
+{
+       RGXFWIF_POWER_TYPE                              ePowType;                               /*!< Type of power request */
+       union
+       {
+               IMG_UINT32                                      ui32NumOfDusts;                 /*!< Number of active Dusts */
+               IMG_BOOL                                        bForced;                                /*!< If the operation is mandatory */
+               IMG_BOOL                                        bCancelForcedIdle;              /*!< If the operation is to cancel previously forced idle */
+               IMG_UINT32                                      ui32ActivePMLatencyms;          /*!< Number of milliseconds to set APM latency */
+       } uPoweReqData;
+} RGXFWIF_POWER_REQUEST;
+
+typedef struct _RGXFWIF_SLCFLUSHINVALDATA_
+{
+       PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to fence on (only useful when bDMContext == TRUE) */
+       IMG_BOOL    bInval;                 /*!< Invalidate the cache as well as flushing */
+       IMG_BOOL    bDMContext;             /*!< The data to flush/invalidate belongs to a specific DM context */
+       RGXFWIF_DM  eDM;                    /*!< DM to flush entries for (only useful when bDMContext == TRUE) */
+} RGXFWIF_SLCFLUSHINVALDATA;
+
+typedef struct _RGXFWIF_HWPERF_CTRL_
+{
+       IMG_BOOL                                bToggle;        /*!< Toggle masked bits or apply full mask? */
+       IMG_UINT64      RGXFW_ALIGN     ui64Mask;   /*!< Mask of events to toggle */
+} RGXFWIF_HWPERF_CTRL;
+
+typedef struct _RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS_
+{
+       IMG_UINT32                              ui32NumBlocks;  /*!< Number of RGX_HWPERF_CONFIG_CNTBLK in the array */
+       PRGX_HWPERF_CONFIG_CNTBLK pasBlockConfigs;      /*!< Address of the RGX_HWPERF_CONFIG_CNTBLK array */
+} RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS;
+
+typedef struct _RGXFWIF_CORECLKSPEEDCHANGE_DATA_
+{
+       IMG_UINT32      ui32NewClockSpeed;                      /*!< New clock speed */
+} RGXFWIF_CORECLKSPEEDCHANGE_DATA;
+
+#define RGXFWIF_HWPERF_CTRL_BLKS_MAX   16
+
+typedef struct _RGXFWIF_HWPERF_CTRL_BLKS_
+{
+       IMG_BOOL        bEnable;
+       IMG_UINT32      ui32NumBlocks;                              /*!< Number of block IDs in the array */
+       IMG_UINT16      aeBlockIDs[RGXFWIF_HWPERF_CTRL_BLKS_MAX];   /*!< Array of RGX_HWPERF_CNTBLK_ID values */
+} RGXFWIF_HWPERF_CTRL_BLKS;
+
+
+typedef struct _RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS_
+{
+       IMG_UINT16 ui16CustomBlock;
+       IMG_UINT16 ui16NumCounters;
+       PRGX_HWPERF_SELECT_CUSTOM_CNTRS pui32CustomCounterIDs;
+} RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS;
+
+typedef struct _RGXFWIF_ZSBUFFER_BACKING_DATA_
+{
+       IMG_UINT32                              psZSBufferFWDevVAddr;                           /*!< ZS-Buffer FW address */
+       IMG_UINT32                              bDone;                                                          /*!< action backing/unbacking succeeded */
+} RGXFWIF_ZSBUFFER_BACKING_DATA;
+
+/*
+ * Flags to pass in the unused bits of the page size grow request
+ */
+#define RGX_FREELIST_GSDATA_RPM_RESTART_EN             (1 << 31)               /*!< Restart RPM after freelist grow command */
+#define RGX_FREELIST_GSDATA_RPM_PAGECNT_MASK   (0x3FFFFFU)             /*!< Mask for page count. */
+
+typedef struct _RGXFWIF_FREELIST_GS_DATA_
+{
+       IMG_UINT32                              psFreeListFWDevVAddr;                           /*!< Freelist FW address */
+       IMG_UINT32                              ui32DeltaSize;                                          /*!< Amount of the Freelist change */
+       IMG_UINT32                              ui32NewSize;                                            /*!< New amount of pages on the freelist */
+} RGXFWIF_FREELIST_GS_DATA;
+
+#define RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG 0x80000000
+
+typedef struct _RGXFWIF_FREELISTS_RECONSTRUCTION_DATA_
+{
+       IMG_UINT32                      ui32FreelistsCount;
+       IMG_UINT32                      aui32FreelistIDs[MAX_HW_TA3DCONTEXTS * RGXFW_MAX_FREELISTS];
+} RGXFWIF_FREELISTS_RECONSTRUCTION_DATA;
+
+/*!
+ ******************************************************************************
+ * Register configuration structures
+ *****************************************************************************/
+
+#define RGXFWIF_REG_CFG_MAX_SIZE 512
+
+typedef enum _RGXFWIF_REGDATA_CMD_TYPE_
+{
+       RGXFWIF_REGCFG_CMD_ADD                          = 101,
+       RGXFWIF_REGCFG_CMD_CLEAR                        = 102,
+       RGXFWIF_REGCFG_CMD_ENABLE                       = 103,
+       RGXFWIF_REGCFG_CMD_DISABLE                      = 104
+} RGXFWIF_REGDATA_CMD_TYPE;
+
+typedef struct _RGXFWIF_REGCONFIG_DATA_
+{
+       RGXFWIF_REGDATA_CMD_TYPE        eCmdType;
+       RGXFWIF_PWR_EVT                 eRegConfigPI;
+       RGXFWIF_REG_CFG_REC RGXFW_ALIGN         sRegConfig;
+
+} RGXFWIF_REGCONFIG_DATA;
+
+typedef struct _RGXFWIF_REG_CFG_
+{
+       IMG_UINT32                      ui32NumRegsSidekick;
+       IMG_UINT32                      ui32NumRegsRascalDust;
+       RGXFWIF_REG_CFG_REC     RGXFW_ALIGN     asRegConfigs[RGXFWIF_REG_CFG_MAX_SIZE];
+} UNCACHED_ALIGN RGXFWIF_REG_CFG;
+
+typedef enum _RGXFWIF_KCCB_CMD_TYPE_
+{
+       RGXFWIF_KCCB_CMD_KICK                                           = 101,
+       RGXFWIF_KCCB_CMD_MMUCACHE                                       = 102,
+       RGXFWIF_KCCB_CMD_BP                                                     = 104,
+       RGXFWIF_KCCB_CMD_SLCBPCTL                               = 106, /*!< slc bypass control. Requires sSLCBPCtlData. For validation */
+       RGXFWIF_KCCB_CMD_SYNC                                   = 107, /*!< host sync command. Requires sSyncData. */
+       RGXFWIF_KCCB_CMD_SLCFLUSHINVAL                          = 108, /*!< slc flush and invalidation request */
+       RGXFWIF_KCCB_CMD_CLEANUP                                        = 109, /*!< Requests cleanup of a FW resource (type specified in the command data) */
+       RGXFWIF_KCCB_CMD_POW                                            = 110, /*!< Power request */
+       RGXFWIF_KCCB_CMD_HWPERF_CTRL_EVENTS                     = 111, /*!< Control the HWPerf event generation behaviour */
+       RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS      = 112, /*!< Configure, clear and enable multiple HWPerf blocks */
+       RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS                       = 113, /*!< Enable or disable multiple HWPerf blocks (reusing existing configuration) */
+       RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE                     = 114, /*!< CORE clock speed change event */
+       RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE        = 115, /*!< Backing for on-demand ZS-Buffer done */
+       RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE      = 116, /*!< Unbacking for on-demand ZS-Buffer done */
+       RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE           = 117, /*!< Freelist Grow done */
+       RGXFWIF_KCCB_CMD_FREELIST_SHRINK_UPDATE         = 118, /*!< Freelist Shrink done */
+       RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE        = 119, /*!< Freelists Reconstruction done */
+       RGXFWIF_KCCB_CMD_HEALTH_CHECK               = 120, /*!< Health check request */
+       RGXFWIF_KCCB_CMD_REGCONFIG                  = 121,
+       RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS = 122, /*!< Configure the custom counters for HWPerf */
+       RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS_DIRECT       = 123, /*!< Configure, clear and enable multiple HWPerf blocks during the init process*/
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       RGXFWIF_FWCCB_CMD_DOPPLER_MEMORY_GROW           = 130,
+#endif
+} RGXFWIF_KCCB_CMD_TYPE;
+
+/* Kernel CCB command packet */
+typedef struct _RGXFWIF_KCCB_CMD_
+{
+       RGXFWIF_KCCB_CMD_TYPE                                   eCmdType;                       /*!< Command type */
+       union
+       {
+               RGXFWIF_KCCB_CMD_KICK_DATA                      sCmdKickData;                   /*!< Data for Kick command */
+               RGXFWIF_MMUCACHEDATA                            sMMUCacheData;                  /*!< Data for MMUCACHE command */
+               RGXFWIF_BPDATA                                          sBPData;                                /*!< Data for Breakpoint Commands */
+               RGXFWIF_SLCBPCTLDATA                            sSLCBPCtlData;                  /*!< Data for SLC Bypass Control */
+               RGXFWIF_KCCB_CMD_SYNC_DATA                      sSyncData;              /*!< Data for host sync commands */
+               RGXFWIF_SLCFLUSHINVALDATA                       sSLCFlushInvalData;             /*!< Data for SLC Flush/Inval commands */
+               RGXFWIF_CLEANUP_REQUEST                         sCleanupData;                   /*!< Data for cleanup commands */
+               RGXFWIF_POWER_REQUEST                           sPowData;                               /*!< Data for power request commands */
+               RGXFWIF_HWPERF_CTRL                                     sHWPerfCtrl;                    /*!< Data for HWPerf control command */
+               RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS       sHWPerfCfgEnableBlks;   /*!< Data for HWPerf configure, clear and enable performance counter block command */
+               RGXFWIF_HWPERF_CTRL_BLKS                        sHWPerfCtrlBlks;                /*!< Data for HWPerf enable or disable performance counter block commands */
+               RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS  sHWPerfSelectCstmCntrs; /*!< Data for HWPerf configure the custom counters to read */
+               RGXFWIF_CORECLKSPEEDCHANGE_DATA         sCORECLKSPEEDCHANGEData;/*!< Data for CORE clock speed change */
+               RGXFWIF_ZSBUFFER_BACKING_DATA           sZSBufferBackingData;   /*!< Feedback for Z/S Buffer backing/unbacking */
+               RGXFWIF_FREELIST_GS_DATA                        sFreeListGSData;                /*!< Feedback for Freelist grow/shrink */
+               RGXFWIF_FREELISTS_RECONSTRUCTION_DATA   sFreeListsReconstructionData;   /*!< Feedback for Freelists reconstruction */
+               RGXFWIF_REGCONFIG_DATA                          sRegConfigData;                 /*!< Data for custom register configuration */
+       } UNCACHED_ALIGN uCmdData;
+} UNCACHED_ALIGN RGXFWIF_KCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_KCCB_CMD);
+
+/*!
+ ******************************************************************************
+ * Firmware CCB command structure for RGX
+ *****************************************************************************/
+
+typedef struct _RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA_
+{
+       IMG_UINT32                              ui32ZSBufferID;
+       IMG_BOOL                                bPopulate;
+} RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA;
+
+typedef struct _RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA_
+{
+       IMG_UINT32                              ui32FreelistID;
+} RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA;
+
+typedef struct _RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA_
+{
+       IMG_UINT32                      ui32FreelistsCount;
+       IMG_UINT32                      ui32HwrCounter;
+       IMG_UINT32                      aui32FreelistIDs[MAX_HW_TA3DCONTEXTS * RGXFW_MAX_FREELISTS];
+} RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA;
+
+typedef struct _RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA_
+{
+       IMG_UINT32                                              ui32ServerCommonContextID;      /*!< Context affected by the reset */
+       RGXFWIF_CONTEXT_RESET_REASON    eResetReason;                           /*!< Reason for reset */
+} RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA;
+
+
+typedef enum _RGXFWIF_FWCCB_CMD_TYPE_
+{
+       RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING                              = 101,  /*!< Requests ZSBuffer to be backed with physical pages */
+       RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING                    = 102,  /*!< Requests ZSBuffer to be unbacked */
+       RGXFWIF_FWCCB_CMD_FREELIST_GROW                                 = 103,  /*!< Requests an on-demand freelist grow/shrink */
+       RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION              = 104,  /*!< Requests freelists reconstruction */
+       RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION    = 105,  /*!< Notifies host of a HWR event on a context */
+       RGXFWIF_FWCCB_CMD_DEBUG_DUMP                                    = 106,  /*!< Requests an on-demand debug dump */
+       RGXFWIF_FWCCB_CMD_UPDATE_STATS                                  = 107,  /*!< Requests an on-demand update on process stats */
+} RGXFWIF_FWCCB_CMD_TYPE;
+
+typedef enum
+{
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS=1,            /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumPartialRenders stat */
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY,                        /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumOutOfMemory stat */
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES,                            /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTAStores stat */
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES,                            /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32Num3DStores stat */
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_SH_STORES,                            /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumSHStores stat */
+    RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES                            /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumCDMStores stat */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE;
+
+
+/* Firmware CCB command packet */
+
+typedef struct
+{
+    RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE                eElementToUpdate;                       /*!< Element to update */
+    IMG_PID                                                                    pidOwner;                                       /*!< The pid of the process whose stats are being updated */
+    IMG_INT32                                                          i32AdjustmentValue;                     /*!< Adjustment to be made to the statistic */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA;
+
+typedef struct _RGXFWIF_FWCCB_CMD_
+{
+       RGXFWIF_FWCCB_CMD_TYPE                                  eCmdType;       /*!< Command type */
+       union
+       {
+               RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA                         sCmdZSBufferBacking;                    /*!< Data for Z/S-Buffer on-demand (un)backing*/
+               RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA                                      sCmdFreeListGS;                                 /*!< Data for on-demand freelist grow/shrink */
+               RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA         sCmdFreeListsReconstruction;    /*!< Data for freelists reconstruction */
+               RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA                            sCmdContextResetNotification;   /*!< Data for context reset notification */
+        RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA                 sCmdUpdateStatsData;            /*!< Data for updating process stats */
+       } RGXFW_ALIGN uCmdData;
+} RGXFW_ALIGN RGXFWIF_FWCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_FWCCB_CMD);
+
+/*!
+ ******************************************************************************
+ * Signature and Checksums Buffer
+ *****************************************************************************/
+typedef struct _RGXFWIF_SIGBUF_CTL_
+{
+       PRGXFWIF_SIGBUFFER              psBuffer;                       /*!< Ptr to Signature Buffer memory */
+       IMG_UINT32                              ui32LeftSizeInRegs;     /*!< Amount of space left for storing regs in the buffer */
+} UNCACHED_ALIGN RGXFWIF_SIGBUF_CTL;
+
+/*!
+ ******************************************************************************
+ * Updated configuration post FW data init.
+ *****************************************************************************/
+typedef struct _RGXFWIF_RUNTIME_CFG_
+{
+       IMG_UINT32                              ui32ActivePMLatencyms;          /* APM latency in ms before signalling IDLE to the host */
+       IMG_BOOL                                bActivePMLatencyPersistant;     /* If set, APM latency does not reset to system default each GPU power transition */
+       IMG_UINT32                              ui32CoreClockSpeed;             /* Core clock speed, currently only used to calculate timer ticks */
+} RGXFWIF_RUNTIME_CFG;
+
+/*!
+ *****************************************************************************
+ * Control data for RGX
+ *****************************************************************************/
+
+#define RGXFWIF_HWR_DEBUG_DUMP_ALL (99999)
+
+#if defined(PDUMP)
+
+#define RGXFWIF_PID_FILTER_MAX_NUM_PIDS 32
+
+typedef enum _RGXFWIF_PID_FILTER_MODE_
+{
+       RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT,
+       RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT
+} RGXFWIF_PID_FILTER_MODE;
+
+typedef struct _RGXFWIF_PID_FILTER_ITEM_
+{
+       IMG_PID uiPID;
+       IMG_UINT32 ui32OSID;
+} RGXFW_ALIGN RGXFWIF_PID_FILTER_ITEM;
+
+typedef struct _RGXFWIF_PID_FILTER_
+{
+       RGXFWIF_PID_FILTER_MODE eMode;
+       /* each process in the filter list is specified by a PID and OS ID pair.
+        * each PID and OS pair is an item in the items array (asItems).
+        * if the array contains less than RGXFWIF_PID_FILTER_MAX_NUM_PIDS entries
+        * then it must be terminated by an item with pid of zero.
+        */
+       RGXFWIF_PID_FILTER_ITEM asItems[RGXFWIF_PID_FILTER_MAX_NUM_PIDS];
+} RGXFW_ALIGN RGXFWIF_PID_FILTER;
+#endif
+
+typedef struct _RGXFWIF_INIT_
+{
+       IMG_DEV_PHYADDR                 RGXFW_ALIGN sFaultPhysAddr;
+
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sPDSExecBase;
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sUSCExecBase;
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sResultDumpBase;
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sDPXControlStreamBase;
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sRTUHeapBase;
+
+       IMG_BOOL                                bFirstTA;
+       IMG_BOOL                                bFirstRender;
+       IMG_BOOL                                bFrameworkAfterInit;
+       IMG_BOOL                                bEnableHWPerf;
+       IMG_BOOL                bDisableFilterHWPerfCustomCounter;
+       IMG_UINT32                              uiPowerSync;
+       IMG_UINT32                              ui32FilterFlags;
+
+       /* Kernel CCBs */
+       PRGXFWIF_CCB_CTL                psKernelCCBCtl[RGXFWIF_DM_MAX];
+       PRGXFWIF_CCB                    psKernelCCB[RGXFWIF_DM_MAX];
+
+       /* Firmware CCBs */
+       PRGXFWIF_CCB_CTL                psFirmwareCCBCtl[RGXFWIF_DM_MAX];
+       PRGXFWIF_CCB                    psFirmwareCCB[RGXFWIF_DM_MAX];
+
+       RGXFWIF_DM                              eDM[RGXFWIF_DM_MAX];
+
+       RGXFWIF_SIGBUF_CTL              asSigBufCtl[RGXFWIF_DM_MAX];
+
+       IMG_BOOL                                bEnableLogging;
+       IMG_UINT32                              ui32ConfigFlags;        /*!< Configuration flags from host */
+       IMG_UINT32                              ui32BreakpointTemps;
+       IMG_UINT32                              ui32BreakpointShareds;
+       IMG_UINT32                              ui32HWRDebugDumpLimit;
+       struct
+       {
+               IMG_UINT64 uiBase;
+               IMG_UINT64 uiLen;
+               IMG_UINT64 uiXStride;
+       }                       RGXFW_ALIGN sBifTilingCfg[RGXFWIF_NUM_BIF_TILING_CONFIGS];
+
+       PRGXFWIF_RUNTIME_CFG            psRuntimeCfg;
+
+       PRGXFWIF_TRACEBUF               psTraceBufCtl;
+       PRGXFWIF_HWPERFINFO             psHWPerfInfoCtl;
+       IMG_UINT64      RGXFW_ALIGN ui64HWPerfFilter;
+
+       PRGXFWIF_HWRINFOBUF             psRGXFWIfHWRInfoBufCtl;
+       PRGXFWIF_GPU_UTIL_FWCB  psGpuUtilFWCbCtl;
+       PRGXFWIF_REG_CFG                psRegCfg;
+       PRGXFWIF_HWPERF_CTL                     psHWPerfCtl;
+
+#if defined(RGXFW_ALIGNCHECKS)
+#if defined(RGX_FIRMWARE)
+       IMG_UINT32*                             paui32AlignChecks;
+#else
+       RGXFWIF_DEV_VIRTADDR    paui32AlignChecks;
+#endif
+#endif
+
+       /* Core clock speed at FW boot time */ 
+       IMG_UINT32              ui32InitialCoreClockSpeed;
+       
+       /* APM latency in ms before signalling IDLE to the host */
+       IMG_UINT32                              ui32ActivePMLatencyms;
+
+       /* Flag to be set by the Firmware after successful start */
+       IMG_BOOL                                bFirmwareStarted;
+
+       IMG_UINT32                              ui32FirmwareStartedTimeStamp;
+
+       IMG_UINT32                              ui32JonesDisableMask;
+
+       /* Compatibility checks to be populated by the Firmware */
+       RGXFWIF_COMPCHECKS              sRGXCompChecks;
+
+       RGXFWIF_DMA_ADDR                sCorememDataStore;
+
+#if defined(RGX_FEATURE_SLC_VIVT)
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sSLC3FenceDevVAddr;
+#endif
+
+#if defined(PDUMP)
+       RGXFWIF_PID_FILTER sPIDFilter;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_INIT;
+
+
+/*!
+ ******************************************************************************
+ * Client CCB commands which are only required by the kernel
+ *****************************************************************************/
+typedef struct _RGXFWIF_CMD_PRIORITY_
+{
+       IMG_UINT32                              ui32Priority;
+} RGXFWIF_CMD_PRIORITY;
+
+/*!
+ ******************************************************************************
+ * RGXFW Unittests declarations
+ *****************************************************************************/
+typedef struct _RGXFW_UNITTEST2_
+{
+       /* Irq events */
+       IMG_UINT32      ui32IrqKicksDM[RGXFWIF_DM_MAX_MTS];
+       IMG_UINT32      ui32IrqKicksBg;
+       IMG_UINT32      ui32IrqKicksTimer;
+
+       /* Bg events */
+       IMG_UINT32      ui32BgKicksDM[RGXFWIF_DM_MAX_MTS];
+       IMG_UINT32      ui32BgKicksCounted;
+
+} RGXFW_UNITTEST2;
+
+/*!
+ ******************************************************************************
+ * RGXFW_UNITTESTS declaration
+ *****************************************************************************/
+#define RGXFW_UNITTEST_FWPING          (0x1)
+#define RGXFW_UNITTEST_FWPONG          (0x2)
+
+#define RGXFW_UNITTEST_IS_BGKICK(DM)   ((DM) & 0x1)
+
+typedef struct _RGXFW_UNITTESTS_
+{
+       IMG_UINT32      ui32Status;
+
+       RGXFW_UNITTEST2 sUnitTest2;
+
+} RGXFW_UNITTESTS;
+
+#endif /*  __RGX_FWIF_KM_H__ */
+
+/******************************************************************************
+ End of file (rgx_fwif_km.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_fwif_resetframework.h b/drivers/gpu/rogue_m/services/include/rgx_fwif_resetframework.h
new file mode 100644 (file)
index 0000000..25ee674
--- /dev/null
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@File                  rgx_fwif_resetframework.h
+@Title                 Post-reset work-around framework FW interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_RGX_FWIF_RESETFRAMEWORK_H)
+#define _RGX_FWIF_RESETFRAMEWORK_H
+
+#include "img_types.h"
+#include "rgx_fwif_shared.h"
+
+typedef struct _RGXFWIF_RF_REGISTERS_
+{
+       IMG_UINT64  uCDMReg_CDM_CTRL_STREAM_BASE;
+} RGXFWIF_RF_REGISTERS;
+
+#define RGXFWIF_RF_FLAG_ENABLE 0x00000001 /*!< enables the reset framework in the firmware */
+
+typedef struct _RGXFWIF_RF_CMD_
+{
+       IMG_UINT32           ui32Flags;
+
+       /* THIS MUST BE THE LAST MEMBER OF THE CONTAINING STRUCTURE */
+       RGXFWIF_RF_REGISTERS RGXFW_ALIGN sFWRegisters;
+
+} RGXFWIF_RF_CMD;
+
+/* to opaquely allocate and copy in the kernel */
+#define RGXFWIF_RF_CMD_SIZE  sizeof(RGXFWIF_RF_CMD)
+
+#endif /* _RGX_FWIF_RESETFRAMEWORK_H */
diff --git a/drivers/gpu/rogue_m/services/include/rgx_fwif_shared.h b/drivers/gpu/rogue_m/services/include/rgx_fwif_shared.h
new file mode 100644 (file)
index 0000000..96a9688
--- /dev/null
@@ -0,0 +1,528 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX firmware interface structures
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX firmware interface structures shared by both host client
+                and host server
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_FWIF_SHARED_H__)
+#define __RGX_FWIF_SHARED_H__
+
+#include "img_types.h"
+#include "rgx_common.h"
+#include "devicemem_typedefs.h"
+
+
+/*!
+ ******************************************************************************
+ * Device state flags
+ *****************************************************************************/
+#define RGXKMIF_DEVICE_STATE_ZERO_FREELIST                     (0x1 << 0)              /*!< Zeroing the physical pages of reconstructed free lists */
+#define RGXKMIF_DEVICE_STATE_FTRACE_EN                         (0x1 << 1)              /*!< Used to enable device FTrace thread to consume HWPerf data */
+#define RGXKMIF_DEVICE_STATE_DISABLE_DW_LOGGING_EN     (0x1 << 2)              /*!< Used to disable the Devices Watchdog logging */
+
+/* Required memory alignment for 64-bit variables accessible by Meta 
+  (the gcc meta aligns 64-bit vars to 64-bit; therefore, mem shared between
+   the host and meta that contains 64-bit vars has to maintain this aligment)*/
+#define RGXFWIF_FWALLOC_ALIGN  sizeof(IMG_UINT64)
+
+typedef struct _RGXFWIF_DEV_VIRTADDR_
+{
+       IMG_UINT32      ui32Addr;
+} RGXFWIF_DEV_VIRTADDR;
+
+typedef struct _RGXFWIF_DMA_ADDR_
+{
+       IMG_DEV_VIRTADDR        RGXFW_ALIGN psDevVirtAddr;
+
+#if defined(RGX_FIRMWARE)
+       IMG_PBYTE               pbyFWAddr;
+#else
+       RGXFWIF_DEV_VIRTADDR    pbyFWAddr;
+#endif
+} UNCACHED_ALIGN RGXFWIF_DMA_ADDR;
+
+typedef IMG_UINT8      RGXFWIF_CCCB;
+
+#if defined(RGX_FIRMWARE)
+/* Compiling the actual firmware - use a fully typed pointer */
+typedef RGXFWIF_CCCB                                   *PRGXFWIF_CCCB;
+typedef struct _RGXFWIF_CCCB_CTL_              *PRGXFWIF_CCCB_CTL;
+typedef struct _RGXFWIF_RENDER_TARGET_ *PRGXFWIF_RENDER_TARGET;
+typedef struct _RGXFWIF_HWRTDATA_              *PRGXFWIF_HWRTDATA;
+typedef struct _RGXFWIF_FREELIST_              *PRGXFWIF_FREELIST;
+typedef struct _RGXFWIF_RAY_FRAME_DATA_        *PRGXFWIF_RAY_FRAME_DATA;
+typedef struct _RGXFWIF_RPM_FREELIST_  *PRGXFWIF_RPM_FREELIST;
+typedef struct _RGXFWIF_RTA_CTL_               *PRGXFWIF_RTA_CTL;
+typedef IMG_UINT32                                             *PRGXFWIF_UFO_ADDR;
+typedef struct _RGXFWIF_CLEANUP_CTL_   *PRGXFWIF_CLEANUP_CTL;
+#else
+/* Compiling the host driver - use a firmware device virtual pointer */
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_CCCB;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_CCCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_RENDER_TARGET;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_HWRTDATA;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_FREELIST;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_RAY_FRAME_DATA;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_RPM_FREELIST;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_RTA_CTL;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_UFO_ADDR;
+typedef RGXFWIF_DEV_VIRTADDR   PRGXFWIF_CLEANUP_CTL;
+#endif /* RGX_FIRMWARE */
+
+
+/* FIXME PRGXFWIF_UFO_ADDR and RGXFWIF_UFO should move back into rgx_fwif_client.h */
+typedef struct _RGXFWIF_UFO_
+{
+       PRGXFWIF_UFO_ADDR       puiAddrUFO;
+       IMG_UINT32                      ui32Value;
+} RGXFWIF_UFO;
+
+
+/*!
+       Last reset reason for a context.
+*/
+typedef enum _RGXFWIF_CONTEXT_RESET_REASON_
+{
+       RGXFWIF_CONTEXT_RESET_REASON_NONE                                       = 0,    /*!< No reset reason recorded */
+       RGXFWIF_CONTEXT_RESET_REASON_GUILTY_LOCKUP                      = 1,    /*!< Caused a reset due to locking up */
+       RGXFWIF_CONTEXT_RESET_REASON_INNOCENT_LOCKUP            = 2,    /*!< Affected by another context locking up */
+       RGXFWIF_CONTEXT_RESET_REASON_GUILTY_OVERRUNING          = 3,    /*!< Overran the global deadline */
+       RGXFWIF_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING        = 4,    /*!< Affected by another context overrunning */
+} RGXFWIF_CONTEXT_RESET_REASON;
+
+
+/*!
+       HWRTData state the render is in
+*/
+typedef enum
+{
+       RGXFWIF_RTDATA_STATE_NONE = 0,
+       RGXFWIF_RTDATA_STATE_KICKTA,
+       RGXFWIF_RTDATA_STATE_KICKTAFIRST,
+       RGXFWIF_RTDATA_STATE_TAFINISHED,
+       RGXFWIF_RTDATA_STATE_KICK3D,
+       RGXFWIF_RTDATA_STATE_3DFINISHED,
+       RGXFWIF_RTDATA_STATE_TAOUTOFMEM,
+       RGXFWIF_RTDATA_STATE_PARTIALRENDERFINISHED,
+       RGXFWIF_RTDATA_STATE_HWR                                        /*!< In case of HWR, we can't set the RTDATA state to NONE,
+                                                                                                        as this will cause any TA to become a first TA.
+                                                                                                        To ensure all related TA's are skipped, we use the HWR state */
+} RGXFWIF_RTDATA_STATE;
+
+typedef struct _RGXFWIF_CLEANUP_CTL_
+{
+       IMG_UINT32                              ui32SubmittedCommands;  /*!< Number of commands received by the FW */
+       IMG_UINT32                              ui32ExecutedCommands;   /*!< Number of commands executed by the FW */
+} UNCACHED_ALIGN RGXFWIF_CLEANUP_CTL;
+
+
+/*!
+ ******************************************************************************
+ * Client CCB control for RGX
+ *****************************************************************************/
+typedef struct _RGXFWIF_CCCB_CTL_
+{
+       IMG_UINT32                              ui32WriteOffset;        /*!< write offset into array of commands (MUST be aligned to 16 bytes!) */
+       IMG_UINT32                              ui32ReadOffset;         /*!< read offset into array of commands */
+       IMG_UINT32                              ui32DepOffset;          /*!< Dependency offset */
+       IMG_UINT32                              ui32WrapMask;           /*!< Offset wrapping mask (Total capacity of the CCB - 1) */
+} UNCACHED_ALIGN RGXFWIF_CCCB_CTL;
+
+typedef enum 
+{
+       RGXFW_LOCAL_FREELIST = 0,
+       RGXFW_GLOBAL_FREELIST = 1,
+#if defined(SUPPORT_MMU_FREELIST)
+       RGXFW_MMU_FREELIST = 2,
+#endif
+       RGXFW_MAX_FREELISTS
+} RGXFW_FREELIST_TYPE;
+
+typedef struct _RGXFWIF_RTA_CTL_
+{
+       IMG_UINT32                              ui32RenderTargetIndex;          //Render number
+       IMG_UINT32                              ui32CurrentRenderTarget;        //index in RTA
+       IMG_UINT32                              ui32ActiveRenderTargets;        //total active RTs
+       IMG_UINT32                              ui32CumulActiveRenderTargets;   //total active RTs from the first TA kick, for OOM
+#if defined(RGX_FIRMWARE)
+       IMG_UINT32                              *paui32ValidRenderTargets;      //Array of valid RT indices
+       IMG_UINT32                              *paui32NumRenders;  //Array of number of occurred partial renders per render target
+#else
+       RGXFWIF_DEV_VIRTADDR                    paui32ValidRenderTargets;  //Array of valid RT indices
+       RGXFWIF_DEV_VIRTADDR                    paui32NumRenders;  //Array of number of occurred partial renders per render target
+#endif
+       IMG_UINT16                              ui16MaxRTs;   //Number of render targets in the array
+} UNCACHED_ALIGN RGXFWIF_RTA_CTL;
+
+typedef struct _RGXFWIF_FREELIST_
+{
+       IMG_DEV_VIRTADDR        RGXFW_ALIGN psFreeListDevVAddr;
+       IMG_UINT64                      RGXFW_ALIGN ui64CurrentDevVAddr;
+       IMG_UINT32                      ui32CurrentStackTop;
+       IMG_UINT32                      ui32MaxPages;
+       IMG_UINT32                      ui32GrowPages;
+       IMG_UINT32                      ui32CurrentPages;
+       IMG_UINT32                      ui32AllocatedPageCount;
+       IMG_UINT32                      ui32AllocatedMMUPageCount;
+       IMG_UINT32                      ui32HWRCounter;
+       IMG_UINT32                      ui32FreeListID;
+       IMG_BOOL                        bGrowPending;
+} UNCACHED_ALIGN RGXFWIF_FREELIST;
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+typedef enum 
+{
+       RGXFW_RPM_SHF_FREELIST = 0,
+       RGXFW_RPM_SHG_FREELIST = 1,
+} RGXFW_RPM_FREELIST_TYPE;
+
+#define                RGXFW_MAX_RPM_FREELISTS         (2)
+
+typedef struct _RGXFWIF_RPM_FREELIST_
+{
+       IMG_DEV_VIRTADDR        RGXFW_ALIGN sFreeListDevVAddr;          /*!< device base address */
+       IMG_DEV_VIRTADDR        RGXFW_ALIGN sRPMPageListDevVAddr;       /*!< device base address for RPM pages in-use */
+       IMG_UINT32                      sSyncAddr;                              /*!< Free list sync object for OOM event */
+       IMG_UINT32                      ui32MaxPages;                   /*!< maximum size */
+       IMG_UINT32                      ui32GrowPages;                  /*!< grow size = maximum pages which may be added later */
+       IMG_UINT32                      ui32CurrentPages;               /*!< number of pages */
+       IMG_UINT32                      ui32ReadOffset;                 /*!< head: where to read alloc'd pages */
+       IMG_UINT32                      ui32WriteOffset;                /*!< tail: where to write de-alloc'd pages */
+       IMG_BOOL                        bReadToggle;                    /*!< toggle bit for circular buffer */
+       IMG_BOOL                        bWriteToggle;
+       IMG_UINT32                      ui32AllocatedPageCount; /*!< TODO: not sure yet if this is useful */
+       IMG_UINT32                      ui32HWRCounter;
+       IMG_UINT32                      ui32FreeListID;                 /*!< unique ID per device, e.g. rolling counter */
+       IMG_BOOL                        bGrowPending;                   /*!< FW is waiting for host to grow the freelist */
+} UNCACHED_ALIGN RGXFWIF_RPM_FREELIST;
+
+typedef struct _RGXFWIF_RAY_FRAME_DATA_
+{
+       /* state manager for shared state between vertex and ray processing */
+       
+       /* TODO: not sure if this will be useful, link it here for now */
+       IMG_UINT32              sRPMFreeLists[RGXFW_MAX_RPM_FREELISTS];
+       
+       IMG_BOOL                bAbortOccurred;
+       
+       /* cleanup state.
+        * Both the SHG and RTU must complete or discard any outstanding work
+        * which references this frame data.
+        */
+       RGXFWIF_CLEANUP_CTL             sCleanupStateSHG;
+       RGXFWIF_CLEANUP_CTL             sCleanupStateRTU;
+       IMG_UINT32                              ui32CleanupStatus;
+#define HWFRAMEDATA_SHG_CLEAN  (1 << 0)
+#define HWFRAMEDATA_RTU_CLEAN  (1 << 1)
+
+} UNCACHED_ALIGN RGXFWIF_RAY_FRAME_DATA;
+#endif
+
+typedef struct _RGXFWIF_RENDER_TARGET_
+{
+       IMG_DEV_VIRTADDR        RGXFW_ALIGN psVHeapTableDevVAddr; /*!< VHeap Data Store */
+       IMG_BOOL                        bTACachesNeedZeroing;                     /*!< Whether RTC and TPC caches (on mem) need to be zeroed on next first TA kick */
+
+} UNCACHED_ALIGN RGXFWIF_RENDER_TARGET;
+
+
+typedef struct _RGXFWIF_HWRTDATA_ 
+{
+       RGXFWIF_RTDATA_STATE    eState;
+
+       IMG_UINT32                              ui32NumPartialRenders; /*!< Number of partial renders. Used to setup ZLS bits correctly */
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN psPMMListDevVAddr; /*!< MList Data Store */
+
+#if defined(RGX_FEATURE_SCALABLE_TE_ARCH)
+       IMG_UINT64                              RGXFW_ALIGN ui64VCECatBase[4];
+       IMG_UINT64                              RGXFW_ALIGN ui64VCELastCatBase[4];
+       IMG_UINT64                              RGXFW_ALIGN ui64TECatBase[4];
+       IMG_UINT64                              RGXFW_ALIGN ui64TELastCatBase[4];
+#else
+       IMG_UINT64                              RGXFW_ALIGN ui64VCECatBase;
+       IMG_UINT64                              RGXFW_ALIGN ui64VCELastCatBase;
+       IMG_UINT64                              RGXFW_ALIGN ui64TECatBase;
+       IMG_UINT64                              RGXFW_ALIGN ui64TELastCatBase;
+#endif
+       IMG_UINT64                              RGXFW_ALIGN ui64AlistCatBase;
+       IMG_UINT64                              RGXFW_ALIGN ui64AlistLastCatBase;
+
+#if defined(SUPPORT_VFP)
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sVFPPageTableAddr;
+#endif
+       IMG_UINT64                              RGXFW_ALIGN ui64PMAListStackPointer;
+       IMG_UINT32                              ui32PMMListStackPointer;
+
+       PRGXFWIF_FREELIST               RGXFW_ALIGN apsFreeLists[RGXFW_MAX_FREELISTS]; 
+       IMG_UINT32                              aui32FreeListHWRSnapshot[RGXFW_MAX_FREELISTS];
+       
+       PRGXFWIF_RENDER_TARGET  psParentRenderTarget;
+
+       RGXFWIF_CLEANUP_CTL             sTACleanupState;
+       RGXFWIF_CLEANUP_CTL             s3DCleanupState;
+       IMG_UINT32                              ui32CleanupStatus;
+#define HWRTDATA_TA_CLEAN      (1 << 0)
+#define HWRTDATA_3D_CLEAN      (1 << 1)
+
+       PRGXFWIF_RTA_CTL                psRTACtl;
+
+       IMG_UINT32                              bHasLastTA;
+       IMG_BOOL                                bPartialRendered;
+
+       IMG_UINT32                              ui32PPPScreen;
+       IMG_UINT32                              ui32PPPGridOffset;
+       IMG_UINT64                              RGXFW_ALIGN ui64PPPMultiSampleCtl;
+       IMG_UINT32                              ui32TPCStride;
+       IMG_DEV_VIRTADDR                RGXFW_ALIGN sTailPtrsDevVAddr;
+       IMG_UINT32                              ui32TPCSize;
+       IMG_UINT32                              ui32TEScreen;
+       IMG_UINT32                              ui32MTileStride;
+       IMG_UINT32                              ui32TEAA;
+       IMG_UINT32                              ui32TEMTILE1;
+       IMG_UINT32                              ui32TEMTILE2;
+       IMG_UINT32                              ui32ISPMergeLowerX;
+       IMG_UINT32                              ui32ISPMergeLowerY;
+       IMG_UINT32                              ui32ISPMergeUpperX;
+       IMG_UINT32                              ui32ISPMergeUpperY;
+       IMG_UINT32                              ui32ISPMergeScaleX;
+       IMG_UINT32                              ui32ISPMergeScaleY;
+} UNCACHED_ALIGN RGXFWIF_HWRTDATA;
+
+typedef enum
+{
+       RGXFWIF_ZSBUFFER_UNBACKED = 0,
+       RGXFWIF_ZSBUFFER_BACKED,
+       RGXFWIF_ZSBUFFER_BACKING_PENDING,
+       RGXFWIF_ZSBUFFER_UNBACKING_PENDING,
+}RGXFWIF_ZSBUFFER_STATE;
+
+typedef struct _RGXFWIF_ZSBUFFER_
+{
+       IMG_UINT32                              ui32ZSBufferID;                         /*!< Buffer ID*/
+       IMG_BOOL                                bOnDemand;                                      /*!< Needs On-demand ZS Buffer allocation */
+       RGXFWIF_ZSBUFFER_STATE  eState;                                         /*!< Z/S-Buffer state */
+       RGXFWIF_CLEANUP_CTL             sCleanupState;                          /*!< Cleanup state */
+} UNCACHED_ALIGN RGXFWIF_FWZSBUFFER;
+
+/* Number of BIF tiling configurations / heaps */
+#define RGXFWIF_NUM_BIF_TILING_CONFIGS 4
+
+/*!
+ *****************************************************************************
+ * RGX Compatibility checks
+ *****************************************************************************/
+/* WARNING: RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX can be increased only and
+               always equal to (N * sizeof(IMG_UINT32) - 1) */
+#define RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX 3 /* WARNING: Do not change this macro without changing 
+                       accesses from dword to byte in function rgx_bvnc_packed() */
+
+/* WARNING: Whenever the layout of RGXFWIF_COMPCHECKS_BVNC is a subject of change,
+       following define should be increased by 1 to indicate to compatibility logic, 
+       that layout has changed */
+#define RGXFWIF_COMPCHECKS_LAYOUT_VERSION 1
+
+typedef struct _RGXFWIF_COMPCHECKS_BVNC_
+{
+       IMG_UINT32      ui32LayoutVersion; /* WARNING: This field must be defined as first one in this structure */
+       IMG_UINT32  ui32VLenMax;
+       IMG_UINT32      ui32BNC;
+       IMG_CHAR        aszV[RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX + 1];
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS_BVNC;
+
+#define RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(name) RGXFWIF_COMPCHECKS_BVNC name = { RGXFWIF_COMPCHECKS_LAYOUT_VERSION, RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX }
+#define RGXFWIF_COMPCHECKS_BVNC_INIT(name) do { (name).ui32LayoutVersion = RGXFWIF_COMPCHECKS_LAYOUT_VERSION; \
+                                                                                               (name).ui32VLenMax = RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX; } while (0)
+
+typedef struct _RGXFWIF_COMPCHECKS_
+{
+       RGXFWIF_COMPCHECKS_BVNC         sHWBVNC;                        /*!< hardware BNC (from the RGX registers) */
+       RGXFWIF_COMPCHECKS_BVNC         sFWBVNC;                        /*!< firmware BNC */
+       IMG_UINT32                                      ui32METAVersion;
+       IMG_UINT32                                      ui32DDKVersion;         /*!< software DDK version */
+       IMG_UINT32                                      ui32DDKBuild;           /*!< software DDK build no. */
+       IMG_UINT32                                      ui32BuildOptions;       /*!< build options bit-field */
+       IMG_BOOL                                        bUpdated;                       /*!< Information is valid */
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS;
+
+
+#define GET_CCB_SPACE(WOff, ROff, CCBSize) \
+       ((((ROff) - (WOff)) + ((CCBSize) - 1)) & ((CCBSize) - 1))
+
+#define UPDATE_CCB_OFFSET(Off, PacketSize, CCBSize) \
+       (Off) = (((Off) + (PacketSize)) & ((CCBSize) - 1))
+
+#define RESERVED_CCB_SPACE             (sizeof(IMG_UINT32))
+
+
+/* Defines relating to the per-context CCBs */
+#define RGX_CCB_SIZE_LOG2                      (16) /* 64kB */
+#define RGX_CCB_ALLOCGRAN                      (64)
+#define RGX_CCB_TYPE_TASK                      (1 << 31)
+#define RGX_CCB_FWALLOC_ALIGN(size)    (((size) + (RGXFWIF_FWALLOC_ALIGN-1)) & ~(RGXFWIF_FWALLOC_ALIGN - 1))
+
+/*!
+ ******************************************************************************
+ * Client CCB commands for RGX
+ *****************************************************************************/
+typedef enum _RGXFWIF_CCB_CMD_TYPE_
+{
+       RGXFWIF_CCB_CMD_TYPE_TA                 = 201 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_3D                 = 202 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_CDM                = 203 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_TQ_3D              = 204 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_TQ_2D              = 205 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_3D_PR              = 206 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_NULL               = 207 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_SHG                = 208 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_RTU                = 209 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_RTU_FC               = 210 | RGX_CCB_TYPE_TASK,
+       RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP = 211 | RGX_CCB_TYPE_TASK,
+
+/* Leave a gap between CCB specific commands and generic commands */
+       RGXFWIF_CCB_CMD_TYPE_FENCE          = 212,
+       RGXFWIF_CCB_CMD_TYPE_UPDATE         = 213,
+       RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE     = 214,
+       RGXFWIF_CCB_CMD_TYPE_FENCE_PR       = 215,
+       RGXFWIF_CCB_CMD_TYPE_PRIORITY       = 216,
+/* Pre and Post timestamp commands are supposed to sandwich the DM cmd. The
+   padding code with the CCB wrap upsets the FW if we don't have the task type
+   bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types.
+*/
+       RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP = 217,
+       RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE = 218,
+       RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE = 219,
+       
+       RGXFWIF_CCB_CMD_TYPE_PADDING    = 220,
+} RGXFWIF_CCB_CMD_TYPE;
+
+typedef struct _RGXFWIF_CCB_CMD_HEADER_
+{
+       RGXFWIF_CCB_CMD_TYPE    eCmdType;
+       IMG_UINT32                              ui32CmdSize;
+} RGXFWIF_CCB_CMD_HEADER;
+
+typedef enum _RGXFWIF_PWR_EVT_
+{
+       RGXFWIF_PWR_EVT_PWR_ON,                 /* Sidekick power event */
+       RGXFWIF_PWR_EVT_DUST_CHANGE,            /* Rascal / dust power event */
+       RGXFWIF_PWR_EVT_ALL                     /* Applies to all power events. Keep as last element */
+} RGXFWIF_PWR_EVT;
+
+typedef struct _RGXFWIF_REG_CFG_REC_
+{
+       IMG_UINT64              ui64Addr;
+       IMG_UINT64              ui64Value;
+} RGXFWIF_REG_CFG_REC;
+
+
+typedef struct _RGXFWIF_TIME_CORR_
+{
+       IMG_UINT64 RGXFW_ALIGN ui64OSTimeStamp;
+       IMG_UINT64 RGXFW_ALIGN ui64CRTimeStamp;
+       IMG_UINT32             ui32CoreClockSpeed;
+
+       /* Utility variable used to convert CR timer deltas to OS timer deltas (nS),
+        * where the deltas are relative to the timestamps above:
+        * deltaOS = (deltaCR * K) >> decimal_shift, see full explanation below */
+       IMG_UINT32             ui32CRDeltaToOSDeltaKNs;
+} UNCACHED_ALIGN RGXFWIF_TIME_CORR;
+
+typedef struct _RGXFWIF_TIMESTAMP_
+{
+       RGXFWIF_TIME_CORR      sTimeCorr;
+       IMG_UINT64 RGXFW_ALIGN ui64Timestamp;
+} UNCACHED_ALIGN RGXFWIF_TIMESTAMP;
+
+
+/* These macros are used to help converting FW timestamps to the Host time domain.
+ * On the FW the RGX_CR_TIMER counter is used to keep track of the time;
+ * it increments by 1 every 256 GPU clock ticks, so the general formula
+ * to perform the conversion is:
+ *
+ * [ GPU clock speed in Hz, if (scale == 10^9) then deltaOS is in nS,
+ *   otherwise if (scale == 10^6) then deltaOS is in uS ]
+ *
+ *             deltaCR * 256                                   256 * scale
+ *  deltaOS = --------------- * scale = deltaCR * K    [ K = --------------- ]
+ *             GPUclockspeed                                  GPUclockspeed
+ *
+ * The actual K is multiplied by 2^20 (and deltaCR * K is divided by 2^20)
+ * to get some better accuracy and to avoid returning 0 in the integer
+ * division 256000000/GPUfreq if GPUfreq is greater than 256MHz.
+ * This is the same as keeping K as a decimal number.
+ *
+ * The maximum deltaOS is slightly more than 5hrs for all GPU frequencies
+ * (deltaCR * K is more or less a costant), and it's relative to
+ * the base OS timestamp sampled as a part of the timer correlation data.
+ * This base is refreshed on GPU power-on, DVFS transition and
+ * periodic frequency calibration (executed every few seconds if the FW is
+ * doing some work), so as long as the GPU is doing something and one of these
+ * events is triggered then deltaCR * K will not overflow and deltaOS will be
+ * correct.
+ */
+
+#define RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT  (20)
+
+#define RGXFWIF_GET_CRDELTA_TO_OSDELTA_K_NS(clockfreq, remainder) \
+       OSDivide64((256000000ULL << RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT), \
+                  ((clockfreq) + 500) / 1000, \
+                  &(remainder))
+
+#define RGXFWIF_GET_DELTA_OSTIME_NS(deltaCR, K) \
+       ( ((deltaCR) * (K)) >> RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT)
+
+#define RGXFWIF_GET_DELTA_OSTIME_US(deltacr, clockfreq, remainder) \
+       OSDivide64r64((deltacr) * 256000, ((clockfreq) + 500) / 1000, &(remainder))
+
+/* Use this macro to get a more realistic GPU core clock speed than
+ * the one given by the upper layers (used when doing GPU frequency
+ * calibration)
+ */
+#define RGXFWIF_GET_GPU_CLOCK_FREQUENCY_HZ(deltacr_us, deltaos_us, remainder) \
+       OSDivide64((deltacr_us) * 256000000, (deltaos_us), &(remainder))
+
+#endif /*  __RGX_FWIF_SHARED_H__ */
+
+/******************************************************************************
+ End of file (rgx_fwif_shared.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_pdump_panics.h b/drivers/gpu/rogue_m/services/include/rgx_pdump_panics.h
new file mode 100644 (file)
index 0000000..6bbe5b0
--- /dev/null
@@ -0,0 +1,67 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX PDump panic definitions header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX PDump panic definitions header
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (RGX_PDUMP_PANICS_H_)
+#define RGX_PDUMP_PANICS_H_
+
+
+/*! Unique device specific IMG_UINT16 panic IDs to identify the cause of a
+ * RGX PDump panic in a PDump script. */
+typedef enum
+{
+       RGX_PDUMP_PANIC_UNDEFINED = 0,
+
+       /* These panics occur when test parameters and driver configuration
+        * enable features that require the firmware and host driver to
+        * communicate. Such features are not supported with off-line playback.
+        */
+       RGX_PDUMP_PANIC_ZSBUFFER_BACKING         = 101, /*!< Requests ZSBuffer to be backed with physical pages */
+       RGX_PDUMP_PANIC_ZSBUFFER_UNBACKING       = 102, /*!< Requests ZSBuffer to be unbacked */
+       RGX_PDUMP_PANIC_FREELIST_GROW            = 103, /*!< Requests an on-demand freelist grow/shrink */
+       RGX_PDUMP_PANIC_FREELISTS_RECONSTRUCTION = 104, /*!< Requests freelists reconstruction */
+} RGX_PDUMP_PANIC;
+
+#endif /* RGX_PDUMP_PANICS_H_ */
+
+
diff --git a/drivers/gpu/rogue_m/services/include/rgx_tq_shared.h b/drivers/gpu/rogue_m/services/include/rgx_tq_shared.h
new file mode 100644 (file)
index 0000000..bd3460c
--- /dev/null
@@ -0,0 +1,63 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX transfer queue shared
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Shared definitions between client and server
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __RGX_TQ_SHARED_H__
+#define __RGX_TQ_SHARED_H__
+
+#define TQ_MAX_PREPARES_PER_SUBMIT             16
+
+#define TQ_PREP_FLAGS_COMMAND_3D               0x0
+#define TQ_PREP_FLAGS_COMMAND_2D               0x1
+#define TQ_PREP_FLAGS_COMMAND_MASK             (0xf)
+#define TQ_PREP_FLAGS_COMMAND_SHIFT            0
+#define TQ_PREP_FLAGS_PDUMPCONTINUOUS  (1 << 4)
+#define TQ_PREP_FLAGS_START                            (1 << 5)
+#define TQ_PREP_FLAGS_END                              (1 << 6)
+
+#define TQ_PREP_FLAGS_COMMAND_SET(m) \
+       ((TQ_PREP_FLAGS_COMMAND_##m << TQ_PREP_FLAGS_COMMAND_SHIFT) & TQ_PREP_FLAGS_COMMAND_MASK)
+
+#define TQ_PREP_FLAGS_COMMAND_IS(m,n) \
+       (((m & TQ_PREP_FLAGS_COMMAND_MASK) >> TQ_PREP_FLAGS_COMMAND_SHIFT)  == TQ_PREP_FLAGS_COMMAND_##n)
+
+#endif /* __RGX_TQ_SHARED_H__ */
diff --git a/drivers/gpu/rogue_m/services/include/rgxapi_km.h b/drivers/gpu/rogue_m/services/include/rgxapi_km.h
new file mode 100644 (file)
index 0000000..3079b44
--- /dev/null
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX API Header kernel mode
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Exported RGX API details
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __RGXAPI_KM_H__
+#define __RGXAPI_KM_H__
+
+#if defined(SUPPORT_SHARED_SLC)
+/*!
+******************************************************************************
+
+ @Function     RGXInitSLC
+
+ @Description Init the SLC after a power up. It is required to call this 
+              function if using SUPPORT_SHARED_SLC. Otherwise, it shouldn't
+                         be called.
+
+ @Input           hDevHandle : RGX Device Node
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXInitSLC(IMG_HANDLE hDevHandle);
+#endif
+
+#if defined(SUPPORT_KERNEL_HWPERF)
+
+#include "rgx_hwperf_km.h"
+
+
+/******************************************************************************
+ * RGX HW Performance Profiling Control API(s)
+ *****************************************************************************/
+
+/**************************************************************************/ /*!
+@Function      RGXHWPerfConnect
+@Description   Obtain a connection object to the HWPerf device
+@Output        phDevData      Address of a handle to a connection object
+@Return        PVRSRV_ERROR:  for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR RGXHWPerfConnect(
+               IMG_HANDLE* phDevData);
+
+
+/**************************************************************************/ /*!
+@Function       RGXHWPerfDisconnect
+@Description    Disconnect from the HWPerf device
+@Input          hSrvHandle    Handle to connection object as returned from
+                                RGXHWPerfConnect()
+@Return         PVRSRV_ERROR: for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR RGXHWPerfDisconnect(
+               IMG_HANDLE hDevData);
+
+
+/**************************************************************************/ /*!
+@Function       RGXHWPerfControl
+@Description    Enable or disable the generation of RGX HWPerf event packets.
+                 See RGXCtrlHWPerf().
+@Input          hDevData         Handle to connection object
+@Input          bToggle          Switch to toggle or apply mask.
+@Input          ui64Mask         Mask of events to control.
+@Return         PVRSRV_ERROR:    for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV RGXHWPerfControl(
+               IMG_HANDLE  hDevData,
+               IMG_BOOL    bToggle,
+               IMG_UINT64  ui64Mask);
+
+
+/**************************************************************************/ /*!
+@Function       RGXHWPerfConfigureAndEnableCounters
+@Description    Enable and configure the performance counter block for
+                 one or more device layout modules.
+                 See RGXConfigureAndEnableHWPerfCounters().
+@Input          hDevData         Handle to connection object
+@Input          ui32NumBlocks    Number of elements in the array
+@Input          asBlockConfigs   Address of the array of configuration blocks
+@Return         PVRSRV_ERROR:    for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV RGXHWPerfConfigureAndEnableCounters(
+               IMG_HANDLE                 hDevData,
+               IMG_UINT32                 ui32NumBlocks,
+               RGX_HWPERF_CONFIG_CNTBLK*  asBlockConfigs);
+
+
+/**************************************************************************/ /*!
+@Function       RGXDisableHWPerfCounters
+@Description    Disable the performance counter block for one or more
+                 device layout modules. See RGXDisableHWPerfCounters().
+@Input          hDevData        Handle to connection/device object
+@Input          ui32NumBlocks   Number of elements in the array
+@Input          aeBlockIDs      An array of bytes with values taken from
+                                 the RGX_HWPERF_CNTBLK_ID enumeration.
+@Return         PVRSRV_ERROR:   for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV RGXHWPerfDisableCounters(
+               IMG_HANDLE   hDevData,
+               IMG_UINT32   ui32NumBlocks,
+               IMG_UINT16*   aeBlockIDs);
+
+
+/******************************************************************************
+ * RGX HW Performance Profiling Retrieval API(s)
+ *
+ * The client must ensure their use of this acquire/release API for a single 
+ * connection/stream must not be shared with multiple execution contexts e.g.
+ * between a kernel thread and an ISR handler. It is the client’s
+ * responsibility to ensure this API is not interrupted by a high priority
+ * thread/ISR
+ *****************************************************************************/
+
+/**************************************************************************/ /*!
+@Function       RGXHWPerfAcquireData
+@Description    When there is data available to read this call returns with
+                 the address and length of the data buffer the
+                 client can safely read. This buffer may contain one or more
+                 event packets. If no data is available then this call 
+                                returns OK and sets *puiBufLen to 0 on exit.
+                                Clients must pair this call with a ReleaseData call.
+@Input          hDevData        Handle to connection/device object
+@Output         ppBuf           Address of a pointer to a byte buffer. On exit
+                                 it contains the address of buffer to read from
+@Output         puiBufLen       Pointer to an integer. On exit it is the size
+                                 of the data to read from the buffer
+@Return         PVRSRV_ERROR:   for system error codes
+*/ /***************************************************************************/
+PVRSRV_ERROR RGXHWPerfAcquireData(
+               IMG_HANDLE  hDevData,
+               IMG_PBYTE*  ppBuf,
+               IMG_UINT32* pui32BufLen);
+
+
+/**************************************************************************/ /*!
+@Function       RGXHWPerfReleaseData
+@Description    Called after client has read the event data out of the buffer
+                 retrieved from the Acquire Data call to release resources.
+@Input          hDevData        Handle to connection/device object
+@Return         PVRSRV_ERROR:   for system error codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR RGXHWPerfReleaseData(
+               IMG_HANDLE hDevData);
+
+
+#endif /* SUPPORT_KERNEL_HWPERF */
+
+
+#endif /* __RGXAPI_KM_H__ */
+
+/******************************************************************************
+ End of file (rgxapi_km.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/include/shared/allocmem.h b/drivers/gpu/rogue_m/services/include/shared/allocmem.h
new file mode 100644 (file)
index 0000000..1abd355
--- /dev/null
@@ -0,0 +1,81 @@
+/*************************************************************************/ /*!
+@File
+@Title          memory allocation header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Memory-Allocation API definitions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __ALLOCMEM_H__
+#define __ALLOCMEM_H__
+
+#include "img_types.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+IMG_PVOID OSAllocMem(IMG_UINT32 ui32Size);
+
+IMG_PVOID OSAllocMemstatMem(IMG_UINT32 ui32Size);
+
+IMG_PVOID OSAllocZMem(IMG_UINT32 ui32Size);
+
+IMG_PVOID OSAllocMemstatZMem(IMG_UINT32 ui32Size);
+
+IMG_VOID OSFreeMem(IMG_PVOID pvCpuVAddr);
+
+IMG_VOID OSFreeMemstatMem(IMG_PVOID pvCpuVAddr);
+
+#define OSFREEMEM(_ptr) do \
+       { OSFreeMem((_ptr)); \
+               (_ptr) = (IMG_VOID*)0; \
+               MSC_SUPPRESS_4127\
+       } while (0)
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __ALLOCMEM_H__ */
+
+/******************************************************************************
+ End of file (allocmem.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/include/shared/hash.h b/drivers/gpu/rogue_m/services/include/shared/hash.h
new file mode 100644 (file)
index 0000000..abacd69
--- /dev/null
@@ -0,0 +1,229 @@
+/*************************************************************************/ /*!
+@File
+@Title          Self scaling hash tables
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements simple self scaling hash tables.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _HASH_H_
+#define _HASH_H_
+
+/* include5/ */
+#include "img_types.h"
+
+/* services/client/include/ or services/server/include/ */
+#include "osfunc.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Keys passed to the comparsion function are only guaranteed to
+ * be aligned on an IMG_UINTPTR_T boundary. 
+ */
+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
+);
+
+/*************************************************************************/ /*!
+@Function       HASH_Func_Default
+@Description    Hash function intended for hashing keys composed of
+                IMG_UINTPTR_T arrays.
+@Input          uKeySize     The size of the hash key, in bytes.
+@Input          pKey         A pointer to the key to hash.
+@Input          uHashTabLen  The length of the hash table. 
+@Return         The hash value.
+*/ /**************************************************************************/
+IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+
+/*************************************************************************/ /*!
+@Function       HASH_Key_Comp_Default
+@Description    Compares keys composed of IMG_UINTPTR_T arrays.
+@Input          uKeySize     The size of the hash key, in bytes.
+@Input          pKey1        Pointer to first hash key to compare.
+@Input          pKey2        Pointer to second hash key to compare.
+@Return         IMG_TRUE  - the keys match.
+                IMG_FALSE - the keys don't match.
+*/ /**************************************************************************/
+IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+/*************************************************************************/ /*!
+@Function       HASH_Create_Extended
+@Description    Create a self scaling hash table, using the supplied
+                key size, and the supllied hash and key comparsion
+                functions.
+@Input          uInitialLen   Initial and minimum length of the
+                              hash table, where the length refers to the number
+                              of entries in the hash table, not its size in
+                              bytes.
+@Input          uKeySize      The size of the key, in bytes.
+@Input          pfnHashFunc   Pointer to hash function.
+@Input          pfnKeyComp    Pointer to key comparsion function.
+@Return         IMG_NULL or hash table handle.
+*/ /**************************************************************************/
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
+
+/*************************************************************************/ /*!
+@Function       HASH_Create
+@Description    Create a self scaling hash table with a key
+                consisting of a single IMG_UINTPTR_T, and using
+                the default hash and key comparison functions.
+@Input          uInitialLen   Initial and minimum length of the
+                              hash table, where the length refers to the
+                              number of entries in the hash table, not its size
+                              in bytes.
+@Return         IMG_NULL or hash table handle.
+*/ /**************************************************************************/
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
+
+/*************************************************************************/ /*!
+@Function       HASH_Delete
+@Description    Delete a hash table created by HASH_Create_Extended or
+                HASH_Create.  All entries in the table must have been
+                removed before calling this function.
+@Input          pHash         Hash table
+*/ /**************************************************************************/
+IMG_VOID HASH_Delete (HASH_TABLE *pHash);
+
+/*************************************************************************/ /*!
+@Function       HASH_Insert_Extended
+@Description    Insert a key value pair into a hash table created
+                with HASH_Create_Extended.
+@Input          pHash         The hash table.
+@Input          pKey          Pointer to the key.
+@Input          v             The value associated with the key.
+@Return         IMG_TRUE  - success
+                IMG_FALSE  - failure
+*/ /**************************************************************************/
+IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
+
+/*************************************************************************/ /*!
+@Function       HASH_Insert
+
+@Description    Insert a key value pair into a hash table created with
+                HASH_Create.
+@Input          pHash         The hash table.
+@Input          k             The key value.
+@Input          v             The value associated with the key.
+@Return         IMG_TRUE - success.
+                IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+
+/*************************************************************************/ /*!
+@Function       HASH_Remove_Extended
+@Description    Remove a key from a hash table created with
+                HASH_Create_Extended.
+@Input          pHash         The hash table.
+@Input          pKey          Pointer to key.
+@Return         0 if the key is missing, or the value associated
+                with the key.
+*/ /**************************************************************************/
+IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
+
+/*************************************************************************/ /*!
+@Function       HASH_Remove
+@Description    Remove a key value pair from a hash table created
+                with HASH_Create.
+@Input          pHash         The hash table.
+@Input          pKey          Pointer to key.
+@Return         0 if the key is missing, or the value associated
+                with the key.
+*/ /**************************************************************************/
+IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+/*************************************************************************/ /*!
+@Function       HASH_Retrieve_Extended
+@Description    Retrieve a value from a hash table created with
+                HASH_Create_Extended.
+@Input          pHash         The hash table.
+@Input          pKey          Pointer to key.
+@Return         0 if the key is missing, or the value associated with
+                the key.
+*/ /**************************************************************************/
+IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
+
+/*************************************************************************/ /*!
+@Function       HASH_Retrieve
+@Description    Retrieve a value from a hash table created with
+                HASH_Create.
+@Input          pHash         The hash table.
+@Input          pKey          Pointer to key.
+@Return         0 if the key is missing, or the value associated with
+                the key.
+*/ /**************************************************************************/
+IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+/*************************************************************************/ /*!
+@Function       HASH_Iterate
+@Description    Iterate over every entry in the hash table
+@Input          pHash                  Hash table to iterate
+@Input          pfnCallback            Callback to call with the key and data for
+                                                               each entry in the hash table
+@Return         Callback error if any, otherwise PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback);
+
+#ifdef HASH_TRACE
+/*************************************************************************/ /*!
+@Function       HASH_Dump
+@Description    Dump out some information about a hash table.
+@Input          pHash         The hash table.
+*/ /**************************************************************************/
+IMG_VOID HASH_Dump (HASH_TABLE *pHash);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* _HASH_H_ */
+
+/******************************************************************************
+ End of file (hash.h)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/include/shared/lock.h b/drivers/gpu/rogue_m/services/include/shared/lock.h
new file mode 100644 (file)
index 0000000..6353c28
--- /dev/null
@@ -0,0 +1,169 @@
+/*************************************************************************/ /*!
+@File           lock.h
+@Title          Locking interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Services internal locking interface
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _LOCK_H_
+#define _LOCK_H_
+
+/* In Linux kernel mode we are using the kernel mutex implementation directly
+ * with macros. This allows us to use the kernel lockdep feature for lock
+ * debugging. */
+#include "lock_types.h"
+
+#if defined(LINUX) && defined(__KERNEL__)
+
+#include "allocmem.h"
+#include <asm/atomic.h>
+
+#define OSLockCreate(phLock, eLockType) ({ \
+       PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \
+       *(phLock) = OSAllocMem(sizeof(struct mutex)); \
+       if (*(phLock)) { mutex_init(*(phLock)); e = PVRSRV_OK; }; \
+       e;})
+#define OSLockDestroy(hLock) ({mutex_destroy((hLock)); OSFreeMem((hLock)); PVRSRV_OK;})
+
+#define OSLockAcquire(hLock) ({mutex_lock((hLock)); PVRSRV_OK;})
+#define OSLockAcquireNested(hLock, subclass) ({mutex_lock_nested((hLock), (subclass)); PVRSRV_OK;})
+#define OSLockRelease(hLock) ({mutex_unlock((hLock)); PVRSRV_OK;})
+
+#define OSLockIsLocked(hLock) ({IMG_BOOL b = ((mutex_is_locked((hLock)) == 1) ? IMG_TRUE : IMG_FALSE); b;})
+#define OSTryLockAcquire(hLock) ({IMG_BOOL b = ((mutex_trylock(hLock) == 1) ? IMG_TRUE : IMG_FALSE); b;})
+
+/* These _may_ be reordered or optimized away entirely by the compiler/hw */
+#define OSAtomicRead(pCounter) ({IMG_INT rv = atomic_read(pCounter); rv;})
+#define OSAtomicWrite(pCounter, i)     ({ atomic_set(pCounter, i); })
+
+/* The following atomic operations, in addition to being SMP-safe, also
+   imply a memory barrier around the operation  */
+#define OSAtomicIncrement(pCounter)    ({IMG_INT rv = atomic_inc_return(pCounter); rv;})
+#define OSAtomicDecrement(pCounter) ({IMG_INT rv = atomic_dec_return(pCounter); rv;})
+#define OSAtomicCompareExchange(pCounter, oldv, newv) ({IMG_INT rv = atomic_cmpxchg(pCounter,oldv,newv); rv;})
+
+#define OSAtomicAdd(pCounter, incr) ({IMG_INT rv = atomic_add_return(incr,pCounter); rv;})
+#define OSAtomicAddUnless(pCounter, incr, test) ({IMG_INT rv = __atomic_add_unless(pCounter,incr,test); rv;})
+
+#define OSAtomicSubtract(pCounter, incr) ({IMG_INT rv = atomic_add_return(-(incr),pCounter); rv;})
+#define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), test)
+
+#else /* defined(LINUX) && defined(__KERNEL__) */
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+IMG_INTERNAL
+PVRSRV_ERROR OSLockCreate(POS_LOCK *phLock, LOCK_TYPE eLockType);
+
+IMG_INTERNAL
+IMG_VOID OSLockDestroy(POS_LOCK hLock);
+
+IMG_INTERNAL
+IMG_VOID OSLockAcquire(POS_LOCK hLock);
+
+/* Nested notation isn't used in UM or other OS's */
+#define OSLockAcquireNested(hLock, subclass) OSLockAcquire((hLock))
+
+IMG_INTERNAL
+IMG_VOID OSLockRelease(POS_LOCK hLock);
+
+IMG_INTERNAL
+IMG_BOOL OSLockIsLocked(POS_LOCK hLock);
+
+#if defined(LINUX)
+
+/* Use GCC intrinsics (read/write semantics consistent with kernel-side implementation) */
+#define OSAtomicRead(pCounter) ({IMG_INT rv =  *(volatile int *)&(pCounter)->counter; rv;}) 
+#define OSAtomicWrite(pCounter, i) ({(pCounter)->counter = (IMG_INT) i;}) 
+#define OSAtomicIncrement(pCounter) ({IMG_INT rv = __sync_add_and_fetch((&(pCounter)->counter), 1); rv;}) 
+#define OSAtomicDecrement(pCounter) ({IMG_INT rv = __sync_sub_and_fetch((&(pCounter)->counter), 1); rv;}) 
+#define OSAtomicCompareExchange(pCounter, oldv, newv)  \
+       ({IMG_INT rv = __sync_val_compare_and_swap((&(pCounter)->counter), oldv, newv); rv;})
+       
+#define OSAtomicAdd(pCounter, incr) ({IMG_INT rv = __sync_add_and_fetch((&(pCounter)->counter), incr); rv;}) 
+#define OSAtomicAddUnless(pCounter, incr, test) ({ \
+       int c; int old; \
+       c = OSAtomicRead(pCounter); \
+    while (1) { \
+               if (c == (test)) break; \
+               old = OSAtomicCompareExchange(pCounter, c, c+(incr)); \
+               if (old == c) break; \
+               c = old; \
+       } c; })
+
+#define OSAtomicSubtract(pCounter, incr) OSAtomicAdd(pCounter, -(incr))        
+#define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), test)
+
+#else
+
+/* These _may_ be reordered or optimized away entirely by the compiler/hw */
+IMG_INTERNAL
+IMG_INT OSAtomicRead(ATOMIC_T *pCounter);
+
+IMG_INTERNAL
+IMG_VOID OSAtomicWrite(ATOMIC_T *pCounter, IMG_INT v);
+
+/* For the following atomic operations, in addition to being SMP-safe, 
+   _should_ also  have a memory barrier around each operation  */
+IMG_INTERNAL
+IMG_INT OSAtomicIncrement(ATOMIC_T *pCounter);
+
+IMG_INTERNAL
+IMG_INT OSAtomicDecrement(ATOMIC_T *pCounter);
+
+IMG_INTERNAL
+IMG_INT OSAtomicAdd(ATOMIC_T *pCounter, IMG_INT v);
+
+IMG_INTERNAL
+IMG_INT OSAtomicAddUnless(ATOMIC_T *pCounter, IMG_INT v, IMG_INT t);
+
+IMG_INTERNAL
+IMG_INT OSAtomicSubtract(ATOMIC_T *pCounter, IMG_INT v);
+
+IMG_INTERNAL
+IMG_INT OSAtomicSubtractUnless(ATOMIC_T *pCounter, IMG_INT v, IMG_INT t);
+
+IMG_INTERNAL
+IMG_INT OSAtomicCompareExchange(ATOMIC_T *pCounter, IMG_INT oldv, IMG_INT newv);
+
+#endif /* defined(LINUX) */
+#endif /* defined(LINUX) && defined(__KERNEL__) */
+
+#endif /* _LOCK_H_ */
diff --git a/drivers/gpu/rogue_m/services/include/shared/ra.h b/drivers/gpu/rogue_m/services/include/shared/ra.h
new file mode 100644 (file)
index 0000000..99e45ff
--- /dev/null
@@ -0,0 +1,205 @@
+/*************************************************************************/ /*!
+@File
+@Title          Resource Allocator API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RA_H_
+#define _RA_H_
+
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/** Resource arena.
+ *  struct _RA_ARENA_ deliberately opaque
+ */
+typedef struct _RA_ARENA_ RA_ARENA;                    //PRQA S 3313
+
+/*
+ * Per-Arena handle - this is private data for the caller of the RA.
+ * The RA knows nothing about this data.  It is given it upon
+ * RA_Create, and promises to pass it to calls to the ImportAlloc and
+ * ImportFree callbacks
+ */
+typedef IMG_HANDLE RA_PERARENA_HANDLE;
+/*
+ * Per-Import handle - this is private data for the caller of the RA.
+ * The RA knows nothing about this data.  It is given it on a
+ * per-import basis, either the "initial" import at RA_Create time, or
+ * further imports via the ImportAlloc callback.  It sends it back via
+ * the ImportFree callback, and also provides it in answer to any
+ * RA_Alloc request to signify from which "import" the allocation came
+ */
+typedef IMG_HANDLE RA_PERISPAN_HANDLE;
+
+typedef IMG_UINT64 RA_BASE_T;
+typedef IMG_UINT32 RA_LOG2QUANTUM_T;
+typedef IMG_UINT64 RA_LENGTH_T;
+
+/* Lock classes: describes the level of nesting between different arenas. */
+#define RA_LOCKCLASS_0 0
+#define RA_LOCKCLASS_1 1
+#define RA_LOCKCLASS_2 2
+
+/*
+ * Flags in an "import" must much the flags for an allocation
+ */
+typedef IMG_UINT32 RA_FLAGS_T;
+
+struct _RA_SEGMENT_DETAILS_
+{
+       RA_LENGTH_T      uiSize;
+       IMG_CPU_PHYADDR sCpuPhyAddr;
+       IMG_HANDLE      hSegment;
+};
+typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
+
+/**
+ *  @Function   RA_Create
+ *
+ *  @Description
+ *
+ *  To create a resource arena.
+ *
+ *  @Input name - the name of the arena for diagnostic purposes.
+ *  @Input uQuantum - the arena allocation quantum.
+ *  @Input ui32LockClass - the lock class level this arena uses.
+ *  @Input alloc - a resource allocation callback or 0.
+ *  @Input free - a resource de-allocation callback or 0.
+ *  @Input per_arena_handle - user private handle passed to alloc and free or 0.
+ *  @Input bNoSplit - Disable splitting up imports.
+ *  @Return pointer to arena, or IMG_NULL.
+ */
+RA_ARENA *
+RA_Create (IMG_CHAR *name,
+           /* subsequent imports: */
+           RA_LOG2QUANTUM_T uLog2Quantum,
+                  IMG_UINT32 ui32LockClass,
+           IMG_BOOL (*imp_alloc)(RA_PERARENA_HANDLE _h,
+                                 RA_LENGTH_T uSize,
+                                 RA_FLAGS_T uFlags,
+                                 RA_BASE_T *pBase,
+                                 RA_LENGTH_T *pActualSize,
+                                 RA_PERISPAN_HANDLE *phPriv),
+           IMG_VOID (*imp_free) (RA_PERARENA_HANDLE,
+                                 RA_BASE_T,
+                                 RA_PERISPAN_HANDLE),
+           RA_PERARENA_HANDLE per_arena_handle,
+                  IMG_BOOL bNoSplit);
+
+/**
+ *  @Function   RA_Delete
+ *
+ *  @Description
+ *
+ *  To delete a resource arena. All resources allocated from the arena
+ *  must be freed before deleting the arena.
+ *                  
+ *  @Input  pArena - the arena to delete.
+ *  @Return None
+ */
+IMG_VOID
+RA_Delete (RA_ARENA *pArena);
+
+/**
+ *  @Function   RA_Add
+ *
+ *  @Description
+ *
+ *  To add a resource span to an arena. The span must not overlap with
+ *  any span previously added to the arena.
+ *
+ *  @Input pArena - the arena to add a span into.
+ *  @Input base - the base of the span.
+ *  @Input uSize - the extent of the span.
+ *  @Input hPriv - handle associated to the span (reserved to user uses)
+ *  @Return IMG_TRUE - success, IMG_FALSE - failure
+ */
+IMG_BOOL
+RA_Add (RA_ARENA *pArena,
+               RA_BASE_T base,
+               RA_LENGTH_T uSize,
+               RA_FLAGS_T uFlags,
+               RA_PERISPAN_HANDLE hPriv);
+
+/**
+ *  @Function   RA_Alloc
+ *
+ *  @Description
+ *
+ *  To allocate resource from an arena.
+ *
+ *  @Input  pArena - the arena
+ *  @Input  uRequestSize - the size of resource segment requested.
+ *  @Output pActualSize - the actual_size of resource segment allocated,
+ *          typcially rounded up by quantum.
+ *  @Input  uFlags - flags influencing allocation policy.
+ *  @Input  uAlignment - the alignment constraint required for the
+ *          allocated segment, use 0 if alignment not required.
+ *  @Output pBase - allocated base resource
+ *  @Output phPriv - the user reference associated with allocated
+ *          resource span.
+ *  @Return IMG_TRUE - success, IMG_FALSE - failure
+ */
+IMG_BOOL
+RA_Alloc (RA_ARENA *pArena, 
+          RA_LENGTH_T uSize,
+          RA_FLAGS_T uFlags,
+          RA_LENGTH_T uAlignment,
+          RA_BASE_T *pBase,
+          RA_LENGTH_T *pActualSize,
+          RA_PERISPAN_HANDLE *phPriv);
+
+/**
+ *  @Function   RA_Free
+ *
+ *  @Description    To free a resource segment.
+ *  
+ *  @Input  pArena - the arena the segment was originally allocated from.
+ *  @Input  base - the base of the resource span to free.
+ *     @Input  bFreeBackingStore - Should backing store memory be freed?
+ *
+ *  @Return None
+ */
+IMG_VOID 
+RA_Free (RA_ARENA *pArena, RA_BASE_T base);
+
+#endif
+
diff --git a/drivers/gpu/rogue_m/services/server/common/cache_generic.c b/drivers/gpu/rogue_m/services/server/common/cache_generic.c
new file mode 100644 (file)
index 0000000..25f2dba
--- /dev/null
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Title          CPU generic cache management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements server side code for CPU cache management in a
+                CPU agnostic manner.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "cache_generic.h"
+#include "cache_internal.h"
+#include "device.h"
+#include "pvr_debug.h"
+#include "pvrsrv.h"
+#include "osfunc.h"
+#include "pmr.h"
+
+PVRSRV_ERROR CacheOpQueue(PVRSRV_CACHE_OP uiCacheOp)
+{
+       PVRSRV_DATA *psData = PVRSRVGetPVRSRVData();
+
+       psData->uiCacheOp = SetCacheOp(psData->uiCacheOp, uiCacheOp);
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/connection_server.c b/drivers/gpu/rogue_m/services/server/common/connection_server.c
new file mode 100644 (file)
index 0000000..c9b44d1
--- /dev/null
@@ -0,0 +1,297 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server side connection management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Handles connections coming from the client and the management
+                connection based information
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "handle.h"
+#include "pvrsrv.h"
+#include "connection_server.h"
+#include "osconnection_server.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "sync_server.h"
+#include "process_stats.h"
+#include "pdump_km.h"
+#include "lists.h"
+
+/* PID associated with Connection currently being purged by Cleanup thread */
+static IMG_PID gCurrentPurgeConnectionPid = 0;
+
+static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection)
+{
+       PVRSRV_ERROR eError;
+
+       if (psConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "ConnectionDestroy: Missing connection!"));
+               PVR_ASSERT(0);
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Close the process statistics */
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       if (psConnection->hProcessStats != IMG_NULL)
+       {
+               PVRSRVStatsDeregisterProcess(psConnection->hProcessStats);
+               psConnection->hProcessStats = IMG_NULL;
+       }
+#endif
+
+       /* Free handle base for this connection */
+       if (psConnection->psHandleBase != IMG_NULL)
+       {
+               PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+               IMG_UINT64 ui64MaxBridgeTime;
+
+               if(psPVRSRVData->bUnload)
+               {
+                       /* driver is unloading so do not allow the bridge lock to be released */
+                       ui64MaxBridgeTime = 0;
+               }
+               else
+               {
+                       ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
+               }
+
+               eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime);
+               if (eError != PVRSRV_OK)
+               {
+                       if (eError != PVRSRV_ERROR_RETRY)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                        "ConnectionDataDestroy: Couldn't free handle base for connection (%d)",
+                                        eError));
+                       }
+
+                       return eError;
+               }
+
+               psConnection->psHandleBase = IMG_NULL;
+       }
+
+       if (psConnection->psSyncConnectionData != IMG_NULL)
+       {
+               SyncUnregisterConnection(psConnection->psSyncConnectionData);
+               psConnection->psSyncConnectionData = IMG_NULL;
+       }
+
+       if (psConnection->psPDumpConnectionData != IMG_NULL)
+       {
+               PDumpUnregisterConnection(psConnection->psPDumpConnectionData);
+               psConnection->psPDumpConnectionData = IMG_NULL;
+       }
+
+       /* Call environment specific connection data deinit function */
+       if (psConnection->hOsPrivateData != IMG_NULL)
+       {
+               eError = OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                "PVRSRVConnectionDataDestroy: OSConnectionPrivateDataDeInit failed (%d)",
+                                eError));
+
+                       return eError;
+               }
+
+               psConnection->hOsPrivateData = IMG_NULL;
+       }
+
+       OSFreeMem(psConnection);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVConnectionConnect(IMG_PVOID *ppvPrivData, IMG_PVOID pvOSData)
+{
+       CONNECTION_DATA *psConnection;
+       PVRSRV_ERROR eError;
+
+       /* Allocate connection data area */
+       psConnection = OSAllocZMem(sizeof(*psConnection));
+       if (psConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVConnectionConnect: Couldn't allocate connection data"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* Call environment specific connection data init function */
+       eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData);
+       if (eError != PVRSRV_OK)
+       {
+                PVR_DPF((PVR_DBG_ERROR,
+                         "PVRSRVConnectionConnect: OSConnectionPrivateDataInit failed (%d)",
+                         eError));
+               goto failure;
+       }
+
+       psConnection->pid = OSGetCurrentProcessID();
+
+       /* Register this connection with the sync core */
+       eError = SyncRegisterConnection(&psConnection->psSyncConnectionData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVConnectionConnect: Couldn't register the sync data"));
+               goto failure;
+       }
+
+       /*
+        * Register this connection with the pdump core. Pass in the sync connection data
+        * as it will be needed later when we only get passed in the PDump connection data.
+        */
+       eError = PDumpRegisterConnection(psConnection->psSyncConnectionData,
+                                        &psConnection->psPDumpConnectionData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVConnectionConnect: Couldn't register the PDump data"));
+               goto failure;
+       }
+
+       /* Allocate handle base for this connection */
+       eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVConnectionConnect: Couldn't allocate handle base for connection (%d)",
+                        eError));
+               goto failure;
+       }
+
+       /* Allocate process statistics */
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVConnectionConnect: Couldn't register process statistics (%d)",
+                        eError));
+               goto failure;
+       }
+#endif
+
+       *ppvPrivData = psConnection;
+
+       return eError;
+
+failure:
+       ConnectionDataDestroy(psConnection);
+
+       return eError;
+}
+
+static PVRSRV_ERROR _CleanupThreadPurgeConnectionData(void *pvConnectionData)
+{
+       PVRSRV_ERROR eErrorConnection, eErrorKernel;
+       CONNECTION_DATA *psConnectionData = pvConnectionData;
+
+       OSAcquireBridgeLock();
+
+       gCurrentPurgeConnectionPid = psConnectionData->pid;
+
+       eErrorConnection = ConnectionDataDestroy(psConnectionData);
+       if (eErrorConnection != PVRSRV_OK)
+       {
+               if (eErrorConnection == PVRSRV_ERROR_RETRY)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE,
+                                "_CleanupThreadPurgeConnectionData: Failed to purge connection data %p "
+                                "(deferring destruction)",
+                                psConnectionData));
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE,
+                        "_CleanupThreadPurgeConnectionData: Connection data %p deferred destruction finished",
+                        psConnectionData));
+       }
+
+       /* Check if possible resize the global handle base */
+       eErrorKernel = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
+       if (eErrorKernel != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "_CleanupThreadPurgeConnectionData: Purge of global handle pool failed (%d)",
+                        eErrorKernel));
+       }
+
+       gCurrentPurgeConnectionPid = 0;
+
+       OSReleaseBridgeLock();
+
+       return eErrorConnection;
+}
+
+void PVRSRVConnectionDisconnect(void *pvDataPtr)
+{
+       CONNECTION_DATA *psConnectionData = pvDataPtr;
+
+       /* Notify the PDump core if the pdump control client is disconnecting */
+       if (psConnectionData->ui32ClientFlags & SRV_FLAGS_PDUMPCTRL)
+       {
+               PDumpDisconnectionNotify();
+       }
+
+       /* Defer the release of the connection data */
+       psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
+       psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
+       psConnectionData->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
+       PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
+}
+
+PVRSRV_ERROR PVRSRVConnectionInit(void)
+{
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVConnectionDeInit(void)
+{
+       return PVRSRV_OK;
+}
+
+IMG_PID PVRSRVGetPurgeConnectionPid(void)
+{
+       return gCurrentPurgeConnectionPid;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/devicemem_heapcfg.c b/drivers/gpu/rogue_m/services/server/common/devicemem_heapcfg.c
new file mode 100644 (file)
index 0000000..6c86b8d
--- /dev/null
@@ -0,0 +1,135 @@
+/*************************************************************************/ /*!
+@File           devicemem_heapcfg.c
+@Title          Temporary Device Memory 2 stuff
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device memory management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+/* our exported API */
+#include "devicemem_heapcfg.h"
+
+#include "device.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+
+
+PVRSRV_ERROR
+HeapCfgHeapConfigCount(
+    const PVRSRV_DEVICE_NODE *psDeviceNode,
+    IMG_UINT32 *puiNumHeapConfigsOut
+)
+{
+
+    *puiNumHeapConfigsOut = psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+HeapCfgHeapCount(
+    const PVRSRV_DEVICE_NODE *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 *puiNumHeapsOut
+)
+{
+    if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+    {
+        return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+    }
+
+    *puiNumHeapsOut = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+HeapCfgHeapConfigName(
+    const PVRSRV_DEVICE_NODE *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 uiHeapConfigNameBufSz,
+    IMG_CHAR *pszHeapConfigNameOut
+)
+{
+    if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+    {
+        return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+    }
+
+    OSSNPrintf(pszHeapConfigNameOut, uiHeapConfigNameBufSz, "%s", psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].pszName);
+
+    return PVRSRV_OK;    
+}
+
+PVRSRV_ERROR
+HeapCfgHeapDetails(
+    const PVRSRV_DEVICE_NODE *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 uiHeapIndex,
+    IMG_UINT32 uiHeapNameBufSz,
+    IMG_CHAR *pszHeapNameOut,
+    IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+    IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+    IMG_UINT32 *puiLog2DataPageSizeOut,
+    IMG_UINT32 *puiLog2ImportAlignmentOut
+)
+{
+    DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint;
+
+    if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+    {
+        return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+    }
+
+    if (uiHeapIndex >= psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps)
+    {
+        return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX;
+    }
+
+    psHeapBlueprint = &psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].psHeapBlueprintArray[uiHeapIndex];
+
+    OSSNPrintf(pszHeapNameOut, uiHeapNameBufSz, "%s", psHeapBlueprint->pszName);
+    *psDevVAddrBaseOut = psHeapBlueprint->sHeapBaseAddr;
+    *puiHeapLengthOut = psHeapBlueprint->uiHeapLength;
+    *puiLog2DataPageSizeOut = psHeapBlueprint->uiLog2DataPageSize;
+    *puiLog2ImportAlignmentOut = psHeapBlueprint->uiLog2ImportAlignment;
+
+    return PVRSRV_OK;    
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/devicemem_history_server.c b/drivers/gpu/rogue_m/services/server/common/devicemem_history_server.c
new file mode 100644 (file)
index 0000000..0ac171d
--- /dev/null
@@ -0,0 +1,225 @@
+/*************************************************************************/ /*!
+@File
+@Title          Devicemem history functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Devicemem history functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "allocmem.h"
+#include "pmr.h"
+#include "pvrsrv.h"
+#include "pvrsrv_device.h"
+#include "pvr_debug.h"
+#include "dllist.h"
+#include "syscommon.h"
+#include "devicemem_server.h"
+#include "lock.h"
+#include "devicemem_history_server.h"
+
+/* a device memory allocation */
+typedef struct _DEVICEMEM_HISTORY_ALLOCATION_
+{
+       IMG_DEV_VIRTADDR sDevVAddr;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ];
+       IMG_UINT64 ui64Time;
+       /* FALSE if this allocation has been freed */
+       IMG_BOOL bAllocated;
+       IMG_PID uiPID;
+} DEVICEMEM_HISTORY_ALLOCATION;
+
+/* this number of entries makes the history buffer allocation just under 2MB */
+#define DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN 29127
+
+typedef struct _DEVICEMEM_HISTORY_DATA_
+{
+       IMG_UINT32 ui32Head;
+       DEVICEMEM_HISTORY_ALLOCATION *psAllocations;
+       POS_LOCK hLock;
+} DEVICEMEM_HISTORY_DATA;
+
+static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData = { 0 };
+
+static INLINE IMG_VOID DevicememHistoryLock(IMG_VOID)
+{
+       OSLockAcquire(gsDevicememHistoryData.hLock);
+}
+
+static INLINE IMG_VOID DevicememHistoryUnlock(IMG_VOID)
+{
+       OSLockRelease(gsDevicememHistoryData.hLock);
+}
+
+PVRSRV_ERROR DevicememHistoryInitKM(IMG_VOID)
+{
+       PVRSRV_ERROR eError;
+
+       eError = OSLockCreate(&gsDevicememHistoryData.hLock, LOCK_TYPE_PASSIVE);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to create lock"));
+               goto err_lock;
+       }
+
+       gsDevicememHistoryData.psAllocations = OSAllocZMem(sizeof(DEVICEMEM_HISTORY_ALLOCATION) * DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN);
+
+       if(gsDevicememHistoryData.psAllocations == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to allocate space for allocations list"));
+               goto err_allocations;
+       }
+
+       return PVRSRV_OK;
+
+err_allocations:
+       OSLockDestroy(gsDevicememHistoryData.hLock);
+err_lock:
+       return eError;
+}
+
+IMG_VOID DevicememHistoryDeInitKM(IMG_VOID)
+{
+       OSFREEMEM(gsDevicememHistoryData.psAllocations);
+       OSLockDestroy(gsDevicememHistoryData.hLock);
+}
+
+static PVRSRV_ERROR DevicememHistoryWrite(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize,
+                                               const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+                                               IMG_BOOL bAlloc)
+{
+       DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
+
+       PVR_ASSERT(gsDevicememHistoryData.psAllocations != IMG_NULL);
+
+       DevicememHistoryLock();
+
+       psAlloc = &gsDevicememHistoryData.psAllocations[gsDevicememHistoryData.ui32Head];
+       PVR_ASSERT(gsDevicememHistoryData.ui32Head < DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN);
+
+       gsDevicememHistoryData.ui32Head = (gsDevicememHistoryData.ui32Head + 1) % DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN;
+
+       psAlloc->sDevVAddr = sDevVAddr;
+       psAlloc->uiSize = uiSize;
+       psAlloc->uiPID = OSGetCurrentProcessID();
+       OSStringNCopy(psAlloc->szString, szString, sizeof(psAlloc->szString));
+       psAlloc->szString[sizeof(psAlloc->szString) - 1] = '\0';
+       psAlloc->bAllocated = bAlloc;
+       psAlloc->ui64Time = OSClockns64();
+
+       DevicememHistoryUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR DevicememHistoryMapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ])
+{
+       return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_TRUE);
+}
+
+PVRSRV_ERROR DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ])
+{
+       return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_FALSE);
+}
+
+/* given a time stamp, calculate the age in nanoseconds (relative to now) */
+static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Then)
+{
+       IMG_UINT64 ui64Now;
+
+       ui64Now = OSClockns64();
+
+       if(ui64Now >= ui64Then)
+       {
+               /* no clock wrap */
+               return ui64Now - ui64Then;
+       }
+       else
+       {
+               /* clock has wrapped */
+               return ((~(IMG_UINT64) 0) - ui64Then) + ui64Now + 1;
+       }
+}
+
+IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut)
+{
+       IMG_UINT32 ui32Entry;
+
+       /* initialise the results count for the caller */
+       psQueryOut->ui32NumResults = 0;
+
+       DevicememHistoryLock();
+
+       /* search from newest to oldest */
+
+       ui32Entry = gsDevicememHistoryData.ui32Head;
+
+       do
+       {
+               DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
+
+               /* searching backwards (from newest to oldest)
+                * wrap around backwards when going past zero
+                */
+               ui32Entry = (ui32Entry != 0) ? ui32Entry - 1 : DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN - 1;
+               psAlloc = &gsDevicememHistoryData.psAllocations[ui32Entry];
+
+               if((psAlloc->uiPID == psQueryIn->uiPID) &&
+                       (psQueryIn->sDevVAddr.uiAddr >= psAlloc->sDevVAddr.uiAddr) &&
+                       (psQueryIn->sDevVAddr.uiAddr < psAlloc->sDevVAddr.uiAddr + psAlloc->uiSize))
+               {
+                               DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults];
+
+                               OSStringNCopy(psResult->szString, psAlloc->szString, sizeof(psResult->szString));
+                               psResult->szString[DEVICEMEM_HISTORY_TEXT_BUFSZ - 1] = '\0';
+                               psResult->sBaseDevVAddr = psAlloc->sDevVAddr;
+                               psResult->uiSize = psAlloc->uiSize;
+                               psResult->bAllocated = psAlloc->bAllocated;
+                               psResult->ui64Age = _CalculateAge(psAlloc->ui64Time);
+                               psResult->ui64When = psAlloc->ui64Time;
+
+                               psQueryOut->ui32NumResults++;
+               }
+       } while((psQueryOut->ui32NumResults < DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS) &&
+                                               (ui32Entry != gsDevicememHistoryData.ui32Head));
+
+       DevicememHistoryUnlock();
+
+       return psQueryOut->ui32NumResults > 0;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/devicemem_server.c b/drivers/gpu/rogue_m/services/server/common/devicemem_server.c
new file mode 100644 (file)
index 0000000..53ebd84
--- /dev/null
@@ -0,0 +1,732 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Server-side component of the Device Memory Management.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* our exported API */
+#include "devicemem_server.h"
+#include "devicemem_utils.h"
+#include "devicemem.h"
+
+#include "device.h" /* For device node */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "mmu_common.h"
+#include "pdump_km.h"
+#include "pmr.h"
+
+#include "allocmem.h"
+#include "osfunc.h"
+#include "lock.h"
+
+struct _DEVMEMINT_CTX_
+{
+    PVRSRV_DEVICE_NODE *psDevNode;
+
+    /* MMU common code needs to have a context.  There's a one-to-one
+       correspondence between device memory context and MMU context,
+       but we have the abstraction here so that we don't need to care
+       what the MMU does with its context, and the MMU code need not
+       know about us at all. */
+    MMU_CONTEXT *psMMUContext;
+
+    ATOMIC_T hRefCount;
+
+    /* This handle is for devices that require notification when a new
+       memory context is created and they need to store private data that
+       is associated with the context. */
+    IMG_HANDLE hPrivData;
+};
+
+struct _DEVMEMINT_CTX_EXPORT_ 
+{
+       DEVMEMINT_CTX *psDevmemCtx;
+};
+
+struct _DEVMEMINT_HEAP_
+{
+    struct _DEVMEMINT_CTX_ *psDevmemCtx;
+    ATOMIC_T hRefCount;
+};
+
+struct _DEVMEMINT_RESERVATION_
+{
+    struct _DEVMEMINT_HEAP_ *psDevmemHeap;
+    IMG_DEV_VIRTADDR sBase;
+    IMG_DEVMEM_SIZE_T uiLength;
+};
+
+struct _DEVMEMINT_MAPPING_
+{
+    struct _DEVMEMINT_RESERVATION_ *psReservation;
+    PMR *psPMR;
+    IMG_UINT32 uiNumPages;
+    IMG_UINT32 uiLog2PageSize;
+};
+
+/*************************************************************************/ /*!
+@Function       _DevmemIntCtxAcquire
+@Description    Acquire a reference to the provided device memory context.
+@Return         None
+*/ /**************************************************************************/
+static INLINE IMG_VOID _DevmemIntCtxAcquire(DEVMEMINT_CTX *psDevmemCtx)
+{
+       OSAtomicIncrement(&psDevmemCtx->hRefCount);
+}
+
+/*************************************************************************/ /*!
+@Function       _DevmemIntCtxRelease
+@Description    Release the reference to the provided device memory context.
+                If this is the last reference which was taken then the
+                memory context will be freed.
+@Return         None
+*/ /**************************************************************************/
+static INLINE IMG_VOID _DevmemIntCtxRelease(DEVMEMINT_CTX *psDevmemCtx)
+{
+       if (OSAtomicDecrement(&psDevmemCtx->hRefCount) == 0)
+       {
+               /* The last reference has gone, destroy the context */
+               PVRSRV_DEVICE_NODE *psDevNode = psDevmemCtx->psDevNode;
+       
+               if (psDevNode->pfnUnregisterMemoryContext)
+               {
+                       psDevNode->pfnUnregisterMemoryContext(psDevmemCtx->hPrivData);
+               }
+           MMU_ContextDestroy(psDevmemCtx->psMMUContext);
+       
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed memory context %p", __FUNCTION__, psDevmemCtx));
+               OSFreeMem(psDevmemCtx);
+       }
+}
+
+/*************************************************************************/ /*!
+@Function       _DevmemIntHeapAcquire
+@Description    Acquire a reference to the provided device memory heap.
+@Return         None
+*/ /**************************************************************************/
+static INLINE IMG_VOID _DevmemIntHeapAcquire(DEVMEMINT_HEAP *psDevmemHeap)
+{
+       OSAtomicIncrement(&psDevmemHeap->hRefCount);
+}
+
+/*************************************************************************/ /*!
+@Function       _DevmemIntHeapRelease
+@Description    Release the reference to the provided device memory heap.
+                If this is the last reference which was taken then the
+                memory context will be freed.
+@Return         None
+*/ /**************************************************************************/
+static INLINE IMG_VOID _DevmemIntHeapRelease(DEVMEMINT_HEAP *psDevmemHeap)
+{
+       OSAtomicDecrement(&psDevmemHeap->hRefCount);
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemServerGetImportHandle
+@Description    For given exportable memory descriptor returns PMR handle.
+@Return         Memory is exportable - Success
+                PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+                                                  IMG_HANDLE *phImport)
+{
+       PVRSRV_ERROR eError;
+
+       if (psMemDesc->psImport->bExportable == IMG_FALSE)
+       {
+        eError = PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION;
+        goto e0;
+       }
+
+       *phImport = psMemDesc->psImport->hPMR;
+       return PVRSRV_OK;
+
+e0:
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemServerGetHeapHandle
+@Description    For given reservation returns the Heap handle.
+@Return         PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION *psReservation,
+                                                  IMG_HANDLE *phHeap)
+{
+       *phHeap = psReservation->psDevmemHeap;
+       return PVRSRV_OK;
+}
+
+
+
+/*************************************************************************/ /*!
+@Function       DevmemIntCtxCreate
+@Description    Creates and initialises a device memory context.
+@Return         valid Device Memory context handle - Success
+                PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxCreate(
+                   PVRSRV_DEVICE_NODE *psDeviceNode,
+                   DEVMEMINT_CTX **ppsDevmemCtxPtr,
+                   IMG_HANDLE *hPrivData
+                   )
+{
+    PVRSRV_ERROR eError;
+    DEVMEMINT_CTX *psDevmemCtx;
+    IMG_HANDLE hPrivDataInt = IMG_NULL;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "%s", __FUNCTION__));
+
+       /* allocate a Devmem context */
+    psDevmemCtx = OSAllocMem(sizeof *psDevmemCtx);
+    if (psDevmemCtx == IMG_NULL)
+       {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF ((PVR_DBG_ERROR, "%s: Alloc failed", __FUNCTION__));
+        goto fail_alloc;
+       }
+
+       OSAtomicWrite(&psDevmemCtx->hRefCount, 1);
+    psDevmemCtx->psDevNode = psDeviceNode;
+
+    /* Call down to MMU context creation */
+
+    eError = MMU_ContextCreate(psDeviceNode,
+                               &psDevmemCtx->psMMUContext);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: MMU_ContextCreate failed", __FUNCTION__));
+               goto fail_mmucontext;
+       }
+
+
+       if (psDeviceNode->pfnRegisterMemoryContext)
+       {
+               eError = psDeviceNode->pfnRegisterMemoryContext(psDeviceNode, psDevmemCtx->psMMUContext, &hPrivDataInt);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to register MMU context", __FUNCTION__));
+                       goto fail_register;
+               }
+       }
+
+       /* Store the private data as it is required to unregister the memory context */
+       psDevmemCtx->hPrivData = hPrivDataInt;
+       *hPrivData = hPrivDataInt;
+    *ppsDevmemCtxPtr = psDevmemCtx;
+
+       return PVRSRV_OK;
+
+fail_register:
+    MMU_ContextDestroy(psDevmemCtx->psMMUContext);
+fail_mmucontext:
+       OSFREEMEM(psDevmemCtx);
+fail_alloc:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemIntHeapCreate
+@Description    Creates and initialises a device memory heap.
+@Return         valid Device Memory heap handle - Success
+                PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntHeapCreate(
+                    DEVMEMINT_CTX *psDevmemCtx,
+                    IMG_DEV_VIRTADDR sHeapBaseAddr,
+                    IMG_DEVMEM_SIZE_T uiHeapLength,
+                    IMG_UINT32 uiLog2DataPageSize,
+                    DEVMEMINT_HEAP **ppsDevmemHeapPtr
+                    )
+{
+    PVRSRV_ERROR eError;
+    DEVMEMINT_HEAP *psDevmemHeap;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "%s: DevmemIntHeap_Create", __FUNCTION__));
+
+       /* allocate a Devmem context */
+       psDevmemHeap = OSAllocMem(sizeof *psDevmemHeap);
+    if (psDevmemHeap == IMG_NULL)
+       {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF ((PVR_DBG_ERROR, "%s: Alloc failed", __FUNCTION__));
+        goto fail_alloc;
+       }
+
+    psDevmemHeap->psDevmemCtx = psDevmemCtx;
+
+       _DevmemIntCtxAcquire(psDevmemHeap->psDevmemCtx);
+
+       OSAtomicWrite(&psDevmemHeap->hRefCount, 1);
+
+    *ppsDevmemHeapPtr = psDevmemHeap;
+
+       return PVRSRV_OK;
+
+fail_alloc:
+    return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap,
+                DEVMEMINT_RESERVATION *psReservation,
+                PMR *psPMR,
+                PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+                DEVMEMINT_MAPPING **ppsMappingPtr)
+{
+    PVRSRV_ERROR eError;
+    DEVMEMINT_MAPPING *psMapping;
+    /* number of pages (device pages) that allocation spans */
+    IMG_UINT32 ui32NumDevPages;
+    /* device virtual address of start of allocation */
+    IMG_DEV_VIRTADDR sAllocationDevVAddr;
+    /* and its length */
+    IMG_DEVMEM_SIZE_T uiAllocationSize;
+
+       /* allocate memory to record the mapping info */
+       psMapping = OSAllocMem(sizeof *psMapping);
+    if (psMapping == IMG_NULL)
+       {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF ((PVR_DBG_ERROR, "DevmemIntMapPMR: Alloc failed"));
+        goto e0;
+       }
+
+    uiAllocationSize = psReservation->uiLength;
+
+
+    ui32NumDevPages = 0xffffffffU & (((uiAllocationSize - 1)
+                                      >> GET_LOG2_PAGESIZE()) + 1);
+    PVR_ASSERT(ui32NumDevPages << GET_LOG2_PAGESIZE() == uiAllocationSize);
+
+    eError = PMRLockSysPhysAddresses(psPMR,
+               GET_LOG2_PAGESIZE());
+    if (eError != PVRSRV_OK)
+       {
+        goto e2;
+       }
+
+    sAllocationDevVAddr = psReservation->sBase;
+
+    /*  N.B.  We pass mapping permission flags to MMU_MapPMR and let
+       it reject the mapping if the permissions on the PMR are not compatible. */
+
+    eError = MMU_MapPMR (psDevmemHeap->psDevmemCtx->psMMUContext,
+                         sAllocationDevVAddr,
+                         psPMR,
+                         ui32NumDevPages << GET_LOG2_PAGESIZE(),
+                         uiMapFlags,
+                         GET_LOG2_PAGESIZE());
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    psMapping->psReservation = psReservation;
+    psMapping->uiNumPages = ui32NumDevPages;
+    psMapping->uiLog2PageSize = GET_LOG2_PAGESIZE();
+    psMapping->psPMR = psPMR;
+    /* Don't bother with refcount on reservation, as a reservation
+       only ever holds one mapping, so we directly increment the
+       refcount on the heap instead */
+    _DevmemIntHeapAcquire(psMapping->psReservation->psDevmemHeap);
+
+    *ppsMappingPtr = psMapping;
+
+    return PVRSRV_OK;
+
+ e2:
+       OSFreeMem(psMapping);
+
+ e0:
+    PVR_ASSERT (eError != PVRSRV_OK);
+    return eError;
+}
+
+
+PVRSRV_ERROR
+DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping)
+{
+    PVRSRV_ERROR eError;
+    DEVMEMINT_HEAP *psDevmemHeap;
+    /* device virtual address of start of allocation */
+    IMG_DEV_VIRTADDR sAllocationDevVAddr;
+    /* number of pages (device pages) that allocation spans */
+    IMG_UINT32 ui32NumDevPages;
+
+    psDevmemHeap = psMapping->psReservation->psDevmemHeap;
+
+    ui32NumDevPages = psMapping->uiNumPages;
+    sAllocationDevVAddr = psMapping->psReservation->sBase;
+
+
+    MMU_UnmapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
+                    sAllocationDevVAddr,
+                    ui32NumDevPages,
+                    GET_LOG2_PAGESIZE());
+
+    eError = PMRUnlockSysPhysAddresses(psMapping->psPMR);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    /* Don't bother with refcount on reservation, as a reservation
+       only ever holds one mapping, so we directly decrement the
+       refcount on the heap instead */
+    _DevmemIntHeapRelease(psDevmemHeap);
+
+       OSFreeMem(psMapping);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap,
+                      IMG_DEV_VIRTADDR sAllocationDevVAddr,
+                      IMG_DEVMEM_SIZE_T uiAllocationSize,
+                      DEVMEMINT_RESERVATION **ppsReservationPtr)
+{
+    PVRSRV_ERROR eError;
+    DEVMEMINT_RESERVATION *psReservation;
+
+       /* allocate memory to record the reservation info */
+       psReservation = OSAllocMem(sizeof *psReservation);
+    if (psReservation == IMG_NULL)
+       {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF ((PVR_DBG_ERROR, "DevmemIntReserveRange: Alloc failed"));
+        goto e0;
+       }
+
+    psReservation->sBase = sAllocationDevVAddr;
+    psReservation->uiLength = uiAllocationSize;
+
+
+    eError = MMU_Alloc (psDevmemHeap->psDevmemCtx->psMMUContext,
+                        uiAllocationSize,
+                        &uiAllocationSize,
+                        0, /* IMG_UINT32 uiProtFlags */
+                        0, /* alignment is n/a since we supply devvaddr */
+                        &sAllocationDevVAddr,
+                        GET_LOG2_PAGESIZE());
+    if (eError != PVRSRV_OK)
+    {
+        goto e1;
+    }
+
+    /* since we supplied the virt addr, MMU_Alloc shouldn't have
+       chosen a new one for us */
+    PVR_ASSERT(sAllocationDevVAddr.uiAddr == psReservation->sBase.uiAddr);
+
+       _DevmemIntHeapAcquire(psDevmemHeap);
+
+    psReservation->psDevmemHeap = psDevmemHeap;
+    *ppsReservationPtr = psReservation;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e1:
+       OSFreeMem(psReservation);
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psReservation)
+{
+
+    MMU_Free (psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+              psReservation->sBase,
+              psReservation->uiLength,
+              GET_LOG2_PAGESIZE());
+
+       _DevmemIntHeapRelease(psReservation->psDevmemHeap);
+       OSFreeMem(psReservation);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntHeapDestroy(
+                     DEVMEMINT_HEAP *psDevmemHeap
+                     )
+{
+    if (OSAtomicRead(&psDevmemHeap->hRefCount) != 1)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "BUG!  %s called but has too many references (%d) "
+                 "which probably means allocations have been made from the heap and not freed",
+                 __FUNCTION__,
+                 OSAtomicRead(&psDevmemHeap->hRefCount)));
+
+        /*
+        * Try again later when you've freed all the memory
+        *
+        * Note:
+        * We don't expect the application to retry (after all this call would
+        * succeed if the client had freed all the memory which it should have
+        * done before calling this function). However, given there should be
+        * an associated handle, when the handle base is destroyed it will free
+        * any allocations leaked by the client and then it will retry this call,
+        * which should then succeed.
+        */
+        return PVRSRV_ERROR_RETRY;
+    }
+
+    PVR_ASSERT(OSAtomicRead(&psDevmemHeap->hRefCount) == 1);
+
+       _DevmemIntCtxRelease(psDevmemHeap->psDevmemCtx);
+
+       PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed heap %p", __FUNCTION__, psDevmemHeap));
+       OSFreeMem(psDevmemHeap);
+
+       return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+@Function       DevmemIntCtxDestroy
+@Description    Destroy that created by DevmemIntCtxCreate
+@Input          psDevmemCtx   Device Memory context
+@Return         cannot fail.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxDestroy(
+                    DEVMEMINT_CTX *psDevmemCtx
+                    )
+{
+       /*
+               We can't determine if we should be freeing the context here
+               as it refcount!=1 could be due to either the fact that heap(s)
+               remain with allocations on them, or that this memory context
+               has been exported.
+               As the client couldn’t do anything useful with this information
+               anyway and the fact that the refcount will ensure we only
+               free the context when _all_ references have been released
+               don't bother checking and just return OK regardless.
+       */
+       _DevmemIntCtxRelease(psDevmemCtx);
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemIntCtxExport
+@Description    Exports a device memory context.
+@Return         valid Device Memory context handle - Success
+                PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxExport(DEVMEMINT_CTX *psDevmemCtx,
+                   DEVMEMINT_CTX_EXPORT **ppsExport)
+{
+       DEVMEMINT_CTX_EXPORT *psExport;
+
+       psExport = OSAllocMem(sizeof(*psExport));
+       if (psExport == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       _DevmemIntCtxAcquire(psDevmemCtx);
+       psExport->psDevmemCtx = psDevmemCtx;
+       
+       *ppsExport = psExport;
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemIntCtxUnexport
+@Description    Unexport an exported a device memory context.
+@Return         None
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxUnexport(DEVMEMINT_CTX_EXPORT *psExport)
+{
+       _DevmemIntCtxRelease(psExport->psDevmemCtx);
+       OSFreeMem(psExport);
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemIntCtxImport
+@Description    Import an exported a device memory context.
+@Return         valid Device Memory context handle - Success
+                PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxImport(DEVMEMINT_CTX_EXPORT *psExport,
+                                  DEVMEMINT_CTX **ppsDevmemCtxPtr,
+                                  IMG_HANDLE *hPrivData)
+{
+       DEVMEMINT_CTX *psDevmemCtx = psExport->psDevmemCtx;
+
+       _DevmemIntCtxAcquire(psDevmemCtx);
+
+       *ppsDevmemCtxPtr = psDevmemCtx;
+       *hPrivData = psDevmemCtx->hPrivData;
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemSLCFlushInvalRequest
+@Description    Requests a SLC Flush and Invalidate
+@Input          psDeviceNode    Device node
+@Input          psPmr           PMR
+@Return         PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemSLCFlushInvalRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                       PMR *psPmr)
+{
+
+       /* invoke SLC flush and invalidate request */
+       psDeviceNode->pfnSLCCacheInvalidateRequest(psDeviceNode, psPmr);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR DevmemIntIsVDevAddrValid(DEVMEMINT_CTX *psDevMemContext,
+                                      IMG_DEV_VIRTADDR sDevAddr)
+{
+    return MMU_IsVDevAddrValid(psDevMemContext->psMMUContext,
+                               GET_LOG2_PAGESIZE(),
+                               sDevAddr) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_GPU_ADDR;
+}
+
+#if defined (PDUMP)
+IMG_UINT32 DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext)
+{
+       IMG_UINT32 ui32MMUContextID;
+       MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32MMUContextID);
+       return ui32MMUContextID;
+}
+
+PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+                                IMG_DEV_VIRTADDR sDevAddrStart,
+                                IMG_DEVMEM_SIZE_T uiSize,
+                                IMG_UINT32 ui32ArraySize,
+                                const IMG_CHAR *pszFilename,
+                                                               IMG_UINT32 ui32FileOffset,
+                                                               IMG_UINT32 ui32PDumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_UINT32 uiPDumpMMUCtx;
+
+    PVR_UNREFERENCED_PARAMETER(ui32ArraySize);
+
+       eError = MMU_AcquirePDumpMMUContext(psDevmemCtx->psMMUContext,
+                                                                               &uiPDumpMMUCtx);
+
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    /*
+      The following SYSMEM refers to the 'MMU Context', hence it
+      should be the MMU context, not the PMR, that says what the PDump
+      MemSpace tag is?
+      From a PDump P.O.V. it doesn't matter which name space we use as long
+      as that MemSpace is used on the 'MMU Context' we're dumping from
+    */
+    eError = PDumpMMUSAB(psDevmemCtx->psDevNode->sDevId.pszPDumpDevName,
+                            uiPDumpMMUCtx,
+                            sDevAddrStart,
+                            uiSize,
+                            pszFilename,
+                            ui32FileOffset,
+                                                       ui32PDumpFlags);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+       MMU_ReleasePDumpMMUContext(psDevmemCtx->psMMUContext);
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+DevmemIntPDumpBitmap(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                               IMG_CHAR *pszFileName,
+                                               IMG_UINT32 ui32FileOffset,
+                                               IMG_UINT32 ui32Width,
+                                               IMG_UINT32 ui32Height,
+                                               IMG_UINT32 ui32StrideInBytes,
+                                               IMG_DEV_VIRTADDR sDevBaseAddr,
+                                               DEVMEMINT_CTX *psDevMemContext,
+                                               IMG_UINT32 ui32Size,
+                                               PDUMP_PIXEL_FORMAT ePixelFormat,
+                                               IMG_UINT32 ui32AddrMode,
+                                               IMG_UINT32 ui32PDumpFlags)
+{
+       IMG_UINT32 ui32ContextID;
+       PVRSRV_ERROR eError;
+
+       eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DevmemIntPDumpBitmap: Failed to acquire MMU context"));
+               return PVRSRV_ERROR_FAILED_TO_ALLOC_MMUCONTEXT_ID;
+       }
+
+       eError = PDumpBitmapKM(psDeviceNode,
+                                                       pszFileName,
+                                                       ui32FileOffset,
+                                                       ui32Width,
+                                                       ui32Height,
+                                                       ui32StrideInBytes,
+                                                       sDevBaseAddr,
+                                                       ui32ContextID,
+                                                       ui32Size,
+                                                       ePixelFormat,
+                                                       ui32AddrMode,
+                                                       ui32PDumpFlags);
+
+       /* Don't care about return value */
+       MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext);
+
+       return eError;
+}
+#endif
diff --git a/drivers/gpu/rogue_m/services/server/common/handle.c b/drivers/gpu/rogue_m/services/server/common/handle.c
new file mode 100644 (file)
index 0000000..dfff220
--- /dev/null
@@ -0,0 +1,2125 @@
+/*************************************************************************/ /*!
+@File
+@Title         Resource Handle Manager
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Provide resource handle management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+/* See handle.h for a description of the handle API. */
+
+/*
+ * The implmentation supports movable handle structures, allowing the address
+ * of a handle structure to change without having to fix up pointers in
+ * any of the handle structures.  For example, the linked list mechanism
+ * used to link subhandles together uses handle array indices rather than
+ * pointers to the structures themselves.
+ */
+
+#include <stddef.h>
+
+#include "handle.h"
+#include "handle_impl.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+
+#define        HANDLE_HASH_TAB_INIT_SIZE               32
+
+#define        SET_FLAG(v, f)                          ((void)((v) |= (f)))
+#define        CLEAR_FLAG(v, f)                        ((void)((v) &= (IMG_UINT)~(f)))
+#define        TEST_FLAG(v, f)                         ((IMG_BOOL)(((v) & (f)) != 0))
+
+#define        TEST_ALLOC_FLAG(psHandleData, f)        TEST_FLAG((psHandleData)->eFlag, f)
+
+#if !defined(ARRAY_SIZE)
+#define ARRAY_SIZE(a)                          (sizeof(a) / sizeof((a)[0]))
+#endif
+
+
+/* Linked list structure. Used for both the list head and list items */
+typedef struct _HANDLE_LIST_
+{
+       IMG_HANDLE hPrev;
+       IMG_HANDLE hNext;
+       IMG_HANDLE hParent;
+} HANDLE_LIST;
+
+typedef struct _HANDLE_DATA_
+{
+       /* The handle that represents this structure */
+       IMG_HANDLE hHandle;
+
+       /* Handle type */
+       PVRSRV_HANDLE_TYPE eType;
+
+       /* Flags specified when the handle was allocated */
+       PVRSRV_HANDLE_ALLOC_FLAG eFlag;
+
+       /* Pointer to the data that the handle represents */
+       void *pvData;
+
+       /*
+        * Callback specified at handle allocation time to
+        * release/destroy/free the data represented by the
+        * handle when it's reference count reaches 0. This
+        * should always be IMG_NULL for subhandles.
+        */
+       PFN_HANDLE_RELEASE pfnReleaseData;
+
+       /* List head for subhandles of this handle */
+       HANDLE_LIST sChildren;
+
+       /* List entry for sibling subhandles */
+       HANDLE_LIST sSiblings;
+
+       /* Reference count, always 1 unless handle is shared */
+       IMG_UINT32 ui32Refs;
+} HANDLE_DATA;
+
+struct _HANDLE_BASE_
+{
+       /* Pointer to a handle implementations base structure */
+       HANDLE_IMPL_BASE *psImplBase;
+
+       /*
+        * Pointer to handle hash table.
+        * The hash table is used to do reverse lookups, converting data
+        * pointers to handles.
+        */
+       HASH_TABLE *psHashTab;
+};
+
+/*
+ * The key for the handle hash table is an array of three elements, the
+ * pointer to the resource, the resource type and the parent handle (or 
+ * IMG_NULL if there is no parent). The eHandKey enumeration gives the 
+ * array indices of the elements making up the key.
+ */
+enum eHandKey
+{
+       HAND_KEY_DATA = 0,
+       HAND_KEY_TYPE,
+       HAND_KEY_PARENT,
+       HAND_KEY_LEN            /* Must be last item in list */
+};
+
+/* HAND_KEY is the type of the hash table key */
+typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
+
+/* Stores a pointer to the function table of the handle back-end in use */
+static HANDLE_IMPL_FUNCTAB const *gpsHandleFuncs = IMG_NULL;
+
+/* 
+ * Global lock added to avoid to call the handling functions
+ * only in a single threaded context.
+ */
+static POS_LOCK gHandleLock;
+static IMG_BOOL gbLockInitialised = IMG_FALSE;
+
+void LockHandle(void)
+{
+       OSLockAcquire(gHandleLock);
+}
+
+void UnlockHandle(void)
+{
+       OSLockRelease(gHandleLock);
+}
+
+/*
+ * Kernel handle base structure. This is used for handles that are not 
+ * allocated on behalf of a particular process.
+ */
+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
+
+/*!
+******************************************************************************
+
+ @Function     GetHandleData
+
+ @Description  Get the handle data structure for a given handle
+
+ @Input                psBase - pointer to handle base structure
+               ppsHandleData - location to return pointer to handle data structure
+               hHandle - handle from client
+               eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the
+                       handle type is not to be checked.
+
+ @Output       ppsHandleData - points to a pointer to the handle data structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleData)
+#endif
+static INLINE
+PVRSRV_ERROR GetHandleData(PVRSRV_HANDLE_BASE *psBase,
+                          HANDLE_DATA **ppsHandleData,
+                          IMG_HANDLE hHandle,
+                          PVRSRV_HANDLE_TYPE eType)
+{
+       HANDLE_DATA *psHandleData;
+       PVRSRV_ERROR eError;
+
+       eError = gpsHandleFuncs->pfnGetHandleData(psBase->psImplBase, 
+                                                 hHandle, 
+                                                 (void **)&psHandleData);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       /*
+        * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function,
+        * check handle is of the correct type.
+        */
+       if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandleData->eType)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "GetHandleData: Handle type mismatch (%d != %d)",
+                        eType, psHandleData->eType));
+               return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
+       }
+
+       /* Return the handle structure */
+       *ppsHandleData = psHandleData;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     HandleListInit
+
+ @Description  Initialise a linked list structure embedded in a handle
+               structure.
+
+ @Input                hHandle - handle containing the linked list structure
+               psList - pointer to linked list structure
+               hParent - parent handle or IMG_NULL
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInit)
+#endif
+static INLINE
+void HandleListInit(IMG_HANDLE hHandle, HANDLE_LIST *psList, IMG_HANDLE hParent)
+{
+       psList->hPrev = hHandle;
+       psList->hNext = hHandle;
+       psList->hParent = hParent;
+}
+
+/*!
+******************************************************************************
+
+ @Function     InitParentList
+
+ @Description  Initialise the children list head in a handle structure.
+               The children are the subhandles of this handle.
+
+ @Input                psHandleData - pointer to handle data structure
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitParentList)
+#endif
+static INLINE
+void InitParentList(HANDLE_DATA *psHandleData)
+{
+       IMG_HANDLE hParent = psHandleData->hHandle;
+
+       HandleListInit(hParent, &psHandleData->sChildren, hParent);
+}
+
+/*!
+******************************************************************************
+
+ @Function     InitChildEntry
+
+ @Description  Initialise the child list entry in a handle structure.
+               The list entry is used to link together subhandles of
+               a given handle.
+
+ @Input                psHandleData - pointer to handle data structure
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitChildEntry)
+#endif
+static INLINE
+void InitChildEntry(HANDLE_DATA *psHandleData)
+{
+       HandleListInit(psHandleData->hHandle, &psHandleData->sSiblings, IMG_NULL);
+}
+
+/*!
+******************************************************************************
+
+ @Function     HandleListIsEmpty
+
+ @Description  Determine whether a given linked list is empty.
+
+ @Input                hHandle - handle containing the list head
+               psList - pointer to the list head
+
+ @Return       IMG_TRUE if the list is empty, IMG_FALSE if it isn't.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIsEmpty)
+#endif
+static INLINE
+IMG_BOOL HandleListIsEmpty(IMG_HANDLE hHandle, HANDLE_LIST *psList) /* Instead of passing in the handle can we not just do (psList->hPrev == psList->hNext) ? IMG_TRUE : IMG_FALSE ??? */
+{
+       IMG_BOOL bIsEmpty;
+
+       bIsEmpty = (IMG_BOOL)(psList->hNext == hHandle);
+
+#ifdef DEBUG
+       {
+               IMG_BOOL bIsEmpty2;
+
+               bIsEmpty2 = (IMG_BOOL)(psList->hPrev == hHandle);
+               PVR_ASSERT(bIsEmpty == bIsEmpty2);
+       }
+#endif
+
+       return bIsEmpty;
+}
+
+#ifdef DEBUG
+/*!
+******************************************************************************
+
+ @Function     NoChildren
+
+ @Description  Determine whether a handle has any subhandles
+
+ @Input                psHandleData - pointer to handle data structure
+
+ @Return       IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoChildren)
+#endif
+static INLINE
+IMG_BOOL NoChildren(HANDLE_DATA *psHandleData)
+{
+       PVR_ASSERT(psHandleData->sChildren.hParent == psHandleData->hHandle);
+
+       return HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sChildren);
+}
+
+/*!
+******************************************************************************
+
+ @Function     NoParent
+
+ @Description  Determine whether a handle is a subhandle
+
+ @Input                psHandleData - pointer to handle data structure
+
+ @Return       IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoParent)
+#endif
+static INLINE
+IMG_BOOL NoParent(HANDLE_DATA *psHandleData)
+{
+       if (HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sSiblings))
+       {
+               PVR_ASSERT(psHandleData->sSiblings.hParent == IMG_NULL);
+
+               return IMG_TRUE;
+       }
+       else
+       {
+               PVR_ASSERT(psHandleData->sSiblings.hParent != IMG_NULL);
+       }
+       return IMG_FALSE;
+}
+#endif /*DEBUG*/
+
+/*!
+******************************************************************************
+
+ @Function     ParentHandle
+
+ @Description  Determine the parent of a handle
+
+ @Input                psHandleData - pointer to handle data structure
+
+ @Return       Parent handle, or IMG_NULL if the handle is not a subhandle.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentHandle)
+#endif
+static INLINE
+IMG_HANDLE ParentHandle(HANDLE_DATA *psHandleData)
+{
+       return psHandleData->sSiblings.hParent;
+}
+
+/*
+ * GetHandleListFromHandleAndOffset is used to generate either a
+ * pointer to the subhandle list head, or a pointer to the linked list
+ * structure of an item on a subhandle list.
+ * The list head is itself on the list, but is at a different offset
+ * in the handle structure to the linked list structure for items on
+ * the list.  The two linked list structures are differentiated by
+ * the third parameter, containing the parent handle.  The parent field
+ * in the list head structure references the handle structure that contains
+ * it.  For items on the list, the parent field in the linked list structure
+ * references the parent handle, which will be different from the handle
+ * containing the linked list structure.
+ */
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleListFromHandleAndOffset)
+#endif
+static INLINE
+HANDLE_LIST *GetHandleListFromHandleAndOffset(PVRSRV_HANDLE_BASE *psBase, 
+                                             IMG_HANDLE hEntry, 
+                                             IMG_HANDLE hParent, 
+                                             IMG_SIZE_T uiParentOffset, 
+                                             IMG_SIZE_T uiEntryOffset)
+{
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psBase != IMG_NULL);
+
+       eError = GetHandleData(psBase, 
+                              &psHandleData, 
+                              hEntry, 
+                              PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               return IMG_NULL;
+       }
+
+       if (hEntry == hParent)
+       {
+               return (HANDLE_LIST *)((IMG_CHAR *)psHandleData + uiParentOffset);
+       }
+       else
+       {
+               return (HANDLE_LIST *)((IMG_CHAR *)psHandleData + uiEntryOffset);
+       }
+}
+
+/*!
+******************************************************************************
+
+ @Function     HandleListInsertBefore
+
+ @Description  Insert a handle before a handle currently on the list.
+
+ @Input                hEntry - handle to be inserted after
+               psEntry - pointer to handle structure to be inserted after
+               uiParentOffset - offset to list head struct in handle structure
+               hNewEntry - handle to be inserted
+               psNewEntry - pointer to handle structure of item to be inserted
+               uiEntryOffset - offset of list item struct in handle structure
+               hParent - parent handle of hNewEntry
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInsertBefore)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase,
+                                   IMG_HANDLE hEntry,
+                                   HANDLE_LIST *psEntry,
+                                   IMG_SIZE_T uiParentOffset,
+                                   IMG_HANDLE hNewEntry,
+                                   HANDLE_LIST *psNewEntry,
+                                   IMG_SIZE_T uiEntryOffset,
+                                   IMG_HANDLE hParent)
+{
+       HANDLE_LIST *psPrevEntry;
+
+       if (psBase == IMG_NULL || psEntry == IMG_NULL || psNewEntry == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psPrevEntry = GetHandleListFromHandleAndOffset(psBase, 
+                                                      psEntry->hPrev, 
+                                                      hParent, 
+                                                      uiParentOffset, 
+                                                      uiEntryOffset);
+       if (psPrevEntry == IMG_NULL)
+       {
+               return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+       }
+
+       PVR_ASSERT(psNewEntry->hParent == IMG_NULL);
+       PVR_ASSERT(hEntry == psPrevEntry->hNext);
+
+#if defined(DEBUG)
+       {
+               HANDLE_LIST *psParentList;
+
+               psParentList = GetHandleListFromHandleAndOffset(psBase, 
+                                                               hParent, 
+                                                               hParent, 
+                                                               uiParentOffset, 
+                                                               uiParentOffset);
+               PVR_ASSERT(psParentList && psParentList->hParent == hParent);
+       }
+#endif /* defined(DEBUG) */
+
+       psNewEntry->hPrev = psEntry->hPrev;
+       psEntry->hPrev = hNewEntry;
+
+       psNewEntry->hNext = hEntry;
+       psPrevEntry->hNext = hNewEntry;
+
+       psNewEntry->hParent = hParent;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     AdoptChild
+
+ @Description  Assign a subhandle to a handle
+
+ @Input                psParentData - pointer to handle structure of parent handle
+               psChildData - pointer to handle structure of child subhandle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(AdoptChild)
+#endif
+static INLINE
+PVRSRV_ERROR AdoptChild(PVRSRV_HANDLE_BASE *psBase,
+                       HANDLE_DATA *psParentData,
+                       HANDLE_DATA *psChildData)
+{
+       IMG_HANDLE hParent = psParentData->sChildren.hParent;
+
+       PVR_ASSERT(hParent == psParentData->hHandle);
+
+       return HandleListInsertBefore(psBase, 
+                                     hParent, 
+                                     &psParentData->sChildren, 
+                                     offsetof(HANDLE_DATA, sChildren), 
+                                     psChildData->hHandle, 
+                                     &psChildData->sSiblings, 
+                                     offsetof(HANDLE_DATA, sSiblings), 
+                                     hParent);
+}
+
+/*!
+******************************************************************************
+
+ @Function     HandleListRemove
+
+ @Description  Remove a handle from a list
+
+ @Input                hEntry - handle to be removed
+               psEntry - pointer to handle structure of item to be removed
+               uiEntryOffset - offset of list item struct in handle structure
+               uiParentOffset - offset to list head struct in handle structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListRemove)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListRemove(PVRSRV_HANDLE_BASE *psBase,
+                             IMG_HANDLE hEntry,
+                             HANDLE_LIST *psEntry,
+                             IMG_SIZE_T uiEntryOffset,
+                             IMG_SIZE_T uiParentOffset)
+{
+       if (psBase == IMG_NULL || psEntry == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       if (!HandleListIsEmpty(hEntry, psEntry))
+       {
+               HANDLE_LIST *psPrev;
+               HANDLE_LIST *psNext;
+
+               psPrev = GetHandleListFromHandleAndOffset(psBase, 
+                                                         psEntry->hPrev, 
+                                                         psEntry->hParent, 
+                                                         uiParentOffset, 
+                                                         uiEntryOffset);
+               if (psPrev == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+               }
+
+               psNext = GetHandleListFromHandleAndOffset(psBase, 
+                                                         psEntry->hNext, 
+                                                         psEntry->hParent, 
+                                                         uiParentOffset, 
+                                                         uiEntryOffset);
+               if (psNext == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+               }
+
+               /*
+                * The list head is on the list, and we don't want to
+                * remove it.
+                */
+               PVR_ASSERT(psEntry->hParent != IMG_NULL);
+
+               psPrev->hNext = psEntry->hNext;
+               psNext->hPrev = psEntry->hPrev;
+
+               HandleListInit(hEntry, psEntry, IMG_NULL);
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     UnlinkFromParent
+
+ @Description  Remove a subhandle from its parents list
+
+ @Input                psHandleData - pointer to handle data structure of child subhandle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(UnlinkFromParent)
+#endif
+static INLINE
+PVRSRV_ERROR UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase,
+                             HANDLE_DATA *psHandleData)
+{
+       return HandleListRemove(psBase, 
+                               psHandleData->hHandle, 
+                               &psHandleData->sSiblings, 
+                               offsetof(HANDLE_DATA, sSiblings), 
+                               offsetof(HANDLE_DATA, sChildren));
+}
+
+/*!
+******************************************************************************
+
+ @Function     HandleListIterate
+
+ @Description  Iterate over the items in a list
+
+ @Input                psHead - pointer to list head
+               uiParentOffset - offset to list head struct in handle structure
+               uiEntryOffset - offset of list item struct in handle structure
+               pfnIterFunc - function to be called for each handle in the list
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIterate)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase,
+                              HANDLE_LIST *psHead,
+                              IMG_SIZE_T uiParentOffset,
+                              IMG_SIZE_T uiEntryOffset,
+                              PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE))
+{
+       IMG_HANDLE hHandle = psHead->hNext;
+       IMG_HANDLE hParent = psHead->hParent;
+       IMG_HANDLE hNext;
+
+       PVR_ASSERT(psHead->hParent != IMG_NULL);
+
+       /*
+        * Follow the next chain from the list head until we reach
+        * the list head again, which signifies the end of the list.
+        */
+       while (hHandle != hParent)
+       {
+               HANDLE_LIST *psEntry;
+               PVRSRV_ERROR eError;
+
+               psEntry = GetHandleListFromHandleAndOffset(psBase, 
+                                                          hHandle, 
+                                                          hParent, 
+                                                          uiParentOffset, 
+                                                          uiEntryOffset);
+               if (psEntry == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+               }
+
+               PVR_ASSERT(psEntry->hParent == psHead->hParent);
+
+               /*
+                * Get the next index now, in case the list item is
+                * modified by the iteration function.
+                */
+               hNext = psEntry->hNext;
+
+               eError = (*pfnIterFunc)(psBase, hHandle);
+               if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+
+               hHandle = hNext;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     IterateOverChildren
+
+ @Description  Iterate over the subhandles of a parent handle
+
+ @Input                psParentData - pointer to parent handle structure
+               pfnIterFunc - function to be called for each subhandle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(IterateOverChildren)
+#endif
+static INLINE
+PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase,
+                                HANDLE_DATA *psParentData,
+                                PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE))
+{
+        return HandleListIterate(psBase,
+                                 &psParentData->sChildren,
+                                 offsetof(HANDLE_DATA, sChildren),
+                                 offsetof(HANDLE_DATA, sSiblings),
+                                 pfnIterFunc);
+}
+
+/*!
+******************************************************************************
+
+ @Function     ParentIfPrivate
+
+ @Description  Return the parent handle if the handle was allocated
+               with PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return
+               IMG_NULL
+
+ @Input                psHandleData - pointer to handle data structure
+
+ @Return       Parent handle, or IMG_NULL
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentIfPrivate)
+#endif
+static INLINE
+IMG_HANDLE ParentIfPrivate(HANDLE_DATA *psHandleData)
+{
+       return TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+                       ParentHandle(psHandleData) : IMG_NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function     InitKey
+
+ @Description  Initialise a hash table key for the current process
+
+ @Input                psBase - pointer to handle base structure
+               aKey - pointer to key
+               pvData - pointer to the resource the handle represents
+               eType - type of resource
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitKey)
+#endif
+static INLINE
+void InitKey(HAND_KEY aKey,
+            PVRSRV_HANDLE_BASE *psBase,
+            void *pvData,
+            PVRSRV_HANDLE_TYPE eType,
+            IMG_HANDLE hParent)
+{
+       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 FreeHandleWrapper(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle);
+
+/*!
+******************************************************************************
+
+ @Function     FreeHandle
+
+ @Description  Free a handle data structure.
+
+ @Input                psBase - Pointer to handle base structure
+               hHandle - Handle to be freed
+               eType - Type of the handle to be freed
+               ppvData - Location for data associated with the freed handle
+
+ @Output               ppvData - Points to data that was associated with the freed handle
+
+ @Return       PVRSRV_OK or PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase,
+                              IMG_HANDLE hHandle,
+                              PVRSRV_HANDLE_TYPE eType,
+                              void **ppvData)
+{
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       HANDLE_DATA *psReleasedHandleData;
+       PVRSRV_ERROR eError;
+
+       eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PVR_ASSERT(psHandleData->ui32Refs > 0);
+
+       /* Call the release data callback for each reference on the handle */
+       if (psHandleData->pfnReleaseData != IMG_NULL)
+       {
+               eError = psHandleData->pfnReleaseData(psHandleData->pvData);
+               if (eError == PVRSRV_ERROR_RETRY)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE,
+                                "FreeHandle: "
+                                "Got retry while calling release data callback for %p (type = %d)",
+                                hHandle,
+                                (IMG_UINT32)psHandleData->eType));
+
+                       return eError;
+               }
+               else if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+       psHandleData->ui32Refs--;
+       if (psHandleData->ui32Refs > 0)
+       {
+               /* Reference count still positive, only possible for shared handles */
+               PVR_ASSERT(TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_SHARED));
+               return PVRSRV_OK;
+       }
+
+       if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               HAND_KEY aKey;
+               IMG_HANDLE hRemovedHandle;
+
+               InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, ParentIfPrivate(psHandleData));
+
+               hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psBase->psHashTab, aKey);
+
+               PVR_ASSERT(hRemovedHandle != IMG_NULL);
+               PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
+               PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
+       }
+
+       eError = UnlinkFromParent(psBase, psHandleData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "FreeHandle: Error whilst unlinking from parent handle (%s)", 
+                        PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+
+       /* Free children */
+       eError = IterateOverChildren(psBase, psHandleData, FreeHandleWrapper);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "FreeHandle: Error whilst freeing subhandles (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+
+       eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase,
+                                                 psHandleData->hHandle,
+                                                 (void **)&psReleasedHandleData);
+       if (eError == PVRSRV_OK)
+       {
+               PVR_ASSERT(psReleasedHandleData == psHandleData);
+       }
+
+       if (ppvData)
+       {
+               *ppvData = psHandleData->pvData;
+       }
+
+       OSFreeMem(psHandleData);
+
+       return eError;
+}
+
+static PVRSRV_ERROR FreeHandleWrapper(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle)
+{
+       return FreeHandle(psBase, hHandle, PVRSRV_HANDLE_TYPE_NONE, IMG_NULL);
+}
+
+/*!
+******************************************************************************
+
+ @Function     FindHandle
+
+ @Description  Find handle corresponding to a resource pointer
+
+ @Input                psBase - pointer to handle base structure
+               pvData - pointer to resource to be associated with the handle
+               eType - the type of resource
+
+ @Return       the handle, or IMG_NULL if not found
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(FindHandle)
+#endif
+static INLINE
+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase,
+                     void *pvData,
+                     PVRSRV_HANDLE_TYPE eType,
+                     IMG_HANDLE hParent)
+{
+       HAND_KEY aKey;
+
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+       InitKey(aKey, psBase, pvData, eType, hParent);
+
+       return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+}
+
+/*!
+******************************************************************************
+
+ @Function     AllocHandle
+
+ @Description  Allocate a new handle
+
+ @Input                phHandle - location for new handle
+               pvData - pointer to resource to be associated with the handle
+               eType - the type of resource
+               hParent - parent handle or IMG_NULL
+               pfnReleaseData - Function to release resource at handle release
+                                time
+
+ @Output       phHandle - points to new handle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase,
+                               IMG_HANDLE *phHandle,
+                               void *pvData,
+                               PVRSRV_HANDLE_TYPE eType,
+                               PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+                               IMG_HANDLE hParent,
+                               PFN_HANDLE_RELEASE pfnReleaseData)
+{
+       HANDLE_DATA *psNewHandleData;
+       IMG_HANDLE hHandle;
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(psBase != IMG_NULL && psBase->psHashTab != IMG_NULL);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               /* Handle must not already exist */
+               PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL);
+       }
+
+       psNewHandleData = OSAllocZMem(sizeof(*psNewHandleData));
+       if (psNewHandleData == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't allocate handle data"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       eError = gpsHandleFuncs->pfnAcquireHandle(psBase->psImplBase, &hHandle, psNewHandleData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Failed to acquire a handle"));
+               goto ErrorFreeHandleData;
+       }
+
+       /*
+        * If a data pointer can be associated with multiple handles, we
+        * don't put the handle in the hash table, as the data pointer
+        * may not map to a unique handle
+        */
+       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               HAND_KEY aKey;
+
+               /* Initialise hash key */
+               InitKey(aKey, psBase, pvData, eType, hParent);
+
+               /* Put the new handle in the hash table */
+               if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
+                       eError = PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+                       goto ErrorReleaseHandle;
+               }
+       }
+
+       psNewHandleData->hHandle = hHandle;
+       psNewHandleData->eType = eType;
+       psNewHandleData->eFlag = eFlag;
+       psNewHandleData->pvData = pvData;
+       psNewHandleData->pfnReleaseData = pfnReleaseData;
+       psNewHandleData->ui32Refs = 1;
+
+       InitParentList(psNewHandleData);
+#if defined(DEBUG)
+       PVR_ASSERT(NoChildren(psNewHandleData));
+#endif
+
+       InitChildEntry(psNewHandleData);
+#if defined(DEBUG)
+       PVR_ASSERT(NoParent(psNewHandleData));
+#endif
+
+       /* Return the new handle to the client */
+       *phHandle = psNewHandleData->hHandle;
+
+       return PVRSRV_OK;
+
+ErrorReleaseHandle:
+       (void)gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, hHandle, IMG_NULL);
+
+ErrorFreeHandleData:
+       OSFreeMem(psNewHandleData);
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVAllocHandle
+
+ @Description  Allocate a handle
+
+ @Input                phHandle - location for new handle
+               pvData - pointer to resource to be associated with the handle
+               eType - the type of resource
+               pfnReleaseData - Function to release resource at handle release
+                                time
+
+ @Output       phHandle - points to new handle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
+                              IMG_HANDLE *phHandle,
+                              void *pvData,
+                              PVRSRV_HANDLE_TYPE eType,
+                              PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+                              PFN_HANDLE_RELEASE pfnReleaseData)
+{
+       IMG_HANDLE hHandle;
+       PVRSRV_ERROR eError;
+
+       *phHandle = IMG_NULL;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       if (pfnReleaseData == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Missing release function"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               /* See if there is already a handle for this data pointer */
+               hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
+               if (hHandle != IMG_NULL)
+               {
+                       HANDLE_DATA *psHandleData = IMG_NULL;
+
+                       eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                        "PVRSRVAllocHandle: Lookup of existing handle failed (%s)",
+                                        PVRSRVGetErrorStringKM(eError)));
+                               goto ExitUnlock;
+                       }
+
+                       /*
+                        * If the client is willing to share a handle, and the
+                        * existing handle is marked as shareable, return the
+                        * existing handle.
+                        */
+                       if (TEST_FLAG(psHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
+                       {
+                               /* The same release function should be used for shared handles */
+                               PVR_ASSERT(psHandleData->pfnReleaseData == pfnReleaseData);
+
+                               psHandleData->ui32Refs++;
+                               *phHandle = hHandle;
+
+                               eError = PVRSRV_OK;
+                               goto ExitUnlock;
+                       }
+
+                       eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+                       goto ExitUnlock;
+               }
+       }
+
+       eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL, pfnReleaseData);
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVAllocSubHandle
+
+ @Description  Allocate a subhandle
+
+ @Input                phHandle - location for new subhandle
+               pvData - pointer to resource to be associated with the subhandle
+               eType - the type of resource
+               hParent - parent handle
+
+ @Output       phHandle - points to new subhandle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase,
+                                 IMG_HANDLE *phHandle,
+                                 void *pvData,
+                                 PVRSRV_HANDLE_TYPE eType,
+                                 PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+                                 IMG_HANDLE hParent)
+{
+       HANDLE_DATA *psPHandleData = IMG_NULL;
+       HANDLE_DATA *psCHandleData = IMG_NULL;
+       IMG_HANDLE hParentKey;
+       IMG_HANDLE hHandle;
+       PVRSRV_ERROR eError;
+
+       *phHandle = IMG_NULL;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : IMG_NULL;
+
+       /* Lookup the parent handle */
+       eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
+               goto ExitUnlock;
+       }
+
+       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               /* See if there is already a handle for this data pointer */
+               hHandle = FindHandle(psBase, pvData, eType, hParentKey);
+               if (hHandle != IMG_NULL)
+               {
+                       eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
+                               goto ExitUnlock;
+                       }
+
+                       PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(psCHandleData) == hParent);
+
+                       /*
+                        * If the client is willing to share a handle, the
+                        * existing handle is marked as shareable, and the
+                        * existing handle has the same parent, return the
+                        * existing handle.
+                        */
+                       if (TEST_FLAG(psCHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && 
+                           ParentHandle(psCHandleData) == hParent)
+                       {
+                               psCHandleData->ui32Refs++;
+                               *phHandle = hHandle;
+
+                               eError = PVRSRV_OK;
+                               goto ExitUnlock;
+                       }
+
+                       eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+                       goto ExitUnlock;
+               }
+       }
+
+       eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey, IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               goto ExitUnlock;
+       }
+
+       eError = GetHandleData(psBase, &psCHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
+
+               /* If we were able to allocate the handle then there should be no reason why we 
+                  can't also get it's handle structure. Otherwise something has gone badly wrong. */
+               PVR_ASSERT(eError == PVRSRV_OK);
+
+               goto ExitUnlock;
+       }
+
+       /*
+        * Get the parent handle structure again, in case the handle
+        * structure has moved (depending on the implementation
+        * of AllocHandle).
+        */
+       eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
+
+               (void)FreeHandle(psBase, hHandle, eType, IMG_NULL);
+               goto ExitUnlock;
+       }
+
+       eError = AdoptChild(psBase, psPHandleData, psCHandleData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Parent handle failed to adopt subhandle"));
+
+               (void)FreeHandle(psBase, hHandle, eType, IMG_NULL);
+               goto ExitUnlock;
+       }
+
+       *phHandle = hHandle;
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVFindHandle
+
+ @Description  Find handle corresponding to a resource pointer
+
+ @Input                phHandle - location for returned handle
+               pvData - pointer to resource to be associated with the handle
+               eType - the type of resource
+
+ @Output       phHandle - points to handle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase,
+                             IMG_HANDLE *phHandle,
+                             void *pvData,
+                             PVRSRV_HANDLE_TYPE eType)
+{
+       IMG_HANDLE hHandle;
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVFindHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       /* See if there is a handle for this data pointer */
+       hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
+       if (hHandle == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_HANDLE_NOT_FOUND;
+               goto ExitUnlock;
+       }
+
+       *phHandle = hHandle;
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVLookupHandle
+
+ @Description  Lookup the data pointer corresponding to a handle
+
+ @Input                ppvData - location to return data pointer
+               hHandle - handle from client
+               eType - handle type
+
+ @Output       ppvData - points to the data pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
+                               IMG_PVOID *ppvData,
+                               IMG_HANDLE hHandle,
+                               PVRSRV_HANDLE_TYPE eType)
+{
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVLookupHandle: Error looking up handle (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               OSDumpStack();
+               goto ExitUnlock;
+       }
+
+       *ppvData = psHandleData->pvData;
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVLookupSubHandle
+
+ @Description  Lookup the data pointer corresponding to a subhandle
+
+ @Input                ppvData - location to return data pointer
+               hHandle - handle from client
+               eType - handle type
+               hAncestor - ancestor handle
+
+ @Output       ppvData - points to the data pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase,
+                                  IMG_PVOID *ppvData,
+                                  IMG_HANDLE hHandle,
+                                  PVRSRV_HANDLE_TYPE eType,
+                                  IMG_HANDLE hAncestor)
+{
+       HANDLE_DATA *psPHandleData = IMG_NULL;
+       HANDLE_DATA *psCHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVLookupSubHandle: Error looking up subhandle (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               OSDumpStack();
+               goto ExitUnlock;
+       }
+
+       /* Look for hAncestor among the handle's ancestors */
+       for (psPHandleData = psCHandleData; ParentHandle(psPHandleData) != hAncestor; )
+       {
+               eError = GetHandleData(psBase, &psPHandleData, ParentHandle(psPHandleData), PVRSRV_HANDLE_TYPE_NONE);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
+                       eError = PVRSRV_ERROR_INVALID_SUBHANDLE;
+                       goto ExitUnlock;
+               }
+       }
+
+       *ppvData = psCHandleData->pvData;
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVGetParentHandle
+
+ @Description  Lookup the parent of a handle
+
+ @Input                phParent - location for returning parent handle
+               hHandle - handle for which the parent handle is required
+               eType - handle type
+               hParent - parent handle
+
+ @Output       *phParent - parent handle, or IMG_NULL if there is no parent
+
+ @Return       Error code or PVRSRV_OK.  Note that not having a parent is
+               not regarded as an error.
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase,
+                                  IMG_HANDLE *phParent,
+                                  IMG_HANDLE hHandle,
+                                  PVRSRV_HANDLE_TYPE eType)
+{
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVGetParentHandle: Error looking up subhandle (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               OSDumpStack();
+               goto ExitUnlock;
+       }
+
+       *phParent = ParentHandle(psHandleData);
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVReleaseHandle
+
+ @Description  Release a handle that is no longer needed
+
+ @Input        hHandle - handle from client
+               eType - handle type
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+                                IMG_HANDLE hHandle,
+                                PVRSRV_HANDLE_TYPE eType)
+{
+       PVRSRV_ERROR eError;
+
+       /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       eError = FreeHandle(psBase, hHandle, eType, IMG_NULL);
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVPurgeHandles
+
+ @Description  Purge handles for a given handle base
+
+ @Input        psBase - pointer to handle base structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Missing handle base"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ExitUnlock;
+       }
+
+       eError = gpsHandleFuncs->pfnPurgeHandles(psBase->psImplBase);
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVAllocHandleBase
+
+ @Description  Allocate a handle base structure for a process
+
+ @Input        ppsBase - pointer to handle base structure pointer
+
+ @Output       ppsBase - points to handle base structure pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+       PVRSRV_HANDLE_BASE *psBase;
+       PVRSRV_ERROR eError;
+
+       if (gpsHandleFuncs == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Handle management not initialised"));
+               return PVRSRV_ERROR_NOT_READY;
+       }
+
+       LockHandle();
+
+       if (ppsBase == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ErrorUnlock;
+       }
+
+       psBase = OSAllocZMem(sizeof(*psBase));
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto ErrorUnlock;
+       }
+
+       eError = gpsHandleFuncs->pfnCreateHandleBase(&psBase->psImplBase);
+       if (eError != PVRSRV_OK)
+       {
+               goto ErrorFreeHandleBase;
+       }
+
+       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"));
+               eError = PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+               goto ErrorDestroyHandleBase;
+       }
+
+       *ppsBase = psBase;
+
+       UnlockHandle();
+
+       return PVRSRV_OK;
+
+ErrorDestroyHandleBase:
+       (void)gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase);
+
+ErrorFreeHandleBase:
+       OSFreeMem(psBase);
+
+ErrorUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+#if defined(DEBUG)
+typedef struct _COUNT_HANDLE_DATA_
+{
+       PVRSRV_HANDLE_BASE *psBase;
+       IMG_UINT32 uiHandleDataCount;
+} COUNT_HANDLE_DATA;
+
+/* Used to count the number of handles that have data associated with them */
+static PVRSRV_ERROR CountHandleDataWrapper(IMG_HANDLE hHandle, void *pvData)
+{
+       COUNT_HANDLE_DATA *psData = (COUNT_HANDLE_DATA *)pvData;
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(gpsHandleFuncs);
+
+       if (psData == IMG_NULL ||
+           psData->psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "CountHandleDataWrapper: Missing free data"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       eError = GetHandleData(psData->psBase, 
+                              &psHandleData, 
+                              hHandle, 
+                              PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "CountHandleDataWrapper: Couldn't get handle data for handle"));
+               return eError;
+       }
+
+       if (psHandleData != IMG_NULL)
+       {
+               psData->uiHandleDataCount++;
+       }
+
+       return PVRSRV_OK;
+}
+#endif /* defined(DEBUG) */
+
+typedef struct FREE_HANDLE_DATA_TAG
+{
+       PVRSRV_HANDLE_BASE *psBase;
+       PVRSRV_HANDLE_TYPE eHandleFreeType;
+       /* timing data (ns) to release bridge lock upon the deadline */
+       IMG_UINT64 ui64TimeStart;
+       IMG_UINT64 ui64MaxBridgeTime;
+} FREE_HANDLE_DATA;
+
+static INLINE IMG_BOOL _CheckIfMaxTimeExpired(IMG_UINT64 ui64TimeStart, IMG_UINT64 ui64MaxBridgeTime)
+{
+       IMG_UINT64 ui64Diff;
+       IMG_UINT64 ui64Now = OSClockns64();
+
+       if(ui64Now >= ui64TimeStart)
+       {
+               ui64Diff = ui64Now - ui64TimeStart;
+       }
+       else
+       {
+               /* time has wrapped around */
+               ui64Diff = (0xFFFFFFFFFFFFFFFF - ui64TimeStart) + ui64Now;
+       }
+
+       return ui64Diff >= ui64MaxBridgeTime;
+}
+
+static PVRSRV_ERROR FreeHandleDataWrapper(IMG_HANDLE hHandle, void *pvData)
+{
+       FREE_HANDLE_DATA *psData = (FREE_HANDLE_DATA *)pvData;
+       HANDLE_DATA *psHandleData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(gpsHandleFuncs);
+
+       if (psData == IMG_NULL ||
+           psData->psBase == IMG_NULL ||
+           psData->eHandleFreeType == PVRSRV_HANDLE_TYPE_NONE)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "FreeHandleDataWrapper: Missing free data"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       eError = GetHandleData(psData->psBase, 
+                              &psHandleData, 
+                              hHandle, 
+                              PVRSRV_HANDLE_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "FreeHandleDataWrapper: Couldn't get handle data for handle"));
+               return eError;
+       }
+
+       if (psHandleData == IMG_NULL || psHandleData->eType != psData->eHandleFreeType)
+       {
+               return PVRSRV_OK;
+       }
+
+       PVR_ASSERT(psHandleData->ui32Refs > 0);
+
+       while (psHandleData->ui32Refs != 0)
+       {
+               if (psHandleData->pfnReleaseData != IMG_NULL)
+               {
+                       eError = psHandleData->pfnReleaseData(psHandleData->pvData);
+                       if (eError == PVRSRV_ERROR_RETRY)
+                       {
+                               PVR_DPF((PVR_DBG_MESSAGE,
+                                        "FreeHandleDataWrapper: "
+                                        "Got retry while calling release data callback for %p (type = %d)",
+                                        hHandle,
+                                        (IMG_UINT32)psHandleData->eType));
+
+                               return eError;
+                       }
+                       else if (eError != PVRSRV_OK)
+                       {
+                               return eError;
+                       }
+               }
+
+               psHandleData->ui32Refs--;
+       }
+
+       if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+       {
+               HAND_KEY aKey;
+               IMG_HANDLE hRemovedHandle;
+
+               InitKey(aKey,
+                       psData->psBase,
+                       psHandleData->pvData,
+                       psHandleData->eType,
+                       ParentIfPrivate(psHandleData));
+
+               hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psData->psBase->psHashTab, aKey);
+
+               PVR_ASSERT(hRemovedHandle != IMG_NULL);
+               PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
+               PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
+       }
+
+       eError = gpsHandleFuncs->pfnSetHandleData(psData->psBase->psImplBase, hHandle, IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       OSFreeMem(psHandleData);
+
+       /* If we reach the end of the time slice release we can release the global
+        * lock, invoke the scheduler and reacquire the lock */
+       if((psData->ui64MaxBridgeTime != 0) && _CheckIfMaxTimeExpired(psData->ui64TimeStart, psData->ui64MaxBridgeTime))
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "FreeResourceByCriteria: Lock timeout (timeout: %llu)",
+                                                                           psData->ui64MaxBridgeTime));
+               UnlockHandle();
+               OSReleaseBridgeLock();
+               /* Invoke the scheduler to check if other processes are waiting for the lock */
+               OSReleaseThreadQuanta();
+               OSAcquireBridgeLock();
+               LockHandle();
+               /* Set again lock timeout and reset the counter */
+               psData->ui64TimeStart = OSClockns64();
+               PVR_DPF((PVR_DBG_MESSAGE, "FreeResourceByCriteria: Lock acquired again"));
+       }
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_HANDLE_TYPE g_aeOrderedFreeList[] =
+{
+       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+       PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+       PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
+       PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+       PVRSRV_HANDLE_TYPE_RGX_RPM_CONTEXT_CLEANUP,
+       PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
+       PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK,
+       PVRSRV_HANDLE_TYPE_RGX_POPULATION,
+       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+       PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RI_HANDLE,
+       PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
+       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+       PVRSRV_HANDLE_TYPE_SERVER_SYNC_EXPORT,
+       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
+       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_PAGELIST,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+       PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
+       PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE,
+       PVRSRV_HANDLE_TYPE_DC_BUFFER,
+       PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+       PVRSRV_HANDLE_TYPE_DC_DEVICE,
+       PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+       PVRSRV_HANDLE_TYPE_DEV_NODE,
+       PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP
+};
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVFreeHandleBase
+
+ @Description  Free a handle base structure
+
+ @Input        psBase - pointer to handle base structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime)
+{
+#if defined(DEBUG)
+       COUNT_HANDLE_DATA sCountData = { 0 };
+#endif
+       FREE_HANDLE_DATA sHandleData = { 0 };
+       IMG_UINT32 i;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(gpsHandleFuncs);
+
+       LockHandle();
+
+       sHandleData.psBase = psBase;
+       sHandleData.ui64TimeStart = OSClockns64();
+       sHandleData.ui64MaxBridgeTime = ui64MaxBridgeTime;
+
+       for (i = 0; i < ARRAY_SIZE(g_aeOrderedFreeList); i++)
+       {
+               sHandleData.eHandleFreeType = g_aeOrderedFreeList[i];
+
+               /* Make sure all handles have been freed before destroying the handle base */
+               eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+                                                              &FreeHandleDataWrapper,
+                                                              (void *)&sHandleData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto ExitUnlock;
+               }
+       }
+
+#if defined(DEBUG)
+       /*
+        * As we're freeing handles based on type, make sure all
+        * handles have actually had their data freed to avoid
+        * resources being leaked
+        */
+       sCountData.psBase = psBase;
+
+       eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+                                                      &CountHandleDataWrapper,
+                                                      (void *)&sCountData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVFreeHandleBase: Failed to perform handle count (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               goto ExitUnlock;
+       }
+
+       if (sCountData.uiHandleDataCount != 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVFreeHandleBase: Found %u handles that need freeing for handle base %p",
+                        sCountData.uiHandleDataCount,
+                        psBase));
+               PVR_ASSERT(0);
+       }
+#endif /* defined(DEBUG) */
+
+       if (psBase->psHashTab != IMG_NULL)
+       {
+               HASH_Delete(psBase->psHashTab);
+       }
+
+       eError = gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase);
+       if (eError != PVRSRV_OK)
+       {
+               goto ExitUnlock;
+       }
+
+       OSFreeMem(psBase);
+
+       eError = PVRSRV_OK;
+
+ExitUnlock:
+       UnlockHandle();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVHandleInit
+
+ @Description  Initialise handle management
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVHandleInit(void)
+{
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(gpsKernelHandleBase == IMG_NULL);
+       PVR_ASSERT(gpsHandleFuncs == IMG_NULL);
+       PVR_ASSERT(!gbLockInitialised);
+
+       eError = OSLockCreate(&gHandleLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVHandleInit: Creation of handle global lock failed (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+       gbLockInitialised = IMG_TRUE;
+
+       eError = PVRSRVHandleGetFuncTable(&gpsHandleFuncs);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVHandleInit: PVRSRVHandleGetFuncTable failed (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               goto ErrorHandleDeinit;
+       }
+
+       eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               goto ErrorHandleDeinit;
+       }
+
+       eError = gpsHandleFuncs->pfnEnableHandlePurging(gpsKernelHandleBase->psImplBase);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%s)",
+                        PVRSRVGetErrorStringKM(eError)));
+               goto ErrorHandleDeinit;
+       }
+
+       return PVRSRV_OK;
+
+ErrorHandleDeinit:
+       (void) PVRSRVHandleDeInit();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVHandleDeInit
+
+ @Description  De-initialise handle management
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVHandleDeInit(void)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if (gpsHandleFuncs != IMG_NULL)
+       {
+               if (gpsKernelHandleBase != IMG_NULL)
+               {
+                       eError = PVRSRVFreeHandleBase(gpsKernelHandleBase, 0 /* do not release bridge lock */);
+                       if (eError == PVRSRV_OK)
+                       {
+                               gpsKernelHandleBase = IMG_NULL;
+                       }
+                       else
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                        "PVRSRVHandleDeInit: FreeHandleBase failed (%s)",
+                                        PVRSRVGetErrorStringKM(eError)));
+                       }
+               }
+
+               if (eError == PVRSRV_OK)
+               {
+                       gpsHandleFuncs = IMG_NULL;
+               }
+       }
+       else
+       {
+               /* If we don't have a handle function table we shouldn't have a handle base either */
+               PVR_ASSERT(gpsKernelHandleBase == IMG_NULL);
+       }
+
+       if (gbLockInitialised)
+       {
+               OSLockDestroy(gHandleLock);
+               gbLockInitialised = IMG_FALSE;
+       }
+
+       return eError;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/lists.c b/drivers/gpu/rogue_m/services/server/common/lists.c
new file mode 100644 (file)
index 0000000..b106d16
--- /dev/null
@@ -0,0 +1,135 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linked list shared functions implementation.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implementation of the list iterators for types shared among
+                more than one file in the services code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "lists.h"
+
+/*===================================================================
+  LIST ITERATOR FUNCTIONS USED IN MORE THAN ONE FILE (those used just
+  once are implemented locally).
+  ===================================================================*/
+
+IMPLEMENT_LIST_ANY(PVRSRV_DEVICE_NODE)
+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)
+
+
+/*===================================================================
+  BELOW ARE IMPLEMENTED SOME COMMON CALLBACKS USED IN DIFFERENT FILES
+  ===================================================================*/
+
+
+/*************************************************************************/ /*!
+@Function       MatchDeviceKM_AnyVaCb
+@Description    Matchs a device node with an id and optionally a class.
+@Input          psDeviceNode  Pointer to the device node.
+@Input          va            Variable argument list, with te following values:
+                                ui32DevIndex  Index of de device to match.
+                                bIgnoreClass  Flag indicating if there's
+                                              no need to check the device class.
+                                eDevClass     Device class, ONLY present if
+                                              bIgnoreClass was IMG_FALSE.
+@Return         The pointer to the device node if it matchs, IMG_NULL
+                otherwise.
+*/ /**************************************************************************/
+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
+       {
+               /*this value will never be used, since the short circuit evaluation
+               of the first clause will stop because bIgnoreClass is true, but the
+               compiler complains if it's not initialized.*/
+               eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
+       }
+
+       if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
+               psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
+       {
+               return psDeviceNode;
+       }
+       return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+@Function      MatchPowerDeviceIndex_AnyVaCb
+@Description    Matches a power device with its device index.
+@Input          va               Variable argument list
+                ui32DeviceIndex  Device index
+@Return         The pointer to the device it matched, IMG_NULL otherwise.
+******************************************************************************/
+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/gpu/rogue_m/services/server/common/mmu_common.c b/drivers/gpu/rogue_m/services/server/common/mmu_common.c
new file mode 100644 (file)
index 0000000..8e89acb
--- /dev/null
@@ -0,0 +1,3244 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common MMU Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements basic low level control of MMU.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "devicemem_server_utils.h"
+
+/* Our own interface */
+#include "mmu_common.h"
+
+/*
+Interfaces to other modules:
+
+Let's keep this graph up-to-date:
+
+   +-----------+
+   | devicemem |
+   +-----------+
+         |
+   +============+
+   | mmu_common |
+   +============+
+         |
+         +-----------------+
+         |                 |
+    +---------+      +----------+
+    |   pmr   |      |  device  |
+    +---------+      +----------+
+*/
+
+#include "img_types.h"
+#include "osfunc.h"
+#include "allocmem.h"
+#if defined(PDUMP)
+#include "pdump_km.h"
+#endif
+#include "pmr.h"
+/* include/ */
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv.h"
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "physmem_lma.h"
+#endif
+
+// #define MMU_OBJECT_REFCOUNT_DEBUGING 1
+#if defined (MMU_OBJECT_REFCOUNT_DEBUGING)
+#define MMU_OBJ_DBG(x) PVR_DPF(x);
+#else
+#define MMU_OBJ_DBG(x)
+#endif
+
+typedef IMG_UINT32 MMU_FLAGS_T;
+
+typedef enum _MMU_MOD_
+{
+       MMU_MOD_UNKNOWN = 0,
+       MMU_MOD_MAP,
+       MMU_MOD_UNMAP,
+} MMU_MOD;
+
+#if defined(SUPPORT_MMU_MODIFICATION_LOGGING)
+#define MMU_MODIFICATION_HISTORY 10
+#define MMU_MODIFICATION_MAX_ENTRIES 1024
+typedef struct _MMU_MOD_INFO_
+{
+       IMG_UINT32 ui32NextEntry;
+       MMU_MOD eModificationHistory[MMU_MODIFICATION_HISTORY];
+       IMG_UINT64 ui64Value[MMU_MODIFICATION_HISTORY];
+} MMU_MOD_INFO;
+#endif
+/*!
+       All physical allocations and frees are relative to this context, so
+       we would get all the allocations of PCs, PDs, and PTs from the same
+       RA.
+
+       We have one per MMU context in case we have mixed UMA/LMA devices
+       within the same system.
+*/
+typedef struct _MMU_PHYSMEM_CONTEXT_
+{
+       /*! Parent device node */
+       PVRSRV_DEVICE_NODE *psDevNode;
+
+       /*! Refcount so we know when to free up the arena */
+       IMG_UINT32 uiNumAllocations;
+
+       /*! Arena from which physical memory is derived */
+       RA_ARENA *psPhysMemRA;
+       /*! Arena name */
+       IMG_CHAR *pszPhysMemRAName;
+       /*! Size of arena name string */
+       IMG_SIZE_T uiPhysMemRANameAllocSize;
+
+} MMU_PHYSMEM_CONTEXT;
+
+/*!
+       Mapping structure for MMU memory allocation
+*/
+typedef struct _MMU_MEMORY_MAPPING_
+{
+       /*! Physmem context to allocate from */
+       MMU_PHYSMEM_CONTEXT             *psContext;
+       /*! OS/system Handle for this allocation */
+       Px_HANDLE                               sMemHandle;
+       /*! CPU virtual address of this allocation */
+       IMG_VOID                                *pvCpuVAddr;
+       /*! Device physical address of this allocation */
+       IMG_DEV_PHYADDR                 sDevPAddr;
+       /*! Size of this allocation */
+       IMG_SIZE_T                              uiSize;
+       /*! Number of current mappings of this allocation */
+       IMG_UINT32                              uiCpuVAddrRefCount;
+} MMU_MEMORY_MAPPING;
+
+/*!
+       Memory descriptor for MMU objects. There can be more then one memory
+       descriptor per MMU memory allocation.
+*/
+typedef struct _MMU_MEMORY_DESC_
+{
+       /* NB: bValid is set if this descriptor describes physical
+          memory.  This allows "empty" descriptors to exist, such that we
+          can allocate them in batches.  */
+       /*! Does this MMU object have physical backing */
+       IMG_BOOL                                bValid;
+       /*! Device Physical address of physical backing */
+       IMG_DEV_PHYADDR                 sDevPAddr;
+       /*! CPU virtual address of physical backing */
+       IMG_VOID                                *pvCpuVAddr;
+       /*! Mapping data for this MMU object */
+       MMU_MEMORY_MAPPING              *psMapping;
+} MMU_MEMORY_DESC;
+
+/*!
+       MMU levelx structure. This is generic and is used
+       for all levels (PC, PD, PT).
+*/
+typedef struct _MMU_Levelx_INFO_
+{
+       /*! The Number of entries in this level */
+       IMG_UINT32 ui32NumOfEntries;
+
+       /*! Number of times this level has been reference. Note: For Level1 (PTE)
+           we still take/drop the reference when setting up the page tables rather
+           then at map/unmap time as this simplifies things */
+       IMG_UINT32 ui32RefCount;
+
+       /*! MemDesc for this level */
+       MMU_MEMORY_DESC sMemDesc;
+
+#if defined(SUPPORT_MMU_MODIFICATION_LOGGING)
+       MMU_MOD_INFO asModifications[MMU_MODIFICATION_MAX_ENTRIES];
+#endif
+
+       /*! Array of infos for the next level. Must be last member in structure */
+       struct _MMU_Levelx_INFO_ *apsNextLevel[1];
+} MMU_Levelx_INFO;
+
+/*!
+       MMU context structure
+*/
+struct _MMU_CONTEXT_
+{
+       /*! Parent device node */
+       PVRSRV_DEVICE_NODE *psDevNode;
+
+       MMU_DEVICEATTRIBS *psDevAttrs;
+
+       /*! For allocation and deallocation of the physical memory where
+           the pagetables live */
+       struct _MMU_PHYSMEM_CONTEXT_ *psPhysMemCtx;
+
+#if defined(PDUMP)
+       /*! PDump context ID (required for PDump commands with virtual addresses) */
+       IMG_UINT32 uiPDumpContextID;
+
+       /*! The refcount of the PDump context ID */
+       IMG_UINT32 ui32PDumpContextIDRefCount;
+#endif
+
+       /*! Data that is passed back during device specific callbacks */
+       IMG_HANDLE hDevData;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+    IMG_UINT32  ui32OSid;
+       IMG_UINT32      ui32OSidReg;
+#endif 
+
+       /*! Lock to ensure exclusive access when manipulating the MMU context or
+        * reading and using its content
+        */
+       POS_LOCK hLock;
+       
+       /*! Base level info structure. Must be last member in structure */
+       MMU_Levelx_INFO sBaseLevelInfo;
+       /* NO OTHER MEMBERS AFTER THIS STRUCTURE ! */
+};
+
+/* useful macros */
+/* units represented in a bitfield */
+#define UNITS_IN_BITFIELD(Mask, Shift) ((Mask >> Shift) + 1)
+
+#define MMU_BAD_PHYS_ADDR 0xbadbad00badULL
+static const IMG_DEV_PHYADDR gsBadDevPhyAddr = {MMU_BAD_PHYS_ADDR};
+
+#if defined(DEBUG)
+static IMG_UINT32 FloorLog2(IMG_UINT64 ui64Val)
+{
+       IMG_UINT32 ui32Ret = 0;
+
+       while (ui64Val >>= 1)
+       {
+               ui32Ret++;
+       }
+
+       return ui32Ret;
+}
+#endif
+
+/*****************************************************************************
+ *                          Utility functions                                *
+ *****************************************************************************/
+
+/*************************************************************************/ /*!
+@Function       _CalcPCEIdx
+
+@Description    Calculate the page catalogue index
+
+@Input          sDevVAddr           Device virtual address
+
+@Input          psDevVAddrConfig    Configuration of the virtual address
+
+@Input          bRoundUp            Round up the index
+
+@Return         The page catalogue index
+*/
+/*****************************************************************************/
+static IMG_UINT32 _CalcPCEIdx(IMG_DEV_VIRTADDR sDevVAddr,
+                              const MMU_DEVVADDR_CONFIG *psDevVAddrConfig,
+                              IMG_BOOL bRoundUp)
+{
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+    IMG_UINT32 ui32RetVal;
+
+    sTmpDevVAddr = sDevVAddr;
+
+       if (bRoundUp)
+       {
+        sTmpDevVAddr.uiAddr --;
+    }
+    ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPCIndexMask)
+        >> psDevVAddrConfig->uiPCIndexShift);
+
+    if (bRoundUp)
+    {
+        ui32RetVal ++;
+    }
+
+    return ui32RetVal;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _CalcPCEIdx
+
+@Description    Calculate the page directory index
+
+@Input          sDevVAddr           Device virtual address
+
+@Input          psDevVAddrConfig    Configuration of the virtual address
+
+@Input          bRoundUp            Round up the index
+
+@Return         The page directory index
+*/
+/*****************************************************************************/
+static IMG_UINT32 _CalcPDEIdx(IMG_DEV_VIRTADDR sDevVAddr,
+                              const MMU_DEVVADDR_CONFIG *psDevVAddrConfig,
+                              IMG_BOOL bRoundUp)
+{
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+    IMG_UINT32 ui32RetVal;
+
+    sTmpDevVAddr = sDevVAddr;
+
+       if (bRoundUp)
+       {
+        sTmpDevVAddr.uiAddr --;
+    }
+    ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPDIndexMask)
+        >> psDevVAddrConfig->uiPDIndexShift);
+
+    if (bRoundUp)
+    {
+        ui32RetVal ++;
+    }
+        
+    return ui32RetVal;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _CalcPCEIdx
+
+@Description    Calculate the page entry index
+
+@Input          sDevVAddr           Device virtual address
+
+@Input          psDevVAddrConfig    Configuration of the virtual address
+
+@Input          bRoundUp            Round up the index
+
+@Return         The page entry index
+*/
+/*****************************************************************************/
+static IMG_UINT32 _CalcPTEIdx(IMG_DEV_VIRTADDR sDevVAddr,
+                              const MMU_DEVVADDR_CONFIG *psDevVAddrConfig,
+                              IMG_BOOL bRoundUp)
+{
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+    IMG_UINT32 ui32RetVal;
+
+    sTmpDevVAddr = sDevVAddr;
+
+       if (bRoundUp)
+       {
+        sTmpDevVAddr.uiAddr --;
+    }
+    ui32RetVal = (IMG_UINT32) ((sTmpDevVAddr.uiAddr & psDevVAddrConfig->uiPTIndexMask)
+        >> psDevVAddrConfig->uiPTIndexShift);
+
+    if (bRoundUp)
+    {
+        ui32RetVal ++;
+    }
+        
+    return ui32RetVal;
+}
+
+/*****************************************************************************
+ *         MMU memory allocation/management functions (mem desc)             *
+ *****************************************************************************/
+
+/*************************************************************************/ /*!
+@Function       _MMU_PhysMem_RAImportAlloc
+
+@Description    Imports MMU Px memory into the RA. This is where the
+                actual allocation of physical memory happens.
+
+@Input          hArenaHandle    Handle that was passed in during the
+                                creation of the RA
+
+@Input          uiSize          Size of the memory to import
+
+@Input          uiFlags         Flags that where passed in the allocation.
+
+@Output         puiBase         The address of where to insert this import
+
+@Output         puiActualSize   The actual size of the import
+
+@Output         phPriv          Handle which will be passed back when
+                                this import is freed
+
+@Return         IMG_TRUE if import alloc was successful, otherwise IMG_FALSE
+*/
+/*****************************************************************************/
+static IMG_BOOL _MMU_PhysMem_RAImportAlloc(RA_PERARENA_HANDLE hArenaHandle,
+                                           RA_LENGTH_T uiSize,
+                                           RA_FLAGS_T uiFlags,
+                                           RA_BASE_T *puiBase,
+                                           RA_LENGTH_T *puiActualSize,
+                                           RA_PERISPAN_HANDLE *phPriv)
+{
+       MMU_PHYSMEM_CONTEXT *psCtx = (MMU_PHYSMEM_CONTEXT *) hArenaHandle;
+       PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) psCtx->psDevNode;
+       MMU_MEMORY_MAPPING *psMapping;
+       PVRSRV_ERROR eError;
+
+       PVR_UNREFERENCED_PARAMETER(uiFlags);
+
+       psMapping = OSAllocMem(sizeof(MMU_MEMORY_MAPPING));
+       if (psMapping == IMG_NULL)
+       {
+               goto e0;
+       }
+
+       eError = psDevNode->pfnMMUPxAlloc(psDevNode, TRUNCATE_64BITS_TO_SIZE_T(uiSize), &psMapping->sMemHandle,
+                                                                               &psMapping->sDevPAddr);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       psMapping->psContext = psCtx;
+       psMapping->uiSize = TRUNCATE_64BITS_TO_SIZE_T(uiSize);
+
+       psMapping->uiCpuVAddrRefCount = 0;
+
+       *phPriv = (RA_PERISPAN_HANDLE) psMapping;
+
+       /* Note: This assumes this memory never gets paged out */
+       *puiBase = (RA_BASE_T)psMapping->sDevPAddr.uiAddr;
+       *puiActualSize = uiSize;
+
+       return IMG_TRUE;
+
+e1:
+       OSFreeMem(psMapping);
+e0:
+       return IMG_FALSE;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_PhysMem_RAImportFree
+
+@Description    Imports MMU Px memory into the RA. This is where the
+                actual free of physical memory happens.
+
+@Input          hArenaHandle    Handle that was passed in during the
+                                creation of the RA
+
+@Input          puiBase         The address of where to insert this import
+
+@Output         phPriv          Private data that the import alloc provided
+
+@Return         None
+*/
+/*****************************************************************************/
+static IMG_VOID _MMU_PhysMem_RAImportFree(RA_PERARENA_HANDLE hArenaHandle,
+                                          RA_BASE_T uiBase,
+                                          RA_PERISPAN_HANDLE hPriv)
+{
+       MMU_MEMORY_MAPPING *psMapping = (MMU_MEMORY_MAPPING *) hPriv;
+       MMU_PHYSMEM_CONTEXT *psCtx = (MMU_PHYSMEM_CONTEXT *) hArenaHandle;
+       PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) psCtx->psDevNode;
+
+       PVR_UNREFERENCED_PARAMETER(uiBase);
+
+       /* Check we have dropped all CPU mappings */
+       PVR_ASSERT(psMapping->uiCpuVAddrRefCount == 0);
+
+       psDevNode->pfnMMUPxFree(psDevNode, &psMapping->sMemHandle);
+       OSFreeMem(psMapping);
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_PhysMemAlloc
+
+@Description    Allocates physical memory for MMU objects
+
+@Input          psCtx           Physmem context to do the allocation from
+
+@Output         psMemDesc       Allocation description
+
+@Input          uiBytes         Size of the allocation in bytes
+
+@Input          uiAlignment     Alignment requirement of this allocation
+
+@Return         PVRSRV_OK if allocation was successful
+*/
+/*****************************************************************************/
+
+static PVRSRV_ERROR _MMU_PhysMemAlloc(MMU_PHYSMEM_CONTEXT *psCtx,
+                                      MMU_MEMORY_DESC *psMemDesc,
+                                      IMG_SIZE_T uiBytes,
+                                      IMG_SIZE_T uiAlignment)
+{
+       RA_BASE_T uiPhysAddr;
+       IMG_BOOL bStatus;
+
+       if (!psMemDesc || psMemDesc->bValid)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       bStatus = RA_Alloc(psCtx->psPhysMemRA,
+                                          uiBytes,
+                                          0, // flags
+                                          uiAlignment,
+                                          &uiPhysAddr,
+                                          IMG_NULL,
+                                          (RA_PERISPAN_HANDLE *) &psMemDesc->psMapping);
+       if(!bStatus)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_MMU_PhysMemAlloc: ERROR call to RA_Alloc() failed"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psMemDesc->bValid = IMG_TRUE;
+       psMemDesc->pvCpuVAddr = IMG_NULL;
+       psMemDesc->sDevPAddr.uiAddr = (IMG_UINTPTR_T) uiPhysAddr;
+
+#if !defined(SUPPORT_MMU_PxE_MAP_ON_DEMAND)
+       {
+               PVRSRV_ERROR eError;
+
+               if (psMemDesc->psMapping->uiCpuVAddrRefCount == 0)
+               {
+                       eError = psCtx->psDevNode->pfnMMUPxMap(psCtx->psDevNode,
+                                                                                       &psMemDesc->psMapping->sMemHandle,
+                                                                                       psMemDesc->psMapping->uiSize,
+                                                                                       &psMemDesc->psMapping->sDevPAddr,
+                                                                                       &psMemDesc->psMapping->pvCpuVAddr);
+                       if (eError != PVRSRV_OK)
+                       {
+                               RA_Free(psCtx->psPhysMemRA, psMemDesc->sDevPAddr.uiAddr);
+                               return eError;
+                       }
+               }
+
+               psMemDesc->psMapping->uiCpuVAddrRefCount++;
+               PVR_ASSERT(psMemDesc->psMapping->pvCpuVAddr != IMG_NULL);
+       
+               /* Work out the address for this mem desc */
+               psMemDesc->pvCpuVAddr = ((IMG_UINT8 *) psMemDesc->psMapping->pvCpuVAddr) + 
+                                                                       (psMemDesc->sDevPAddr.uiAddr -
+                                                                       psMemDesc->psMapping->sDevPAddr.uiAddr);
+       }
+#endif
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_PhysMemFree
+
+@Description    Allocates physical memory for MMU objects
+
+@Input          psCtx           Physmem context to do the free on
+
+@Input          psMemDesc       Allocation description
+
+@Return         None
+*/
+/*****************************************************************************/
+static IMG_VOID _MMU_PhysMemFree(MMU_PHYSMEM_CONTEXT *psCtx,
+                                     MMU_MEMORY_DESC *psMemDesc)
+{
+       RA_BASE_T uiPhysAddr;
+
+       PVR_ASSERT(psMemDesc->bValid);
+
+#if !defined(SUPPORT_MMU_PxE_MAP_ON_DEMAND)
+
+       if(--psMemDesc->psMapping->uiCpuVAddrRefCount == 0)
+       {
+               psCtx->psDevNode->pfnMMUPxUnmap(psCtx->psDevNode, &psMemDesc->psMapping->sMemHandle,
+                               psMemDesc->psMapping->pvCpuVAddr);
+
+               psMemDesc->psMapping->pvCpuVAddr = IMG_NULL;
+       }
+
+       psMemDesc->pvCpuVAddr = IMG_NULL;
+#endif
+
+       uiPhysAddr = psMemDesc->sDevPAddr.uiAddr;
+       RA_Free(psCtx->psPhysMemRA, uiPhysAddr);
+
+       psMemDesc->bValid = IMG_FALSE;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_MapCPUVAddr
+
+@Description    Map an allocation of physical memory for MMU objects
+                into the CPU address space
+
+@Input          psMemDesc       Allocation description
+
+@Return         PVRSRV_OK if map was successful
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR _MMU_MapCPUVAddr(MMU_MEMORY_DESC *psMMUMemDesc)
+{
+#if defined(SUPPORT_MMU_PxE_MAP_ON_DEMAND)
+       MMU_MEMORY_MAPPING *psMapping = psMMUMemDesc->psMapping;
+       MMU_PHYSMEM_CONTEXT *psCtx = psMapping->psContext;
+       PVRSRV_DEVICE_NODE *psDevNode = psCtx->psDevNode;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       /* There should only be one call to map */
+       PVR_ASSERT(psMMUMemDesc->pvCpuVAddr == IMG_NULL);
+
+       if (psMapping->uiCpuVAddrRefCount == 0)
+       {
+               
+               eError = psDevNode->pfnMMUPxMap(psDevNode,
+                                                                               &psMapping->sMemHandle,
+                                                                               psMapping->uiSize,
+                                                                               &psMapping->sDevPAddr,
+                                                                               &psMapping->pvCpuVAddr);
+       }
+       psMapping->uiCpuVAddrRefCount++;
+
+       PVR_ASSERT(psMapping->pvCpuVAddr != IMG_NULL);
+
+       /* Workout the address for this mem desc */
+       psMMUMemDesc->pvCpuVAddr = ((IMG_UINT8 *) psMapping->pvCpuVAddr) + 
+                                                               (psMMUMemDesc->psMapping->sDevPAddr.uiAddr -
+                                                               psMapping->sDevPAddr.uiAddr);
+
+       return eError;
+#else
+       return PVRSRV_OK;
+#endif
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_UnmapCPUVAddr
+
+@Description    Unmap an allocation of physical memory for MMU objects
+                from the CPU address space
+
+@Input          psMemDesc       Allocation description
+
+@Return         PVRSRV_OK if map was successful
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR _MMU_UnmapCPUVAddr(MMU_MEMORY_DESC *psMMUMemDesc)
+{
+#if defined(SUPPORT_MMU_PxE_MAP_ON_DEMAND)
+       MMU_MEMORY_MAPPING *psMapping = psMMUMemDesc->psMapping;
+       MMU_PHYSMEM_CONTEXT *psCtx = psMapping->psContext;
+       PVRSRV_DEVICE_NODE *psDevNode = psCtx->psDevNode;
+
+       if (--psMapping->uiCpuVAddrRefCount == 0)
+       {
+               psDevNode->pfnMMUPxUnmap(psDevNode, &psMapping->sMemHandle,
+                                                                       psMMUMemDesc->pvCpuVAddr);
+       }
+
+       psMMUMemDesc->pvCpuVAddr = IMG_NULL;
+#endif
+       return PVRSRV_OK;
+}
+
+
+/*****************************************************************************
+ *              MMU object allocation/management functions                   *
+ *****************************************************************************/
+
+#if defined(SUPPORT_MMU_MODIFICATION_LOGGING)
+static IMG_CHAR *_MMU_LogPxEModificationToString(MMU_MOD eMMUMod)
+{
+       switch(eMMUMod)
+       {
+               case MMU_MOD_UNKNOWN:
+                       return "Unknown";
+               case MMU_MOD_MAP:
+                       return "Map";
+               case MMU_MOD_UNMAP:
+                       return "Unmap";
+               default:
+                       break;
+       }
+       return "Bad enum";
+}
+
+static INLINE IMG_VOID _MMU_LogPxEModification(MMU_Levelx_INFO *psLevel, IMG_UINT32 ui32Index, MMU_MOD eMMUMod, IMG_UINT64 ui64Value)
+{
+       IMG_UINT32 ui32NextEntry = psLevel->asModifications[ui32Index].ui32NextEntry;
+
+       PVR_ASSERT(ui32Index < MMU_MODIFICATION_MAX_ENTRIES);
+       if (ui32Index < MMU_MODIFICATION_MAX_ENTRIES)
+       {
+               psLevel->asModifications[ui32Index].eModificationHistory[ui32NextEntry] = eMMUMod;
+               psLevel->asModifications[ui32Index].ui64Value[ui32NextEntry] = ui64Value;
+               psLevel->asModifications[ui32Index].ui32NextEntry = (ui32NextEntry + 1) % MMU_MODIFICATION_HISTORY;
+       }
+}
+
+static INLINE IMG_VOID _MMU_LogPxEDump(MMU_Levelx_INFO *psLevel, IMG_UINT32 ui32Index)
+{
+       IMG_UINT32 i;
+
+       PVR_ASSERT(ui32Index < MMU_MODIFICATION_MAX_ENTRIES);
+       if (ui32Index < MMU_MODIFICATION_MAX_ENTRIES)
+       {
+               for (i=0;i<MMU_MODIFICATION_HISTORY;i++)
+               {
+                       IMG_UINT32 ui32Tmp = (psLevel->asModifications[ui32Index].ui32NextEntry-1-i+MMU_MODIFICATION_HISTORY)%MMU_MODIFICATION_HISTORY;
+                       PVR_LOG(("Mod last - %d (index %d): Op = %s, Value = 0x%016llx", 
+                                       i,
+                                       ui32Tmp,
+                                       _MMU_LogPxEModificationToString(psLevel->asModifications[ui32Index].eModificationHistory[ui32Tmp]),
+                                       psLevel->asModifications[ui32Index].ui64Value[ui32Tmp]));
+                                       
+               }
+       }
+}
+#else  // defined(SUPPORT_MMU_MODIFICATION_LOGGING)
+static INLINE IMG_VOID _MMU_LogPxEModification(MMU_Levelx_INFO *psLevel, IMG_UINT32 ui32Index, MMU_MOD eMMUMod, IMG_UINT64 ui64Value)
+{
+       PVR_UNREFERENCED_PARAMETER(psLevel);
+       PVR_UNREFERENCED_PARAMETER(ui32Index);
+       PVR_UNREFERENCED_PARAMETER(eMMUMod);
+}
+
+static INLINE IMG_VOID _MMU_LogPxEDump(MMU_Levelx_INFO *psLevel, IMG_UINT32 ui32Index)
+{
+       PVR_UNREFERENCED_PARAMETER(psLevel);
+}
+#endif // defined(SUPPORT_MMU_MODIFICATION_LOGGING)
+
+
+static INLINE IMG_VOID _MMU_ConvertDevMemFlags(IMG_BOOL bInvalidate,
+                                               PVRSRV_MEMALLOCFLAGS_T uiMappingFlags,
+                                               MMU_PROTFLAGS_T *uiMMUProtFlags)
+{
+       /* Do flag conversion between devmem flags and MMU generic flags */
+
+       if (bInvalidate == IMG_FALSE)
+       {
+               *uiMMUProtFlags |= ( (uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK)
+                                                       >> PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET)
+                                                       << MMU_PROTFLAGS_DEVICE_OFFSET;
+
+               if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_GPU_READABLE)
+               {
+                       *uiMMUProtFlags |= MMU_PROTFLAGS_READABLE;
+               }
+               if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE)
+               {
+                       *uiMMUProtFlags |= MMU_PROTFLAGS_WRITEABLE;
+               }
+
+               switch ( DevmemDeviceCacheMode(uiMappingFlags) )
+               {
+                       case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED:
+                       case PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE:
+                                       break;
+                       case PVRSRV_MEMALLOCFLAG_GPU_CACHED:
+                                       *uiMMUProtFlags |= MMU_PROTFLAGS_CACHED;
+                                       break;
+                       default:
+                                       PVR_DPF((PVR_DBG_ERROR,"_MMU_DerivePTProtFlags: Wrong parameters"));
+                                       return;
+               }
+
+               if (DevmemDeviceCacheCoherency(uiMappingFlags))
+               {
+                       *uiMMUProtFlags |= MMU_PROTFLAGS_CACHE_COHERENT;
+               }
+       }
+       else
+       {
+               *uiMMUProtFlags |= MMU_PROTFLAGS_INVALID;
+       }
+}
+
+/*************************************************************************/ /*!
+@Function       _PxMemAlloc
+
+@Description    Allocates physical memory for MMU objects, initialises
+                and PDumps it.
+
+@Input          psMMUContext    MMU context
+
+@Input          uiNumEntries    Number of entries to allocate
+
+@Input          psConfig        MMU Px config
+
+@Input          eMMULevel       MMU level that that allocation is for
+
+@Output         psMemDesc       Description of allocation
+
+@Return         PVRSRV_OK if allocation was successful
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR _PxMemAlloc(MMU_CONTEXT *psMMUContext,
+                                                               IMG_UINT32 uiNumEntries,
+                                                               const MMU_PxE_CONFIG *psConfig,
+                                                               MMU_LEVEL eMMULevel,
+                                                               MMU_MEMORY_DESC *psMemDesc,
+                                                               IMG_UINT8 uiLog2Align)
+{
+       PVRSRV_ERROR eError;
+       IMG_SIZE_T uiBytes;
+       IMG_SIZE_T uiAlign;
+#if defined(PDUMP)
+       PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psDevNode;
+#endif
+       PVR_ASSERT(psConfig->uiBytesPerEntry != 0);
+
+       uiBytes = uiNumEntries * psConfig->uiBytesPerEntry;
+       /* We need here the alignment of the previous level because that is the entry for we generate here */
+       uiAlign = 1 << uiLog2Align;
+
+       /*  allocate the object */
+       eError = _MMU_PhysMemAlloc(psMMUContext->psPhysMemCtx,
+                                                               psMemDesc, uiBytes, uiAlign);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_PxMemAlloc: failed to allocate memory for the  MMU object"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       /*
+               some OS's can alloc memory without a CPU ptr.
+               Map the memory to the CPU (may be a no-op) 
+       */
+       eError = _MMU_MapCPUVAddr(psMemDesc);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_PxMemAlloc: failed to map MMU object to CPU"));
+               eError = PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+               goto e1;
+       }
+
+       /*
+               Clear the object
+               Note: if any MMUs are cleared with non-zero values then will need a custom
+               clear function
+       */
+       OSMemSet(psMemDesc->pvCpuVAddr, 0, uiBytes);
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Alloc MMU object");
+
+       PDumpMMUMalloc(psDevNode->pszMMUPxPDumpMemSpaceName,
+                   eMMULevel,
+                   &psMemDesc->sDevPAddr,
+                   uiBytes,
+                   uiAlign);
+       
+       PDumpMMUDumpPxEntries(eMMULevel,
+                                                 psDevNode->pszMMUPxPDumpMemSpaceName,
+                                                 psMemDesc->pvCpuVAddr,
+                                                 psMemDesc->sDevPAddr,
+                                                 0,
+                                                 uiNumEntries,
+                                                 IMG_NULL, IMG_NULL, 0, /* pdump symbolic info is irrelevant here */
+                                                 psConfig->uiBytesPerEntry,
+                                                 uiLog2Align,
+                                                 psConfig->uiAddrShift,
+                                                 psConfig->uiAddrMask,
+                                                 psConfig->uiProtMask,
+                                                 0);
+#endif
+
+       /* unmap the memory from the CPU (may be a no-op) */
+       _MMU_UnmapCPUVAddr(psMemDesc);
+
+       return PVRSRV_OK;
+
+e1:
+       _MMU_PhysMemFree(psMMUContext->psPhysMemCtx, psMemDesc);
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       _PxMemFree
+
+@Description    Frees physical memory for MMU objects, de-initialises
+                and PDumps it.
+
+@Input          psMemDesc       Description of allocation
+
+@Return         PVRSRV_OK if allocation was successful
+*/
+/*****************************************************************************/
+
+static IMG_VOID _PxMemFree(MMU_CONTEXT *psMMUContext,
+                                                       MMU_MEMORY_DESC *psMemDesc, MMU_LEVEL eMMULevel)
+{
+#if defined(PDUMP)
+       PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psDevNode;
+#endif
+#if defined(MMU_CLEARMEM_ON_FREE)
+       PVRSRV_ERROR eError;
+       /*
+               some OS's can alloc memory without a CPU ptr.
+               Map the memory to the CPU (may be a no-op) 
+       */
+       eError = _MMU_MapCPUVAddr(psMemDesc);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_PxMemFree: failed to map MMU object to CPU"));
+               PVR_ASSERT(0);
+       }
+
+       /*
+               Clear the MMU object
+               Note: if any MMUs are cleared with non-zero values then will need a custom
+               clear function
+       */
+       OSMemSet(psMemDesc->pvCpuVAddr, 0, psMemDesc->ui32Bytes);
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Clear MMU object before freeing it");
+#endif
+
+       /* unmap the memory from the CPU (may be a no-op) */
+       _MMU_UnmapCPUVAddr(psMemDesc);
+#endif/* MMU_CLEARMEM_ON_FREE */
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Free MMU object");
+       {
+               PDumpMMUFree(psDevNode->pszMMUPxPDumpMemSpaceName, eMMULevel, &psMemDesc->sDevPAddr);
+       }
+#else
+       PVR_UNREFERENCED_PARAMETER(eMMULevel);
+#endif
+       /*  free the PC */
+       _MMU_PhysMemFree(psMMUContext->psPhysMemCtx, psMemDesc);
+}
+
+static PVRSRV_ERROR _SetupPTE(MMU_CONTEXT *psMMUContext,
+                              MMU_Levelx_INFO *psLevel,
+                              IMG_UINT32 uiIndex,
+                              const MMU_PxE_CONFIG *psConfig,
+                              const IMG_DEV_PHYADDR *psDevPAddr,
+                              IMG_BOOL bUnmap,
+#if defined(PDUMP)
+                              const IMG_CHAR *pszMemspaceName,
+                              const IMG_CHAR *pszSymbolicAddr,
+                              IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset,
+#endif
+                              IMG_UINT64 uiProtFlags)
+{
+       MMU_MEMORY_DESC *psMemDesc = &psLevel->sMemDesc;
+       IMG_UINT64 ui64PxE64;
+
+       /* Calculate Entry */
+       ui64PxE64 =    psDevPAddr->uiAddr /* Calculate the offset to that base */
+                   >> psConfig->uiLog2Align /* Shift away the useless bits, because the alignment is very coarse and we address by alignment */
+                   << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */
+                    & psConfig->uiAddrMask; /* Delete unused bits */
+       ui64PxE64 |= uiProtFlags;
+
+       /* Set the entry */
+       if (psConfig->uiBytesPerEntry == 8)
+       {
+               IMG_UINT64 *pui64Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */
+
+               pui64Px[uiIndex] = ui64PxE64;
+       }
+       else if (psConfig->uiBytesPerEntry == 4)
+       {
+               IMG_UINT32 *pui32Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */
+
+               /* assert that the result fits into 32 bits before writing
+                  it into the 32-bit array with a cast */
+               PVR_ASSERT(ui64PxE64 == (ui64PxE64 & 0xffffffffU));
+
+               pui32Px[uiIndex] = (IMG_UINT32) ui64PxE64;
+       }
+       else
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+
+       /* Log modification */
+       _MMU_LogPxEModification(psLevel,
+                               uiIndex,
+                               (bUnmap == IMG_TRUE)?MMU_MOD_UNMAP:MMU_MOD_MAP,
+                               ui64PxE64);
+
+#if defined (PDUMP)
+       PDumpMMUDumpPxEntries(MMU_LEVEL_1,
+                                                 psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName,
+                                                 psMemDesc->pvCpuVAddr,
+                                                 psMemDesc->sDevPAddr,
+                                                 uiIndex,
+                                                 1,
+                                                 pszMemspaceName,
+                                                 pszSymbolicAddr,
+                                                 uiSymbolicAddrOffset,
+                                                 psConfig->uiBytesPerEntry,
+                                                 psConfig->uiLog2Align,
+                                                 psConfig->uiAddrShift,
+                                                 psConfig->uiAddrMask,
+                                                 psConfig->uiProtMask,
+                                                 0);
+#endif /*PDUMP*/
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       _SetupPxE
+
+@Description    Sets up an entry of an MMU object to point to the
+                provided address
+
+@Input          psMMUContext    MMU context to operate on
+
+@Input          psLevel         Level info for MMU object
+
+@Input          uiIndex         Index into the MMU object to setup
+
+@Input          psConfig        MMU Px config
+
+@Input          eMMULevel       Level of MMU object
+
+@Input          psDevPAddr      Address to setup the MMU object to point to
+
+@Input          pszMemspaceName Name of the PDump memory space that the entry
+                                will point to
+
+@Input          pszSymbolicAddr PDump symbolic address that the entry will
+                                point to
+
+@Input          uiProtFlags     MMU protection flags
+
+@Return         PVRSRV_OK if the setup was successful
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR _SetupPxE(MMU_CONTEXT *psMMUContext,
+                                                               MMU_Levelx_INFO *psLevel,
+                                                               IMG_UINT32 uiIndex,
+                                                               const MMU_PxE_CONFIG *psConfig,
+                                                               MMU_LEVEL eMMULevel,
+                                                               const IMG_DEV_PHYADDR *psDevPAddr,
+#if defined(PDUMP)
+                                                               const IMG_CHAR *pszMemspaceName,
+                                                               const IMG_CHAR *pszSymbolicAddr,
+                                                               IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset,
+#endif
+                                                               MMU_FLAGS_T uiProtFlags,
+                                                               IMG_UINT8 uiLog2PageSize)
+{
+       PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psDevNode;
+       MMU_MEMORY_DESC *psMemDesc = &psLevel->sMemDesc;
+       PVRSRV_ERROR eError;
+
+       IMG_UINT32 (*pfnDerivePxEProt4)(IMG_UINT32);
+       IMG_UINT64 (*pfnDerivePxEProt8)(IMG_UINT32, IMG_UINT8);
+
+       if (!psDevPAddr)
+       {
+               /* Invalidate entry */
+               if (~uiProtFlags & MMU_PROTFLAGS_INVALID)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Error, no physical address specified, but not invalidating entry"));
+                       uiProtFlags |= MMU_PROTFLAGS_INVALID;
+               }
+               psDevPAddr = &gsBadDevPhyAddr;
+       }
+       else
+       {
+               if (uiProtFlags & MMU_PROTFLAGS_INVALID)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "A physical address was specified when requesting invalidation of entry"));
+                       uiProtFlags |= MMU_PROTFLAGS_INVALID;
+               }
+       }
+
+       switch(eMMULevel)
+       {
+               case MMU_LEVEL_3:
+                               pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePCEProt4;
+                               pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePCEProt8;
+                               break;
+
+               case MMU_LEVEL_2:
+                               pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePDEProt4;
+                               pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePDEProt8;
+                               break;
+
+               case MMU_LEVEL_1:
+                               pfnDerivePxEProt4 = psMMUContext->psDevAttrs->pfnDerivePTEProt4;
+                               pfnDerivePxEProt8 = psMMUContext->psDevAttrs->pfnDerivePTEProt8;
+                               break;
+
+               default:
+                               PVR_DPF((PVR_DBG_ERROR, "%s: invalid MMU level", __func__));
+                               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Map the Page Catalogue into CPU virtual memory */
+       eError = _MMU_MapCPUVAddr(psMemDesc);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: failed to map Px to CPU", __func__));
+               return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+       }
+
+       /* How big is a PxE in bytes? */
+       /* Filling the actual Px entry with an address */
+       switch(psConfig->uiBytesPerEntry)
+       {
+               case 4:
+               {
+                       IMG_UINT32 *pui32Px;
+                       IMG_UINT64 ui64PxE64;
+
+                       pui32Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */
+
+                       ui64PxE64 = psDevPAddr->uiAddr /* Calculate the offset to that base */
+                                                       >> psConfig->uiLog2Align /* Shift away the useless bits, because the alignment is very coarse and we address by alignment */
+                                                       << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */
+                                                       & psConfig->uiAddrMask; /* Delete unused bits */
+
+                       ui64PxE64 |= (IMG_UINT64)pfnDerivePxEProt4(uiProtFlags);
+                       /* assert that the result fits into 32 bits before writing
+                          it into the 32-bit array with a cast */
+                       PVR_ASSERT(ui64PxE64 == (ui64PxE64 & 0xffffffffU));
+
+                       /* We should never invalidate an invalid page */
+                       if (uiProtFlags & MMU_PROTFLAGS_INVALID)
+                       {
+                               PVR_ASSERT(pui32Px[uiIndex] != ui64PxE64);
+                       }
+                       pui32Px[uiIndex] = (IMG_UINT32) ui64PxE64;
+                       _MMU_LogPxEModification(psLevel,
+                                                                       uiIndex,
+                                                                       (uiProtFlags & MMU_PROTFLAGS_INVALID)?MMU_MOD_UNMAP:MMU_MOD_MAP,
+                                                                       ui64PxE64);
+                       break;  
+               }
+               case 8:
+               {
+                       IMG_UINT64 *pui64Px = psMemDesc->pvCpuVAddr; /* Give the virtual base address of Px */
+                       
+                       pui64Px[uiIndex] = psDevPAddr->uiAddr  /* Calculate the offset to that base */
+                                                               >> psConfig->uiLog2Align
+                                                               << psConfig->uiAddrShift
+                                                               & psConfig->uiAddrMask;
+                       pui64Px[uiIndex] |= pfnDerivePxEProt8(uiProtFlags, uiLog2PageSize);
+
+                       _MMU_LogPxEModification(psLevel,
+                                                                       uiIndex,
+                                                                       (uiProtFlags & MMU_PROTFLAGS_INVALID)?MMU_MOD_UNMAP:MMU_MOD_MAP,
+                                                                       pui64Px[uiIndex]);
+                       break;  
+               }
+               default:
+                       PVR_DPF((PVR_DBG_ERROR, "%s: PxE size not supported (%d) for level %d",
+                                                                       __func__, psConfig->uiBytesPerEntry, eMMULevel));
+
+                       _MMU_UnmapCPUVAddr(psMemDesc);
+
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+#if defined (PDUMP)
+       PDumpMMUDumpPxEntries(eMMULevel,
+                                                 psDevNode->pszMMUPxPDumpMemSpaceName,
+                                                 psMemDesc->pvCpuVAddr,
+                                                 psMemDesc->sDevPAddr,
+                                                 uiIndex,
+                                                 1,
+                                                 pszMemspaceName,
+                                                 pszSymbolicAddr,
+                                                 uiSymbolicAddrOffset,
+                                                 psConfig->uiBytesPerEntry,
+                                                 psConfig->uiLog2Align,
+                                                 psConfig->uiAddrShift,
+                                                 psConfig->uiAddrMask,
+                                                 psConfig->uiProtMask,
+                                                 0);
+#endif
+
+       psDevNode->pfnMMUCacheInvalidate(psDevNode, psMMUContext->hDevData,
+                                                                        eMMULevel,
+                                                                        (uiProtFlags & MMU_PROTFLAGS_INVALID)?IMG_TRUE:IMG_FALSE);
+
+
+       /* unmap the memory from the CPU (may be a no-op) */
+       eError = _MMU_UnmapCPUVAddr(psMemDesc);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: failed to release the CPU mapping", __func__));
+               return PVRSRV_ERROR_MMU_FAILED_TO_UNMAP_PAGE_TABLE;
+       }
+       
+       return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ *                   MMU host control functions (Level Info)                 *
+ *****************************************************************************/
+
+
+/*************************************************************************/ /*!
+@Function       _MMU_FreeLevel
+
+@Description    Recursively frees the specified range of Px entries. If any
+                level has its last reference dropped then the MMU object
+                memory and the MMU_Levelx_Info will be freed.
+
+                               At each level we might be crossing a boundary from one Px to
+                               another. The values for auiStartArray should be by used for
+                               the first call into each level and the values in auiEndArray
+                               should only be used in the last call for each level.
+                               In order to determine if this is the first/last call we pass
+                               in bFirst and bLast.
+                               When one level calls down to the next only if bFirst/bLast is set
+                               and it's the first/last iteration of the loop at its level will
+                               bFirst/bLast set for the next recursion.
+                               This means that each iteration has the knowledge of the previous
+                               level which is required.
+
+@Input          psMMUContext    MMU context to operate on
+
+@Input          psLevel                 Level info on which to to free the
+                                        specified range
+
+@Input          auiStartArray           Array of start indexes (one for each level)
+
+@Input          auiEndArray             Array of end indexes (one for each level)
+
+@Input          auiEntriesPerPxArray    Array of number of entries for the Px
+                                        (one for each level)
+
+@Input          apsConfig               Array of PxE configs (one for each level)
+
+@Input          aeMMULevel              Array of MMU levels (one for each level)
+
+@Input          pui32CurrentLevel       Pointer to a variable which is set to our
+                                        current level 
+
+@Input          uiStartIndex            Start index of the range to free
+
+@Input          uiEndIndex              End index of the range to free
+
+@Input                 bFirst                  This is the first call for this level
+
+@Input                 bLast                   This is the last call for this level
+
+@Return         IMG_TRUE if the last reference to psLevel was dropped
+*/
+/*****************************************************************************/
+static IMG_BOOL _MMU_FreeLevel(MMU_CONTEXT *psMMUContext,
+                                                               MMU_Levelx_INFO *psLevel,
+                                                               IMG_UINT32 auiStartArray[],
+                                                               IMG_UINT32 auiEndArray[],
+                                                               IMG_UINT32 auiEntriesPerPxArray[],
+                                                               const MMU_PxE_CONFIG *apsConfig[],
+                                                               MMU_LEVEL aeMMULevel[],
+                                                               IMG_UINT32 *pui32CurrentLevel,
+                                                               IMG_UINT32 uiStartIndex,
+                                                               IMG_UINT32 uiEndIndex,
+                                                               IMG_BOOL bFirst,
+                                                               IMG_BOOL bLast)
+{
+       IMG_UINT32 uiThisLevel = *pui32CurrentLevel;
+       const MMU_PxE_CONFIG *psConfig = apsConfig[uiThisLevel];
+       IMG_UINT32 i;
+       IMG_BOOL bFreed = IMG_FALSE;
+       IMG_UINT8 uiLog2PageSize;
+
+       /* Sanity check */
+       PVR_ASSERT(*pui32CurrentLevel < MMU_MAX_LEVEL);
+       PVR_ASSERT(psLevel != IMG_NULL);
+
+       MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_FreeLevel: level = %d, range %d - %d, refcount = %d",
+                               aeMMULevel[uiThisLevel], uiStartIndex,
+                               uiEndIndex, psLevel->ui32RefCount));
+
+       for (i = uiStartIndex;(i < uiEndIndex) && (psLevel != IMG_NULL);i++)
+       {
+               if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
+               {
+                       MMU_Levelx_INFO *psNextLevel = psLevel->apsNextLevel[i];
+                       IMG_UINT32 uiNextStartIndex;
+                       IMG_UINT32 uiNextEndIndex;
+                       IMG_BOOL bNextFirst;
+                       IMG_BOOL bNextLast;
+
+                       /* If we're crossing a Px then the start index changes */
+                       if (bFirst && (i == uiStartIndex))
+                       {
+                               uiNextStartIndex = auiStartArray[uiThisLevel + 1];
+                               bNextFirst = IMG_TRUE;
+                       }
+                       else
+                       {
+                               uiNextStartIndex = 0;
+                               bNextFirst = IMG_FALSE;
+                       }
+
+                       /* If we're crossing a Px then the end index changes */
+                       if (bLast && (i == (uiEndIndex - 1)))
+                       {
+                               uiNextEndIndex = auiEndArray[uiThisLevel + 1];
+                               bNextLast = IMG_TRUE;
+                       }
+                       else
+                       {
+                               uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1];
+                               bNextLast = IMG_FALSE;
+                       }
+
+                       /* Recurse into the next level */
+                       (*pui32CurrentLevel)++;
+                       if (_MMU_FreeLevel(psMMUContext, psNextLevel, auiStartArray,
+                                                               auiEndArray, auiEntriesPerPxArray,
+                                                               apsConfig, aeMMULevel, pui32CurrentLevel,
+                                                               uiNextStartIndex, uiNextEndIndex,
+                                                               bNextFirst, bNextLast))
+                       {
+                               /* The level below us is empty, drop the refcount and clear the pointer */
+                               psLevel->ui32RefCount--;
+                               psLevel->apsNextLevel[i] = IMG_NULL;
+
+                               /* Level 1 PTE reprogramming is done in the unmap */
+                               if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
+                               {
+                                       PVRSRV_ERROR eError;
+                                       /* Take the page size from the page table configs.
+                                          Calculate array entry for PT config dependent on max MMU level */
+                                       uiLog2PageSize = apsConfig[MMU_MAX_LEVEL-1]->uiLog2Align;
+                                       /* Un-wire the entry */
+                                       eError = _SetupPxE(psMMUContext,
+                                                                       psLevel,
+                                                                       i,
+                                                                       psConfig,
+                                                                       aeMMULevel[uiThisLevel],
+                                                                       IMG_NULL,
+#if defined(PDUMP)
+                                                                       IMG_NULL,       /* Only required for data page */
+                                                                       IMG_NULL,       /* Only required for data page */
+                                                                       0,                      /* Only required for data page */
+#endif
+                                                                       MMU_PROTFLAGS_INVALID,
+                                                                       uiLog2PageSize);                
+
+                                       PVR_ASSERT(eError == PVRSRV_OK);
+                               }
+
+
+                               /* Check we haven't wrapped around */
+                               PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+                       }
+                       (*pui32CurrentLevel)--;
+               }
+               else
+               {
+                       psLevel->ui32RefCount--;
+               }
+
+               /*
+                  Free this level if it is no longer referenced, unless it's the base
+                  level in which case it's part of the MMU context and should be freed
+                  when the MMU context is freed
+               */
+               if ((psLevel->ui32RefCount == 0) && (psLevel != &psMMUContext->sBaseLevelInfo))
+               {
+                       _PxMemFree(psMMUContext, &psLevel->sMemDesc, aeMMULevel[uiThisLevel]);
+                       OSFreeMem(psLevel);
+                       psLevel = IMG_NULL;
+                       bFreed = IMG_TRUE;
+               }
+       }
+       MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_FreeLevel end: level = %d, refcount = %d",
+                               aeMMULevel[uiThisLevel], bFreed?0:psLevel->ui32RefCount));
+
+       return bFreed;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_AllocLevel
+
+@Description    Recursively allocates the specified range of Px entries. If any
+                level has its last reference dropped then the MMU object
+                memory and the MMU_Levelx_Info will be freed.
+
+                               At each level we might be crossing a boundary from one Px to
+                               another. The values for auiStartArray should be by used for
+                               the first call into each level and the values in auiEndArray
+                               should only be used in the last call for each level.
+                               In order to determine if this is the first/last call we pass
+                               in bFirst and bLast.
+                               When one level calls down to the next only if bFirst/bLast is set
+                               and it's the first/last iteration of the loop at its level will
+                               bFirst/bLast set for the next recursion.
+                               This means that each iteration has the knowledge of the previous
+                               level which is required.
+
+@Input          psMMUContext    MMU context to operate on
+
+@Input          psLevel                 Level info on which to to free the
+                                        specified range
+
+@Input          auiStartArray           Array of start indexes (one for each level)
+
+@Input          auiEndArray             Array of end indexes (one for each level)
+
+@Input          auiEntriesPerPxArray    Array of number of entries for the Px
+                                        (one for each level)
+
+@Input          apsConfig               Array of PxE configs (one for each level)
+
+@Input          aeMMULevel              Array of MMU levels (one for each level)
+
+@Input          pui32CurrentLevel       Pointer to a variable which is set to our
+                                        current level 
+
+@Input          uiStartIndex            Start index of the range to free
+
+@Input          uiEndIndex              End index of the range to free
+
+@Input                 bFirst                  This is the first call for this level
+
+@Input                 bLast                   This is the last call for this level
+
+@Return         IMG_TRUE if the last reference to psLevel was dropped
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR _MMU_AllocLevel(MMU_CONTEXT *psMMUContext,
+                                                                       MMU_Levelx_INFO *psLevel,
+                                                                       IMG_UINT32 auiStartArray[],
+                                                                       IMG_UINT32 auiEndArray[],
+                                                                       IMG_UINT32 auiEntriesPerPxArray[],
+                                                                       const MMU_PxE_CONFIG *apsConfig[],
+                                                                       MMU_LEVEL aeMMULevel[],
+                                                                       IMG_UINT32 *pui32CurrentLevel,
+                                                                       IMG_UINT32 uiStartIndex,
+                                                                       IMG_UINT32 uiEndIndex,
+                                                                       IMG_BOOL bFirst,
+                                                                       IMG_BOOL bLast)
+{
+       IMG_UINT32 uiThisLevel = *pui32CurrentLevel; /* Starting with 0 */
+       const MMU_PxE_CONFIG *psConfig = apsConfig[uiThisLevel]; /* The table config for the current level */
+       PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       IMG_UINT32 uiAllocState = 99; /* Debug info to check what progress was made in the function. Updated during this function. */
+       IMG_UINT32 i;
+
+       /* Sanity check */
+       PVR_ASSERT(*pui32CurrentLevel < MMU_MAX_LEVEL);
+
+       MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_AllocLevel: level = %d, range %d - %d, refcount = %d",
+                               aeMMULevel[uiThisLevel], uiStartIndex,
+                               uiEndIndex, psLevel->ui32RefCount));
+
+       /* Go from uiStartIndex to uiEndIndex through the Px */
+       for (i = uiStartIndex;i < uiEndIndex;i++) 
+       {
+               /* Only try an allocation if this is not the last level */
+               /*Because a PT allocation is already done while setting the entry in PD */
+               if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
+               {
+                       IMG_UINT32 uiNextStartIndex;
+                       IMG_UINT32 uiNextEndIndex;
+                       IMG_BOOL bNextFirst;
+                       IMG_BOOL bNextLast;
+                       IMG_UINT8 uiLog2PageSize;
+
+                       /* If there is already a next Px level existing, do not allocate it */
+                       if (!psLevel->apsNextLevel[i])
+                       {
+                               MMU_Levelx_INFO *psNextLevel;
+                               IMG_UINT32 ui32AllocSize;
+                               IMG_UINT32 uiNextEntries;
+
+                               /* Allocate and setup the next level */
+                               uiNextEntries = auiEntriesPerPxArray[uiThisLevel + 1];
+                               ui32AllocSize = sizeof(MMU_Levelx_INFO);
+                               if (aeMMULevel[uiThisLevel + 1] != MMU_LEVEL_1)
+                               {
+                                       ui32AllocSize += sizeof(MMU_Levelx_INFO *) * (uiNextEntries - 1);
+                               }
+                               psNextLevel = OSAllocMem(ui32AllocSize);
+                               if (psNextLevel == IMG_NULL)
+                               {
+                                       uiAllocState = 0;
+                                       goto e0;
+                               }
+                               OSMemSet(psNextLevel, 0, ui32AllocSize);
+
+                               /* Hook in this level for next time */
+                               psLevel->apsNextLevel[i] = psNextLevel;
+
+                               psNextLevel->ui32NumOfEntries = uiNextEntries;
+                               psNextLevel->ui32RefCount = 0;
+                               /* Allocate Px memory for a sub level*/
+                               eError = _PxMemAlloc(psMMUContext, uiNextEntries, apsConfig[uiThisLevel + 1],
+                                                                               aeMMULevel[uiThisLevel + 1],
+                                                                               &psNextLevel->sMemDesc,
+                                                                               psConfig->uiLog2Align);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       uiAllocState = 1;
+                                       goto e0;
+                               }
+
+                               uiLog2PageSize = apsConfig[MMU_MAX_LEVEL-1]->uiLog2Align;
+                               /* Wire up the entry */
+                               eError = _SetupPxE(psMMUContext,
+                                                                       psLevel,
+                                                                       i,
+                                                                       psConfig,
+                                                                       aeMMULevel[uiThisLevel],
+                                                                       &psNextLevel->sMemDesc.sDevPAddr,
+#if defined(PDUMP)
+                                                                       IMG_NULL,       /* Only required for data page */
+                                                                       IMG_NULL,       /* Only required for data page */
+                                                                       0,                      /* Only required for data page */
+#endif
+                                                                       0,
+                                                                       uiLog2PageSize);
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       uiAllocState = 2;
+                                       goto e0;
+                               }
+
+                               psLevel->ui32RefCount++;
+                       }
+
+                       /* If we're crossing a Px then the start index changes */
+                       if (bFirst && (i == uiStartIndex))
+                       {
+                               uiNextStartIndex = auiStartArray[uiThisLevel + 1];
+                               bNextFirst = IMG_TRUE;
+                       }
+                       else
+                       {
+                               uiNextStartIndex = 0;
+                               bNextFirst = IMG_FALSE;
+                       }
+
+                       /* If we're crossing a Px then the end index changes */
+                       if (bLast && (i == (uiEndIndex - 1)))
+                       {
+                               uiNextEndIndex = auiEndArray[uiThisLevel + 1];
+                               bNextLast = IMG_TRUE;
+                       }
+                       else
+                       {
+                               uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1];
+                               bNextLast = IMG_FALSE;
+                       }
+
+                       /* Recurse into the next level */
+                       (*pui32CurrentLevel)++;
+                       eError = _MMU_AllocLevel(psMMUContext, psLevel->apsNextLevel[i],
+                                                                               auiStartArray,
+                                                                               auiEndArray,
+                                                                               auiEntriesPerPxArray,
+                                                                               apsConfig,
+                                                                               aeMMULevel,
+                                                                               pui32CurrentLevel,
+                                                                               uiNextStartIndex,
+                                                                               uiNextEndIndex,
+                                                                               bNextFirst,
+                                                                               bNextLast);
+                       (*pui32CurrentLevel)--;
+                       if (eError != PVRSRV_OK)
+                       {
+                               uiAllocState = 2;
+                               goto e0;
+                       }
+               }
+               else
+               {
+                       /* All we need to do for level 1 is bump the refcount */
+                       psLevel->ui32RefCount++;
+               }
+               PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+       }
+       MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_AllocLevel end: level = %d, refcount = %d",
+                               aeMMULevel[uiThisLevel], psLevel->ui32RefCount));
+       return PVRSRV_OK;
+
+e0:
+       /* Sanity check that we've not come down this route unexpectedly */
+       PVR_ASSERT(uiAllocState!=99);
+       PVR_DPF((PVR_DBG_ERROR, "_MMU_AllocLevel: Error %d allocating Px for level %d in stage %d"
+                                                       ,eError, aeMMULevel[uiThisLevel], uiAllocState));
+
+       /* the start value of index variable i is nor initialized on purpose 
+          indeed this for loop deinitialize what has already been initialized 
+          just before failing in reverse order. So the i index has already the
+          right value. */
+       for (/* i already set */ ; i>= uiStartIndex  &&  i< uiEndIndex; i--)
+       {
+               switch(uiAllocState)
+               {
+                       IMG_UINT32 uiNextStartIndex;
+                       IMG_UINT32 uiNextEndIndex;
+                       IMG_BOOL bNextFirst;
+                       IMG_BOOL bNextLast;
+
+                       case 3:
+                                       /* If we're crossing a Px then the start index changes */
+                                       if (bFirst && (i == uiStartIndex))
+                                       {
+                                               uiNextStartIndex = auiStartArray[uiThisLevel + 1];
+                                               bNextFirst = IMG_TRUE;
+                                       }
+                                       else
+                                       {
+                                               uiNextStartIndex = 0;
+                                               bNextFirst = IMG_FALSE;
+                                       }
+
+                                       /* If we're crossing a Px then the end index changes */
+                                       if (bLast && (i == (uiEndIndex - 1)))
+                                       {
+                                               uiNextEndIndex = auiEndArray[uiThisLevel + 1];
+                                               bNextLast = IMG_TRUE;
+                                       }
+                                       else
+                                       {
+                                               uiNextEndIndex = auiEntriesPerPxArray[uiThisLevel + 1];
+                                               bNextLast = IMG_FALSE;
+                                       }
+
+                                       if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
+                                       {
+                                               (*pui32CurrentLevel)++;
+                                               if (_MMU_FreeLevel(psMMUContext, psLevel->apsNextLevel[i],
+                                                                                       auiStartArray, auiEndArray,
+                                                                                       auiEntriesPerPxArray, apsConfig,
+                                                                                       aeMMULevel, pui32CurrentLevel,
+                                                                                       uiNextStartIndex, uiNextEndIndex,
+                                                                                       bNextFirst, bNextLast))
+                                               {
+                                                       psLevel->ui32RefCount--;
+                                                       psLevel->apsNextLevel[i] = IMG_NULL;
+
+                                                       /* Check we haven't wrapped around */
+                                                       PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+                                               }
+                                               (*pui32CurrentLevel)--;
+                                       }
+                                       else
+                                       {
+                                               /* We should never come down this path, but it's here
+                                                  for completeness */
+                                               psLevel->ui32RefCount--;
+
+                                               /* Check we haven't wrapped around */
+                                               PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+                                       }
+                       case 2:
+                                       if (psLevel->apsNextLevel[i] != IMG_NULL  &&
+                                           psLevel->apsNextLevel[i]->ui32RefCount == 0)
+                                       {
+                                               _PxMemFree(psMMUContext, &psLevel->sMemDesc,
+                                                                       aeMMULevel[uiThisLevel]);
+                                       }
+                       case 1:
+                                       if (psLevel->apsNextLevel[i] != IMG_NULL  &&
+                                           psLevel->apsNextLevel[i]->ui32RefCount == 0)
+                                       {
+                                               OSFreeMem(psLevel->apsNextLevel[i]);
+                                               psLevel->apsNextLevel[i] = IMG_NULL;
+                                       }
+                       case 0:
+                                       uiAllocState = 3;
+                                       break;
+               }
+       }
+       return eError;
+}
+
+/*****************************************************************************
+ *                   MMU page table functions                                *
+ *****************************************************************************/
+
+/*************************************************************************/ /*!
+@Function       _MMU_GetLevelData
+
+@Description    Get the all the level data and calculates the indexes for the
+                specified address range
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          sDevVAddrStart          Start device virtual address
+
+@Input          sDevVAddrEnd            End device virtual address
+
+@Input          uiLog2DataPageSize      Log2 of the page size to use
+
+@Input          auiStartArray           Array of start indexes (one for each level)
+
+@Input          auiEndArray             Array of end indexes (one for each level)
+
+@Input          uiEntriesPerPxArray     Array of number of entries for the Px
+                                        (one for each level)
+
+@Input          apsConfig               Array of PxE configs (one for each level)
+
+@Input          aeMMULevel              Array of MMU levels (one for each level)
+@Input          apsConfig               Array of PxE configs (one for each level)
+
+@Input          aeMMULevel              Array of MMU levels (one for each level)
+
+@Input          pui32CurrentLevel       Pointer to a variable which is set to our
+                                        current level 
+
+@Input          uiStartIndex            Start index of the range to free
+
+@Input          uiEndIndex              End index of the range to free
+
+@Return         IMG_TRUE if the last reference to psLevel was dropped
+*/
+/*****************************************************************************/
+static IMG_VOID _MMU_GetLevelData(MMU_CONTEXT *psMMUContext,
+                                                                       IMG_DEV_VIRTADDR sDevVAddrStart,
+                                                                       IMG_DEV_VIRTADDR sDevVAddrEnd,
+                                                                       IMG_UINT32 uiLog2DataPageSize,
+                                                                       IMG_UINT32 auiStartArray[],
+                                                                       IMG_UINT32 auiEndArray[],
+                                                                       IMG_UINT32 auiEntriesPerPx[],
+                                                                       const MMU_PxE_CONFIG *apsConfig[],
+                                                                       MMU_LEVEL aeMMULevel[],
+                                                                       const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
+                                                                       IMG_HANDLE *phPriv)
+{
+       const MMU_PxE_CONFIG *psMMUPDEConfig;
+       const MMU_PxE_CONFIG *psMMUPTEConfig;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs;
+       PVRSRV_ERROR eError;
+       IMG_UINT32 i = 0;
+
+       eError = psDevAttrs->pfnGetPageSizeConfiguration(uiLog2DataPageSize,
+                                                                                                               &psMMUPDEConfig,
+                                                                                                               &psMMUPTEConfig,
+                                                                                                               ppsMMUDevVAddrConfig,
+                                                                                                               phPriv);
+       PVR_ASSERT(eError == PVRSRV_OK);
+       
+       psDevVAddrConfig = *ppsMMUDevVAddrConfig;
+
+       if (psDevVAddrConfig->uiPCIndexMask != 0)
+       {
+               auiStartArray[i] = _CalcPCEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE);
+               auiEndArray[i] = _CalcPCEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE);
+               auiEntriesPerPx[i] = (IMG_UINT32)UNITS_IN_BITFIELD(psDevVAddrConfig->uiPCIndexMask,
+                                                                                                       psDevVAddrConfig->uiPCIndexShift);
+               apsConfig[i] = psDevAttrs->psBaseConfig;
+               aeMMULevel[i] = MMU_LEVEL_3;
+               i++;
+       }
+
+       if (psDevVAddrConfig->uiPDIndexMask != 0)
+       {
+               auiStartArray[i] = _CalcPDEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE);
+               auiEndArray[i] = _CalcPDEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE);
+               auiEntriesPerPx[i] = (IMG_UINT32)UNITS_IN_BITFIELD(psDevVAddrConfig->uiPDIndexMask,
+                                                                                                       psDevVAddrConfig->uiPDIndexShift);
+               if (i == 0)
+               {
+                       apsConfig[i] = psDevAttrs->psBaseConfig;
+               }
+               else
+               {
+                       apsConfig[i] = psMMUPDEConfig;
+               }
+               aeMMULevel[i] = MMU_LEVEL_2;
+               i++;
+       }
+
+       /*
+               There is always a PTE entry so we have a slightly different behaviour than above.
+               E.g. for 2 MB RGX pages the uiPTIndexMask is 0x0000000000 but still there
+               is a PT with one entry.
+
+       */
+       auiStartArray[i] = _CalcPTEIdx(sDevVAddrStart, psDevVAddrConfig, IMG_FALSE);
+       if (psDevVAddrConfig->uiPTIndexMask !=0)
+       {
+               auiEndArray[i] = _CalcPTEIdx(sDevVAddrEnd, psDevVAddrConfig, IMG_TRUE);
+       }
+       else
+       {
+               /*
+                       If the PTE mask is zero it means there is only 1 PTE and thus
+                       the start and end array are one in the same
+               */
+               auiEndArray[i] = auiStartArray[i];
+       }
+       auiEntriesPerPx[i] = (IMG_UINT32)UNITS_IN_BITFIELD(psDevVAddrConfig->uiPTIndexMask,
+                                                                                                       psDevVAddrConfig->uiPTIndexShift);
+       if (i == 0)
+       {
+               apsConfig[i] = psDevAttrs->psBaseConfig;
+       }
+       else
+       {
+               apsConfig[i] = psMMUPTEConfig;
+       }
+       aeMMULevel[i] = MMU_LEVEL_1;
+}
+
+static IMG_VOID _MMU_PutLevelData(MMU_CONTEXT *psMMUContext, IMG_HANDLE hPriv)
+{
+       MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs;
+
+       psDevAttrs->pfnPutPageSizeConfiguration(hPriv);
+}
+
+/*************************************************************************/ /*!
+@Function       _AllocPageTables
+
+@Description    Allocate page tables and any higher level MMU objects required
+                for the specified virtual range
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          sDevVAddrStart          Start device virtual address
+
+@Input          sDevVAddrEnd            End device virtual address
+
+@Input          uiProtFlags             Generic MMU protection flags
+
+@Return         PVRSRV_OK if the allocation was successful
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR
+_AllocPageTables(MMU_CONTEXT *psMMUContext,
+                 IMG_DEV_VIRTADDR sDevVAddrStart,
+                 IMG_DEV_VIRTADDR sDevVAddrEnd,
+                 MMU_FLAGS_T uiProtFlags,
+                 IMG_UINT8 uiLog2PageSize)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 auiStartArray[MMU_MAX_LEVEL];
+       IMG_UINT32 auiEndArray[MMU_MAX_LEVEL];
+       IMG_UINT32 auiEntriesPerPx[MMU_MAX_LEVEL];
+       MMU_LEVEL aeMMULevel[MMU_MAX_LEVEL];
+       const MMU_PxE_CONFIG *apsConfig[MMU_MAX_LEVEL];
+       const MMU_DEVVADDR_CONFIG       *psDevVAddrConfig;
+       IMG_HANDLE hPriv;
+       IMG_UINT32 ui32CurrentLevel = 0;
+
+
+       PVR_DPF((PVR_DBG_ALLOC,
+                        "_AllocPageTables: vaddr range: 0x%010llx:0x%010llx",
+                        sDevVAddrStart.uiAddr,
+                        sDevVAddrEnd.uiAddr
+                        ));
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Allocating page tables for %llu bytes virtual range: 0x%010llX to 0x%010llX",
+                               (IMG_UINT64)sDevVAddrEnd.uiAddr - (IMG_UINT64)sDevVAddrStart.uiAddr,
+                 (IMG_UINT64)sDevVAddrStart.uiAddr,
+                 (IMG_UINT64)sDevVAddrEnd.uiAddr);
+#endif
+
+       _MMU_GetLevelData(psMMUContext, sDevVAddrStart, sDevVAddrEnd,
+                                               (IMG_UINT32) uiLog2PageSize, auiStartArray, auiEndArray,
+                                               auiEntriesPerPx, apsConfig, aeMMULevel,
+                                               &psDevVAddrConfig, &hPriv);
+
+       eError = _MMU_AllocLevel(psMMUContext, &psMMUContext->sBaseLevelInfo,
+                                                               auiStartArray, auiEndArray, auiEntriesPerPx,
+                                                               apsConfig, aeMMULevel, &ui32CurrentLevel,
+                                                               auiStartArray[0], auiEndArray[0],
+                                                               IMG_TRUE, IMG_TRUE);
+
+       _MMU_PutLevelData(psMMUContext, hPriv);
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       _FreePageTables
+
+@Description    Free page tables and any higher level MMU objects at are no
+                longer referenced for the specified virtual range
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          sDevVAddrStart          Start device virtual address
+
+@Input          sDevVAddrEnd            End device virtual address
+
+@Return         None
+*/
+/*****************************************************************************/
+static IMG_VOID _FreePageTables(MMU_CONTEXT *psMMUContext,
+                                   IMG_DEV_VIRTADDR sDevVAddrStart,
+                                   IMG_DEV_VIRTADDR sDevVAddrEnd,
+                                   IMG_UINT8 uiLog2PageSize)
+{
+       IMG_UINT32 auiStartArray[MMU_MAX_LEVEL];
+       IMG_UINT32 auiEndArray[MMU_MAX_LEVEL];
+       IMG_UINT32 auiEntriesPerPx[MMU_MAX_LEVEL];
+       MMU_LEVEL aeMMULevel[MMU_MAX_LEVEL];
+       const MMU_PxE_CONFIG *apsConfig[MMU_MAX_LEVEL];
+       const MMU_DEVVADDR_CONFIG       *psDevVAddrConfig;
+       IMG_UINT32 ui32CurrentLevel = 0;
+       IMG_HANDLE hPriv;
+
+
+       PVR_DPF((PVR_DBG_ALLOC,
+                        "_FreePageTables: vaddr range: 0x%010llx:0x%010llx",
+                        sDevVAddrStart.uiAddr,
+                        sDevVAddrEnd.uiAddr
+                        ));
+
+       _MMU_GetLevelData(psMMUContext, sDevVAddrStart, sDevVAddrEnd,
+                                               uiLog2PageSize, auiStartArray, auiEndArray,
+                                               auiEntriesPerPx, apsConfig, aeMMULevel,
+                                               &psDevVAddrConfig, &hPriv);
+
+       _MMU_FreeLevel(psMMUContext, &psMMUContext->sBaseLevelInfo,
+                                       auiStartArray, auiEndArray, auiEntriesPerPx,
+                                       apsConfig, aeMMULevel, &ui32CurrentLevel,
+                                       auiStartArray[0], auiEndArray[0],
+                                       IMG_TRUE, IMG_TRUE);
+
+       _MMU_PutLevelData(psMMUContext, hPriv);
+}
+
+
+/*************************************************************************/ /*!
+@Function       _MMU_GetPTInfo
+
+@Description    Get the PT level information and PT entry index for the specified
+                virtual address
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          psDevVAddr              Device virtual address to get the PTE info
+                                        from.
+
+@Input          psDevVAddrConfig        The current virtual address config obtained
+                                        by another function call before.
+
+@Output         psLevel                 Level info of the PT
+
+@Output         pui32PTEIndex           Index into the PT the address corresponds to
+
+@Return         None
+*/
+/*****************************************************************************/
+static INLINE IMG_VOID _MMU_GetPTInfo(MMU_CONTEXT                *psMMUContext,
+                                      IMG_DEV_VIRTADDR            sDevVAddr,
+                                      const MMU_DEVVADDR_CONFIG  *psDevVAddrConfig,
+                                      MMU_Levelx_INFO           **psLevel,
+                                      IMG_UINT32                 *pui32PTEIndex)
+{
+       MMU_Levelx_INFO *psLocalLevel = IMG_NULL;
+
+       IMG_UINT32 uiPCEIndex;
+       IMG_UINT32 uiPDEIndex;
+
+       switch(psMMUContext->psDevAttrs->eTopLevel)
+       {
+               case MMU_LEVEL_3:
+                       /* find the page directory containing the PCE */
+                       uiPCEIndex = _CalcPCEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+                       psLocalLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiPCEIndex];
+
+               case MMU_LEVEL_2:
+                       /* find the page table containing the PDE */
+                       uiPDEIndex = _CalcPDEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+                       if (psLocalLevel != IMG_NULL)
+                       {
+                               psLocalLevel = psLocalLevel->apsNextLevel[uiPDEIndex];
+                       }
+                       else
+                       {
+                               psLocalLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiPDEIndex];
+                       }
+
+               case MMU_LEVEL_1:
+                       /* find PTE index into page table */
+                       *pui32PTEIndex = _CalcPTEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+                       if (psLocalLevel == IMG_NULL)
+                       {
+                               psLocalLevel = &psMMUContext->sBaseLevelInfo;
+                       }
+                       break;
+
+               default:
+                       PVR_DPF((PVR_DBG_ERROR, "_MMU_GetPTEInfo: Invalid MMU level"));
+                       return;
+       }
+
+       *psLevel = psLocalLevel;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_GetPTConfig
+
+@Description    Get the level config. Call _MMU_PutPTConfig after use!
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          uiLog2DataPageSize      Log 2 of the page size
+
+@Output         ppsConfig               Config of the PTE
+
+@Output         phPriv                  Private data handle to be passed back
+                                        when the info is put
+
+@Output         ppsDevVAddrConfig       Config of the device virtual addresses
+
+@Return         None
+*/
+/*****************************************************************************/
+static INLINE IMG_VOID _MMU_GetPTConfig(MMU_CONTEXT               *psMMUContext,
+                                       IMG_UINT32                  uiLog2DataPageSize,
+                                       const MMU_PxE_CONFIG      **ppsConfig,
+                                       IMG_HANDLE                 *phPriv,
+                                       const MMU_DEVVADDR_CONFIG **ppsDevVAddrConfig)
+{
+       MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       const MMU_PxE_CONFIG *psPDEConfig;
+       const MMU_PxE_CONFIG *psPTEConfig;
+
+       if (psDevAttrs->pfnGetPageSizeConfiguration(uiLog2DataPageSize,
+                                                   &psPDEConfig,
+                                                   &psPTEConfig,
+                                                   &psDevVAddrConfig,
+                                                   phPriv) != PVRSRV_OK)
+       {
+               /*
+                  There should be no way we got here unless uiLog2DataPageSize
+                  has changed after the MMU_Alloc call (in which case it's a bug in
+                  the MM code)
+               */
+               PVR_DPF((PVR_DBG_ERROR, "_MMU_GetPTConfig: Could not get valid page size config"));
+               PVR_ASSERT(0);
+       }
+
+       *ppsConfig = psPTEConfig;
+       *ppsDevVAddrConfig = psDevVAddrConfig;
+}
+
+/*************************************************************************/ /*!
+@Function       _MMU_PutPTConfig
+
+@Description    Put the level info. Has to be called after _MMU_GetPTConfig to
+                ensure correct refcounting.
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          phPriv                  Private data handle created by
+                                        _MMU_GetPTConfig.
+
+@Return         None
+*/
+/*****************************************************************************/
+static INLINE IMG_VOID _MMU_PutPTConfig(MMU_CONTEXT *psMMUContext,
+                                 IMG_HANDLE hPriv)
+{
+       MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs;
+
+       if( psDevAttrs->pfnPutPageSizeConfiguration(hPriv) != PVRSRV_OK )
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_MMU_GetPTConfig: Could not put page size config"));
+               PVR_ASSERT(0);
+       }
+
+}
+
+/*****************************************************************************
+ *                     Public interface functions                            *
+ *****************************************************************************/
+
+/*
+       MMU_ContextCreate
+*/
+PVRSRV_ERROR
+MMU_ContextCreate(PVRSRV_DEVICE_NODE *psDevNode,
+                   MMU_CONTEXT **ppsMMUContext)
+{
+       MMU_CONTEXT *psMMUContext;
+       MMU_DEVICEATTRIBS *psDevAttrs;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       const MMU_PxE_CONFIG *psConfig;
+       MMU_PHYSMEM_CONTEXT *psCtx;
+       IMG_UINT32 ui32BaseObjects;
+       IMG_UINT32 ui32Size;
+       IMG_CHAR sBuf[40];
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       psDevAttrs = psDevNode->psMMUDevAttrs;
+       psConfig = psDevAttrs->psBaseConfig;
+       psDevVAddrConfig = psDevAttrs->psTopLevelDevVAddrConfig;
+
+       switch(psDevAttrs->eTopLevel)
+       {
+               case MMU_LEVEL_3:       ui32BaseObjects = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(psDevVAddrConfig->uiPCIndexMask,
+                                                                                                       psDevVAddrConfig->uiPCIndexShift));
+                                                               break;
+
+               case MMU_LEVEL_2:       ui32BaseObjects = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(psDevVAddrConfig->uiPDIndexMask,
+                                                                                                       psDevVAddrConfig->uiPDIndexShift));
+                                                               break;
+
+               case MMU_LEVEL_1:       ui32BaseObjects = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(psDevVAddrConfig->uiPTIndexMask,
+                                                                                                       psDevVAddrConfig->uiPTIndexShift));
+                                                               break;
+
+               default:
+                                                               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Invalid MMU config"));
+                                                               eError = PVRSRV_ERROR_INVALID_PARAMS;
+                                                               goto e0;
+       }
+
+       /* Allocate the MMU context with the Level 1 Px info's */
+       ui32Size = sizeof(MMU_CONTEXT) + 
+                                               ((ui32BaseObjects - 1) * sizeof(MMU_Levelx_INFO *));
+
+       psMMUContext = OSAllocMem(ui32Size);
+       if (psMMUContext == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: ERROR call to OSAllocMem failed"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       OSMemSet (psMMUContext, 0, ui32Size);
+
+#if defined(PDUMP)
+       /* Clear the refcount */
+       psMMUContext->ui32PDumpContextIDRefCount = 0;
+#endif
+       /* Record Device specific attributes in the context for subsequent use */
+       psMMUContext->psDevAttrs = psDevAttrs;
+       psMMUContext->psDevNode = psDevNode;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+       IMG_UINT32 ui32OSid, ui32OSidReg;
+       RetrieveOSidsfromPidList(OSGetCurrentProcessID(), &ui32OSid, &ui32OSidReg);
+       MMU_SetOSids(psMMUContext, ui32OSid, ui32OSidReg);
+}
+#endif
+
+       /* 
+         Allocate physmem context and set it up
+        */
+       psCtx = OSAllocMem(sizeof (MMU_PHYSMEM_CONTEXT));
+       if (psCtx == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: ERROR call to OSAllocMem failed"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e1;
+       }
+       psMMUContext->psPhysMemCtx = psCtx;
+
+       OSMemSet (psCtx, 0, sizeof(MMU_PHYSMEM_CONTEXT));
+       psCtx->psDevNode = psDevNode;
+
+       OSSNPrintf(sBuf, sizeof(sBuf)-1, "pgtables %p", psCtx);
+       psCtx->uiPhysMemRANameAllocSize = OSStringLength(sBuf)+1;
+       psCtx->pszPhysMemRAName = OSAllocMem(psCtx->uiPhysMemRANameAllocSize);
+       if (psCtx->pszPhysMemRAName == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Out of memory"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e2;
+       }
+
+       OSStringCopy(psCtx->pszPhysMemRAName, sBuf);
+
+       psCtx->psPhysMemRA = RA_Create(psCtx->pszPhysMemRAName,
+                                                                       /* subsequent import */
+                                                                       psDevNode->uiMMUPxLog2AllocGran,
+                                                                       RA_LOCKCLASS_1,
+                                                                       _MMU_PhysMem_RAImportAlloc,
+                                                                       _MMU_PhysMem_RAImportFree,
+                                                                       psCtx, /* priv */
+                                                                       IMG_FALSE);
+       if (psCtx->psPhysMemRA == IMG_NULL)
+       {
+               OSFreeMem(psCtx->pszPhysMemRAName);
+               psCtx->pszPhysMemRAName = IMG_NULL;
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e3;
+       }
+
+       /* allocate the base level object */
+       /*
+          Note: Although this is not required by the this file until
+                the 1st allocation is made, a device specific callback
+                might request the base object address so we allocate
+                it up front.
+       */
+       if (_PxMemAlloc(psMMUContext,
+                                                       ui32BaseObjects,
+                                                       psConfig,
+                                                       psDevAttrs->eTopLevel,
+                                                       &psMMUContext->sBaseLevelInfo.sMemDesc,
+                                                       psConfig->uiLog2Align))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Failed to alloc level 1 object"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e4;
+       }
+
+       psMMUContext->sBaseLevelInfo.ui32NumOfEntries = ui32BaseObjects;
+       psMMUContext->sBaseLevelInfo.ui32RefCount = 0;
+
+       eError = OSLockCreate(&psMMUContext->hLock, LOCK_TYPE_PASSIVE);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Failed to create lock for MMU_CONTEXT"));
+               goto e5;
+       }
+
+       /* return context */
+       *ppsMMUContext = psMMUContext;
+
+       return PVRSRV_OK;
+
+e5:
+       _PxMemFree(psMMUContext, &psMMUContext->sBaseLevelInfo.sMemDesc, psDevAttrs->eTopLevel);
+e4:
+       RA_Delete(psCtx->psPhysMemRA);
+e3:
+       OSFreeMem(psCtx->pszPhysMemRAName);
+e2:
+       OSFreeMem(psCtx);
+e1:
+       OSFreeMem(psMMUContext);
+e0:
+       return eError;
+}
+
+/*
+       MMU_ContextDestroy
+*/
+IMG_VOID
+MMU_ContextDestroy (MMU_CONTEXT *psMMUContext)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       PVR_DPF ((PVR_DBG_MESSAGE, "MMU_ContextDestroy: Enter"));
+
+       if (psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK)
+       {
+               /* There should be no way to get here with live pages unless
+                  there is a bug in this module or the MM code */
+               PVR_ASSERT(psMMUContext->sBaseLevelInfo.ui32RefCount == 0);
+       }
+
+       /* Free the top level MMU object */
+       _PxMemFree(psMMUContext,
+                               &psMMUContext->sBaseLevelInfo.sMemDesc,
+                               psMMUContext->psDevAttrs->eTopLevel);
+
+       /* Free physmem context */
+       RA_Delete(psMMUContext->psPhysMemCtx->psPhysMemRA);
+       psMMUContext->psPhysMemCtx->psPhysMemRA = IMG_NULL;
+       OSFreeMem(psMMUContext->psPhysMemCtx->pszPhysMemRAName);
+       psMMUContext->psPhysMemCtx->pszPhysMemRAName = IMG_NULL;
+
+       OSFreeMem(psMMUContext->psPhysMemCtx);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+       RemovePidOSidCoupling(OSGetCurrentProcessID());
+#endif
+
+       OSLockDestroy(psMMUContext->hLock);
+
+       /* free the context itself. */
+       OSFreeMem(psMMUContext);
+       /*not nulling pointer, copy on stack*/
+
+       PVR_DPF ((PVR_DBG_MESSAGE, "MMU_ContextDestroy: Exit"));
+}
+
+/*
+       MMU_Alloc
+*/
+PVRSRV_ERROR
+MMU_Alloc (MMU_CONTEXT *psMMUContext,
+                  IMG_DEVMEM_SIZE_T uSize,
+                  IMG_DEVMEM_SIZE_T *puActualSize,
+           IMG_UINT32 uiProtFlags,
+                  IMG_DEVMEM_SIZE_T uDevVAddrAlignment,
+                  IMG_DEV_VIRTADDR *psDevVAddr,
+                  IMG_UINT8 uiLog2PageSize)
+{
+    PVRSRV_ERROR eError;
+    IMG_DEV_VIRTADDR sDevVAddrEnd;
+
+
+       const MMU_PxE_CONFIG *psPDEConfig;
+       const MMU_PxE_CONFIG *psPTEConfig;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+
+       MMU_DEVICEATTRIBS *psDevAttrs;
+       IMG_HANDLE hPriv;
+       
+#if !defined (DEBUG)
+       PVR_UNREFERENCED_PARAMETER(uDevVAddrAlignment);
+#endif
+
+       PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Alloc: uSize=0x%010llx, uiProtFlags=0x%x, align=0x%010llx", uSize, uiProtFlags, uDevVAddrAlignment));
+
+       /* check params */
+       if (!psMMUContext || !psDevVAddr || !puActualSize)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: invalid params"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psDevAttrs = psMMUContext->psDevAttrs;
+
+       eError = psDevAttrs->pfnGetPageSizeConfiguration(uiLog2PageSize,
+                                                                                                       &psPDEConfig,
+                                                                                                       &psPTEConfig,
+                                                                                                       &psDevVAddrConfig,
+                                                                                                       &hPriv);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to get config info (%d)", eError));
+               return eError;
+       }
+
+       /* size and alignment must be datapage granular */
+       if(((psDevVAddr->uiAddr & psDevVAddrConfig->uiPageOffsetMask) != 0)
+       || ((uSize & psDevVAddrConfig->uiPageOffsetMask) != 0))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: invalid address or size granularity"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       sDevVAddrEnd = *psDevVAddr;
+       sDevVAddrEnd.uiAddr += uSize;
+
+       OSLockAcquire(psMMUContext->hLock);
+       eError = _AllocPageTables(psMMUContext, *psDevVAddr, sDevVAddrEnd, uiProtFlags, uiLog2PageSize);
+       OSLockRelease(psMMUContext->hLock);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
+        return PVRSRV_ERROR_MMU_FAILED_TO_ALLOCATE_PAGETABLES;
+       }
+
+       psDevAttrs->pfnPutPageSizeConfiguration(hPriv);
+
+       return PVRSRV_OK;
+}
+
+/*
+       MMU_Free
+*/
+IMG_VOID
+MMU_Free (MMU_CONTEXT *psMMUContext,
+          IMG_DEV_VIRTADDR sDevVAddr,
+          IMG_DEVMEM_SIZE_T uiSize,
+          IMG_UINT8 uiLog2PageSize)
+{
+       IMG_DEV_VIRTADDR sDevVAddrEnd;
+
+       if (psMMUContext == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
+               return;
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE, "MMU_Free: Freeing DevVAddr 0x%010llX",
+                        sDevVAddr.uiAddr));
+
+       /* ensure the address range to free is inside the heap */
+       sDevVAddrEnd = sDevVAddr;
+       sDevVAddrEnd.uiAddr += uiSize;
+
+       OSLockAcquire(psMMUContext->hLock);
+
+       _FreePageTables(psMMUContext, sDevVAddr, sDevVAddrEnd, uiLog2PageSize);
+
+       OSLockRelease(psMMUContext->hLock);
+}
+
+/*
+       MMU_UnmapPages
+*/
+IMG_VOID
+MMU_UnmapPages (MMU_CONTEXT *psMMUContext,
+                IMG_DEV_VIRTADDR sDevVAddr,
+                IMG_UINT32 ui32PageCount,
+                IMG_UINT8 uiLog2PageSize)
+{
+       IMG_UINT32 uiPTEIndex = 0;
+       IMG_UINT32 uiPageSize = 1 << uiLog2PageSize;
+       MMU_Levelx_INFO *psLevel = IMG_NULL;
+       MMU_Levelx_INFO *psPrevLevel = IMG_NULL;
+       IMG_HANDLE hPriv;
+       const MMU_PxE_CONFIG *psConfig;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       IMG_UINT64 uiProtFlags = 0;
+       MMU_PROTFLAGS_T uiMMUProtFlags = 0;
+
+#if defined PDUMP
+       PDUMPCOMMENT("Invalidate %d entries in page tables for virtual range: 0x%010llX to 0x%010llX",
+                    ui32PageCount,
+                    (IMG_UINT64)sDevVAddr.uiAddr,
+                    ((IMG_UINT64)sDevVAddr.uiAddr) + (uiPageSize*ui32PageCount)-1);
+#endif
+
+       /* Get PT and address configs */
+       _MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2PageSize,
+                        &psConfig, &hPriv, &psDevVAddrConfig);
+
+       _MMU_ConvertDevMemFlags(IMG_TRUE,
+                               0,
+                               &uiMMUProtFlags);
+
+       /* Callback to get device specific protection flags */
+       if (psConfig->uiBytesPerEntry == 4)
+       {
+               uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags);
+       }
+       else if (psConfig->uiBytesPerEntry == 8)
+       {
+               uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2PageSize);
+       }
+
+
+       OSLockAcquire(psMMUContext->hLock);
+
+       /* Unmap page by page */
+       while (ui32PageCount != 0)
+       {
+               psPrevLevel = psLevel;
+
+               /* Get index for table and table descriptor */
+               _MMU_GetPTInfo(psMMUContext, sDevVAddr,
+                              psDevVAddrConfig, &psLevel, &uiPTEIndex);
+
+               /* Map table if not done in previous loop*/
+               if ( psLevel != psPrevLevel ) {
+
+                       if ( psPrevLevel != IMG_NULL )
+                       {
+                               if (_MMU_UnmapCPUVAddr( &(psPrevLevel->sMemDesc) ) != PVRSRV_OK )
+                               {
+                                       goto e0;
+                               }
+                       }
+
+                       if ( _MMU_MapCPUVAddr( &(psLevel->sMemDesc) ) != PVRSRV_OK )
+                       {
+                               goto e0;
+                       }
+               }
+
+               /* Set the PT entry to invalid and poison it with a bad address */
+               if (_SetupPTE(psMMUContext,
+                             psLevel,
+                             uiPTEIndex,
+                             psConfig,
+                             &gsBadDevPhyAddr,
+                             IMG_TRUE,
+#if defined(PDUMP)
+                             IMG_NULL, IMG_NULL, 0U,
+#endif
+                             uiProtFlags) != PVRSRV_OK )
+               {
+                       goto e1;
+               }
+
+               /* Check we haven't wrapped around */
+               PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+               ui32PageCount--;
+               sDevVAddr.uiAddr += uiPageSize;
+       }
+
+       /* Unmap the last used table */
+       if (psLevel != IMG_NULL)
+       {
+               if (_MMU_UnmapCPUVAddr( &(psLevel->sMemDesc) ) != PVRSRV_OK )
+               {
+                       goto e0;
+               }
+       }
+
+       OSLockRelease(psMMUContext->hLock);
+
+       _MMU_PutPTConfig(psMMUContext, hPriv);
+
+       /* Flush TLB for PTs*/
+       psMMUContext->psDevNode->pfnMMUCacheInvalidate(psMMUContext->psDevNode,
+                                                      psMMUContext->hDevData,
+                                                      MMU_LEVEL_1,
+                                                      IMG_TRUE);
+
+       return;
+
+e1:
+       _MMU_UnmapCPUVAddr( &(psLevel->sMemDesc) );
+       _MMU_PutPTConfig(psMMUContext, hPriv);
+       PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: _SetupPTE failed"));
+       PVR_ASSERT(0);
+       OSLockRelease(psMMUContext->hLock);
+       return;
+e0:
+       _MMU_PutPTConfig(psMMUContext, hPriv);
+       PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Failed to map/unmap page table"));
+       PVR_ASSERT(0);
+       OSLockRelease(psMMUContext->hLock);
+       return;
+}
+
+/*
+       MMU_MapPMR
+
+       N.B.  The caller _must_ have already called
+       "PMRLockSysPhysAddr()" on this PMR _before_ calling MMU_MapPMR.
+       Why?  (i) Because we really want this module to concentrate on
+       page table management, and interacts the absolute minimum with
+       the PMR; and (ii) because in the future we may map PMRs in
+       partially (e.g. demand-paging scenario) and it would not be
+       right to call locksysphysaddr on each individual mapping; and
+       (iii) we've already got "unmap pages" where we don't have the
+       PMR handle (we could change the API, but I can't justify this
+       just for this).  However, it may be worth re-thinking this,
+       because we'll eventually want to support mixed page sizes
+       within one allocation (rather than it being a heap attribute)
+       so we may have to move more logic into the mmu code.
+*/
+PVRSRV_ERROR
+MMU_MapPMR (MMU_CONTEXT *psMMUContext,
+            IMG_DEV_VIRTADDR sDevVAddr,
+            const PMR *psPMR,
+            IMG_DEVMEM_SIZE_T uiSizeBytes,
+            PVRSRV_MEMALLOCFLAGS_T uiMappingFlags,
+            IMG_UINT8 uiLog2PageSize)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       IMG_UINT32 uiCount, i;
+       IMG_UINT32 ui32MappedCount = 0;
+       IMG_UINT32 uiPageSize = 1 << uiLog2PageSize;
+       IMG_UINT32 uiPTEIndex = 0;
+       IMG_UINT64 uiProtFlags;
+       MMU_PROTFLAGS_T uiMMUProtFlags = 0;
+       MMU_Levelx_INFO *psLevel = IMG_NULL;
+       MMU_Levelx_INFO *psPrevLevel = IMG_NULL;
+       IMG_HANDLE hPriv;
+       const MMU_PxE_CONFIG *psConfig;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+       IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
+       IMG_DEV_PHYADDR *psDevPAddr;
+       IMG_BOOL *pbValid;
+
+#if defined(PDUMP)
+       IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
+       IMG_CHAR aszSymbolicAddress[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+       IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset;
+
+       PDUMPCOMMENT("Wire up Page Table entries to point to the Data Pages (%lld bytes)", uiSizeBytes);
+#endif /*PDUMP*/
+
+       /* We should verify the size and contiguity when supporting variable page size */
+
+       PVR_ASSERT (psMMUContext != IMG_NULL);
+       PVR_ASSERT (psPMR != IMG_NULL);
+
+       /* Get general PT and address configs */
+       _MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2PageSize,
+                        &psConfig, &hPriv, &psDevVAddrConfig);
+
+       _MMU_ConvertDevMemFlags(IMG_FALSE,
+                               uiMappingFlags,
+                               &uiMMUProtFlags);
+
+       /* Callback to get device specific protection flags */
+
+       if (psConfig->uiBytesPerEntry == 8)
+       {
+               uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt8(uiMMUProtFlags , uiLog2PageSize);
+       }
+       else if (psConfig->uiBytesPerEntry == 4)
+       {
+               uiProtFlags = psMMUContext->psDevAttrs->pfnDerivePTEProt4(uiMMUProtFlags);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR,"MMU_MapPMR: The page table entry byte length is not supported"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       /* Allocate memory for page-frame-numbers and validity states,
+          N.B. assert could be triggered by an illegal uiSizeBytes */
+       uiCount = uiSizeBytes >> uiLog2PageSize;
+       PVR_ASSERT((IMG_DEVMEM_OFFSET_T)uiCount << uiLog2PageSize == uiSizeBytes);
+    if (uiCount > PMR_MAX_TRANSLATION_STACK_ALLOC)
+    {
+               psDevPAddr = OSAllocMem(uiCount * sizeof(IMG_DEV_PHYADDR));
+               if (psDevPAddr == IMG_NULL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR device PFN list"));
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto e0;
+               }
+
+               pbValid = OSAllocMem(uiCount * sizeof(IMG_BOOL));
+               if (pbValid == IMG_NULL)
+               {
+                       /* Should allocation fail, clean-up here before exit */
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR device PFN state"));
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;                    
+                       OSFreeMem(psDevPAddr);                  
+                       goto e0;
+               }
+    }
+       else
+       {
+               psDevPAddr = asDevPAddr;
+               pbValid = abValid;
+       }
+
+       /* "uiSize" is the amount of contiguity in the underlying
+          page.  Normally this would be constant for the system, but,
+          that constant needs to be communicated, in case it's ever
+          different; caller guarantees that PMRLockSysPhysAddr() has
+          already been called */
+       eError = PMR_DevPhysAddr(psPMR,
+                                                        uiLog2PageSize,
+                                                        uiCount,
+                                                        0,
+                                                        psDevPAddr,
+                                                        pbValid);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       OSLockAcquire(psMMUContext->hLock);
+
+       /* Map in all pages of that PMR page by page*/
+       for (i=0, uiCount=0; uiCount < uiSizeBytes; i++, uiCount += uiPageSize)
+       {
+#if defined(PDUMP)
+               IMG_DEVMEM_OFFSET_T uiNextSymName;
+#endif /*PDUMP*/
+
+               /*
+                       The default value of the entry is invalid so we don't need to mark
+                       it as such if the page wasn't valid, we just advance pass that address
+               */
+               if (pbValid[i])
+               {
+                       /* check the physical alignment of the memory to map */
+                       PVR_ASSERT((psDevPAddr[i].uiAddr & (uiPageSize-1)) == 0);
+
+#if defined(DEBUG)
+{
+                       IMG_UINT32 ui32BitLength = FloorLog2(psDevPAddr[i].uiAddr);
+                       if (ui32BitLength > RGX_FEATURE_PHYS_BUS_WIDTH )
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"_MMU_MapPage Failed. The physical address bitlength (%d) "
+                                        "is greater than what the chip can handle (%d).",
+                                        ui32BitLength, RGX_FEATURE_PHYS_BUS_WIDTH));
+
+                               PVR_ASSERT(ui32BitLength <= RGX_FEATURE_PHYS_BUS_WIDTH );
+                               eError = PVRSRV_ERROR_INVALID_PARAMS;
+                               OSLockRelease(psMMUContext->hLock);
+                               goto e1;
+                       }
+}
+#endif /*DEBUG*/
+
+#if defined(PDUMP)
+                       eError = PMR_PDumpSymbolicAddr(psPMR, uiCount,
+                                                      sizeof(aszMemspaceName), &aszMemspaceName[0],
+                                                      sizeof(aszSymbolicAddress), &aszSymbolicAddress[0],
+                                                      &uiSymbolicAddrOffset,
+                                                      &uiNextSymName);
+                       PVR_ASSERT(eError == PVRSRV_OK);
+#endif /*PDUMP*/
+
+                       psPrevLevel = psLevel;
+
+                       /* Calculate PT index and get table descriptor */
+                       _MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig,
+                                       &psLevel, &uiPTEIndex);
+
+                       /* Map table if not done in previous loop*/
+                       if ( psLevel != psPrevLevel ) {
+
+                               eError = _MMU_MapCPUVAddr( &(psLevel->sMemDesc) );
+                               PVR_ASSERT(eError == PVRSRV_OK);
+
+                               if ( psPrevLevel != IMG_NULL )
+                               {
+                                       eError = _MMU_UnmapCPUVAddr( &(psPrevLevel->sMemDesc) );
+                                       PVR_ASSERT(eError == PVRSRV_OK);
+                               }
+                       }
+
+                       /* Set the PT entry with the specified address and protection flags */
+                       eError = _SetupPTE(psMMUContext, psLevel, uiPTEIndex,
+                                          psConfig, &psDevPAddr[i], IMG_FALSE,
+#if defined(PDUMP)
+                                          aszMemspaceName,
+                                          aszSymbolicAddress,
+                                          uiSymbolicAddrOffset,
+#endif /*PDUMP*/
+                                          uiProtFlags);
+
+       
+                       if(eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "MMU_MapPMR: Mapping failed"));
+                               OSLockRelease(psMMUContext->hLock);
+                               goto e1;
+                       }
+
+                       PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
+                       PVR_DPF ((PVR_DBG_MESSAGE,
+                                 "MMU_MapPMR: devVAddr=%10llX, size=0x%x/0x%010llx",
+                                 sDevVAddr.uiAddr,
+                                 uiCount,
+                                 uiSizeBytes));
+
+                       ui32MappedCount++;
+               }
+
+               sDevVAddr.uiAddr += uiPageSize;
+       }
+
+       OSLockRelease(psMMUContext->hLock);
+
+       if (psLevel != IMG_NULL)
+       {
+               eError = _MMU_UnmapCPUVAddr( &(psLevel->sMemDesc) );
+               PVR_ASSERT(eError == PVRSRV_OK);
+       }
+
+       _MMU_PutPTConfig(psMMUContext, hPriv);
+
+       /* Flush TLB for PTs*/
+       psMMUContext->psDevNode->pfnMMUCacheInvalidate(psMMUContext->psDevNode,
+                                                      psMMUContext->hDevData,
+                                                      MMU_LEVEL_1,
+                                                      IMG_FALSE);
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Wired up %d Page Table entries (out of %d)", ui32MappedCount, i);
+#endif /*PDUMP*/
+
+e1:
+       if (psDevPAddr != asDevPAddr)
+       {
+               /* uiCount modified, check against stack address */
+               OSFreeMem(pbValid);
+               OSFreeMem(psDevPAddr);
+       }
+e0:
+       PVR_ASSERT(eError == PVRSRV_OK);
+    return eError;
+}
+
+/*
+       MMU_AcquireBaseAddr
+*/
+PVRSRV_ERROR
+MMU_AcquireBaseAddr(MMU_CONTEXT *psMMUContext, IMG_DEV_PHYADDR *psPhysAddr)
+{
+       if (!psMMUContext)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       *psPhysAddr = psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr;
+       return PVRSRV_OK;
+}
+
+/*
+       MMU_ReleaseBaseAddr
+*/
+IMG_VOID
+MMU_ReleaseBaseAddr(MMU_CONTEXT *psMMUContext)
+{
+       PVR_UNREFERENCED_PARAMETER(psMMUContext);
+}
+
+/*
+       MMU_SetDeviceData
+*/
+IMG_VOID MMU_SetDeviceData(MMU_CONTEXT *psMMUContext, IMG_HANDLE hDevData)
+{
+       psMMUContext->hDevData = hDevData;
+}
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+/*
+    MMU_SetOSid, MMU_GetOSid
+*/
+
+IMG_VOID MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg)
+{
+       psMMUContext->ui32OSid = ui32OSid;
+       psMMUContext->ui32OSidReg = ui32OSidReg;
+
+    return ;
+}
+
+IMG_VOID MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 *pui32OSid, IMG_UINT32 *pui32OSidReg)
+{
+       *pui32OSid = psMMUContext->ui32OSid;
+       *pui32OSidReg = psMMUContext->ui32OSidReg;
+
+       return ;
+}
+
+#endif
+
+/*
+       MMU_CheckFaultAddress
+*/
+IMG_VOID MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, IMG_DEV_VIRTADDR *psDevVAddr)
+{
+       MMU_DEVICEATTRIBS *psDevAttrs = psMMUContext->psDevAttrs;
+       const MMU_PxE_CONFIG *psConfig;
+       const MMU_PxE_CONFIG *psMMUPDEConfig;
+       const MMU_PxE_CONFIG *psMMUPTEConfig;
+       const MMU_DEVVADDR_CONFIG *psMMUDevVAddrConfig;
+       IMG_HANDLE hPriv;
+       MMU_Levelx_INFO *psLevel;
+       PVRSRV_ERROR eError;
+       IMG_UINT64 uiIndex;
+       IMG_UINT32 ui32PCIndex;
+       IMG_UINT32 ui32PDIndex;
+       IMG_UINT32 ui32PTIndex;
+       IMG_UINT32 ui32Log2PageSize;
+
+       OSLockAcquire(psMMUContext->hLock);
+
+       /*
+               At this point we don't know the page size so assume it's 4K.
+               When we get the the PD level (MMU_LEVEL_2) we can check to see
+               if this assumption is correct.
+       */
+       eError = psDevAttrs->pfnGetPageSizeConfiguration(12,
+                                                                                                        &psMMUPDEConfig,
+                                                                                                        &psMMUPTEConfig,
+                                                                                                        &psMMUDevVAddrConfig,
+                                                                                                        &hPriv);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("Failed to get the page size info for log2 page sizeof 12"));
+       }
+
+       psLevel = &psMMUContext->sBaseLevelInfo;
+       psConfig = psDevAttrs->psBaseConfig;
+
+       switch(psMMUContext->psDevAttrs->eTopLevel)
+       {
+               case MMU_LEVEL_3:
+                       /* Determine the PC index */
+                       uiIndex = psDevVAddr->uiAddr & psDevAttrs->psTopLevelDevVAddrConfig->uiPCIndexMask;
+                       uiIndex = uiIndex >> psDevAttrs->psTopLevelDevVAddrConfig->uiPCIndexShift;
+                       ui32PCIndex = (IMG_UINT32) uiIndex;
+                       PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PCIndex));
+                       
+                       if (ui32PCIndex >= psLevel->ui32NumOfEntries)
+                       {
+                               PVR_LOG(("PC index (%d) out of bounds (%d)", ui32PCIndex, psLevel->ui32NumOfEntries));
+                               break;
+                       }
+
+                       if (_MMU_MapCPUVAddr(&psLevel->sMemDesc) != PVRSRV_OK)
+                       {
+                               PVR_LOG(("Failed to map MMU MemDesc"));
+                       }
+
+                       if (psConfig->uiBytesPerEntry == 4)
+                       {
+                               IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PCE for index %d = 0x%08x and %s be valid",
+                                                ui32PCIndex,
+                                                pui32Ptr[ui32PCIndex],
+                                                psLevel->apsNextLevel[ui32PCIndex]?"should":"should not"));
+                       }
+                       else
+                       {
+                               IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PCE for index %d = 0x%016llx and %s be valid",
+                                                ui32PCIndex,
+                                                pui64Ptr[ui32PCIndex],
+                                                psLevel->apsNextLevel[ui32PCIndex]?"should":"should not"));
+                       }
+
+                       _MMU_UnmapCPUVAddr(&psLevel->sMemDesc);
+                       _MMU_LogPxEDump(psLevel, ui32PCIndex);
+
+                       psLevel = psLevel->apsNextLevel[ui32PCIndex];
+                       if (!psLevel)
+                       {
+                               break;
+                       }
+                       psConfig = psMMUPDEConfig;
+                       /* Fall through */
+
+               case MMU_LEVEL_2:
+                       /* Determine the PD index */
+                       uiIndex = psDevVAddr->uiAddr & psDevAttrs->psTopLevelDevVAddrConfig->uiPDIndexMask;
+                       uiIndex = uiIndex >> psDevAttrs->psTopLevelDevVAddrConfig->uiPDIndexShift;
+                       ui32PDIndex = (IMG_UINT32) uiIndex;
+                       PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PDIndex));
+
+                       if (ui32PDIndex >= psLevel->ui32NumOfEntries)
+                       {
+                               PVR_LOG(("PD index (%d) out of bounds (%d)", ui32PDIndex, psLevel->ui32NumOfEntries));
+                               break;
+                       }
+
+                       if (_MMU_MapCPUVAddr(&psLevel->sMemDesc) != PVRSRV_OK)
+                       {
+                               PVR_LOG(("Failed to map MMU MemDesc"));
+                       }
+
+                       if (psConfig->uiBytesPerEntry == 4)
+                       {
+                               IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PDE for index %d = 0x%08x and %s be valid",
+                                                ui32PDIndex,
+                                                pui32Ptr[ui32PDIndex],
+                                                psLevel->apsNextLevel[ui32PDIndex]?"should":"should not"));
+
+                               if (psDevAttrs->pfnGetPageSizeFromPDE4(pui32Ptr[ui32PDIndex], &ui32Log2PageSize) != PVRSRV_OK)
+                               {
+                                       PVR_LOG(("Failed to get the page size from the PDE"));
+                               }
+                       }
+                       else
+                       {
+                               IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PDE for index %d = 0x%016llx and %s be valid",
+                                                ui32PDIndex,
+                                                pui64Ptr[ui32PDIndex],
+                                                psLevel->apsNextLevel[ui32PDIndex]?"should":"should not"));
+
+                               if (psDevAttrs->pfnGetPageSizeFromPDE8(pui64Ptr[ui32PDIndex], &ui32Log2PageSize) != PVRSRV_OK)
+                               {
+                                       PVR_LOG(("Failed to get the page size from the PDE"));
+                               }
+                       }
+
+                       _MMU_UnmapCPUVAddr(&psLevel->sMemDesc);
+                       _MMU_LogPxEDump(psLevel, ui32PDIndex);
+
+                       /*
+                               We assumed the page size was 4K, now we have the actual size
+                               from the PDE we can confirm if our assumption was correct.
+                               Until now it hasn't mattered as the PC and PD are the same
+                               regardless of the page size
+                       */
+                       if (ui32Log2PageSize != 12)
+                       {
+                               /* Put the 4K page size data */
+                               psDevAttrs->pfnPutPageSizeConfiguration(hPriv);
+
+                               /* Get the correct size data */
+                               eError = psDevAttrs->pfnGetPageSizeConfiguration(ui32Log2PageSize,
+                                                                                                                                &psMMUPDEConfig,
+                                                                                                                                &psMMUPTEConfig,
+                                                                                                                                &psMMUDevVAddrConfig,
+                                                                                                                                &hPriv);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_LOG(("Failed to get the page size info for log2 page sizeof %d", ui32Log2PageSize));
+                                       break;
+                               }
+                       }
+                       psLevel = psLevel->apsNextLevel[ui32PDIndex];
+                       if (!psLevel)
+                       {
+                               break;
+                       }
+                       psConfig = psMMUPTEConfig;
+                       /* Fall through */
+
+               case MMU_LEVEL_1:
+                       /* Determine the PT index */
+                       uiIndex = psDevVAddr->uiAddr & psMMUDevVAddrConfig->uiPTIndexMask;
+                       uiIndex = uiIndex >> psMMUDevVAddrConfig->uiPTIndexShift;
+                       ui32PTIndex = (IMG_UINT32) uiIndex;
+                       PVR_ASSERT(uiIndex == ((IMG_UINT64) ui32PTIndex));
+
+                       if (ui32PTIndex >= psLevel->ui32NumOfEntries)
+                       {
+                               PVR_LOG(("PT index (%d) out of bounds (%d)", ui32PTIndex, psLevel->ui32NumOfEntries));
+                               break;
+                       }
+
+                       if (_MMU_MapCPUVAddr(&psLevel->sMemDesc) != PVRSRV_OK)
+                       {
+                               PVR_LOG(("Failed to map MMU MemDesc"));
+                       }
+
+                       if (psConfig->uiBytesPerEntry == 4)
+                       {
+                               IMG_UINT32 *pui32Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PTE for index %d = 0x%08x",
+                                                ui32PTIndex,
+                                                pui32Ptr[ui32PTIndex]));
+                       }
+                       else
+                       {
+                               IMG_UINT64 *pui64Ptr = psLevel->sMemDesc.pvCpuVAddr;
+
+                               PVR_LOG(("PTE for index %d = 0x%016llx",
+                                                ui32PTIndex,
+                                                pui64Ptr[ui32PTIndex]));
+                       }
+
+                       _MMU_UnmapCPUVAddr(&psLevel->sMemDesc);
+                       _MMU_LogPxEDump(psLevel, ui32PTIndex);
+                       
+                       break;
+                       default:
+                               PVR_LOG(("Unsupported MMU setup"));
+                               break;
+       }
+
+       OSLockRelease(psMMUContext->hLock);
+}
+
+IMG_BOOL MMU_IsVDevAddrValid(MMU_CONTEXT *psMMUContext,
+                             IMG_UINT32 uiLog2PageSize,
+                             IMG_DEV_VIRTADDR sDevVAddr)
+{
+    MMU_Levelx_INFO *psLevel = IMG_NULL;
+    const MMU_PxE_CONFIG *psConfig;
+    const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+    IMG_HANDLE hPriv;
+    IMG_UINT32 uiIndex = 0;
+    IMG_BOOL bStatus = IMG_FALSE;
+
+    _MMU_GetPTConfig(psMMUContext, uiLog2PageSize, &psConfig, &hPriv, &psDevVAddrConfig);
+
+    OSLockAcquire(psMMUContext->hLock);
+
+    switch(psMMUContext->psDevAttrs->eTopLevel)
+    {
+        case MMU_LEVEL_3:
+            uiIndex = _CalcPCEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+            psLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiIndex];
+            if (psLevel == IMG_NULL)
+                break;
+            /* fall through */
+        case MMU_LEVEL_2:
+            uiIndex = _CalcPDEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+
+            if (psLevel != IMG_NULL)
+                psLevel = psLevel->apsNextLevel[uiIndex];
+            else
+                psLevel = psMMUContext->sBaseLevelInfo.apsNextLevel[uiIndex];
+
+            if (psLevel == IMG_NULL)
+                break;
+            /* fall through */
+        case MMU_LEVEL_1:
+            uiIndex = _CalcPTEIdx(sDevVAddr, psDevVAddrConfig, IMG_FALSE);
+
+            if (psLevel == IMG_NULL)
+                psLevel = &psMMUContext->sBaseLevelInfo;
+
+            if (_MMU_MapCPUVAddr(&psLevel->sMemDesc) != PVRSRV_OK)
+            {
+                PVR_LOG(("MMU_IsVDevAddrValid: _MMU_MapCPUVAddr failed"));
+                break;
+            }
+
+            bStatus = ((IMG_UINT64 *) psLevel->sMemDesc.pvCpuVAddr)[uiIndex]
+                      & psConfig->uiValidEnMask;
+            _MMU_UnmapCPUVAddr(&psLevel->sMemDesc); /* ignore return status */
+            break;
+        default:
+            PVR_LOG(("MMU_IsVDevAddrValid: Unsupported MMU setup"));
+            break;
+    }
+
+    OSLockRelease(psMMUContext->hLock);
+
+    _MMU_PutPTConfig(psMMUContext, hPriv);
+
+    return bStatus;
+}
+
+#if defined(PDUMP)
+/*
+       MMU_ContextDerivePCPDumpSymAddr
+*/
+PVRSRV_ERROR MMU_ContextDerivePCPDumpSymAddr(MMU_CONTEXT *psMMUContext,
+                                             IMG_CHAR *pszPDumpSymbolicNameBuffer,
+                                             IMG_SIZE_T uiPDumpSymbolicNameBufferSize)
+{
+    IMG_SIZE_T uiCount;
+    IMG_UINT64 ui64PhysAddr;
+       PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psDevNode->sDevId;
+
+    if (!psMMUContext->sBaseLevelInfo.sMemDesc.bValid)
+    {
+        /* We don't have any allocations.  You're not allowed to ask
+           for the page catalogue base address until you've made at
+           least one allocation */
+        return PVRSRV_ERROR_MMU_API_PROTOCOL_ERROR;
+    }
+
+    ui64PhysAddr = (IMG_UINT64)psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr.uiAddr;
+
+    PVR_ASSERT(uiPDumpSymbolicNameBufferSize >= (IMG_UINT32)(21 + OSStringLength(psDevId->pszPDumpDevName)));
+
+    /* Page table Symbolic Name is formed from page table phys addr
+       prefixed with MMUPT_. */
+
+    uiCount = OSSNPrintf(pszPDumpSymbolicNameBuffer,
+                         uiPDumpSymbolicNameBufferSize,
+                         ":%s:%s%016llX",
+                         psDevId->pszPDumpDevName,
+                         psMMUContext->sBaseLevelInfo.sMemDesc.bValid?"MMUPC_":"XXX",
+                         ui64PhysAddr);
+    
+    if (uiCount + 1 > uiPDumpSymbolicNameBufferSize)
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    return PVRSRV_OK;
+}
+
+/*
+       MMU_PDumpWritePageCatBase
+*/
+PVRSRV_ERROR
+MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext,
+                          const IMG_CHAR *pszSpaceName,
+                          IMG_DEVMEM_OFFSET_T uiOffset,
+                          IMG_UINT32 ui32WordSize,
+                          IMG_UINT32 ui32AlignShift,
+                          IMG_UINT32 ui32Shift,
+                                                 PDUMP_FLAGS_T uiPdumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszPageCatBaseSymbolicAddr[100];
+       const IMG_CHAR *pszPDumpDevName = psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName;
+
+
+       eError = MMU_ContextDerivePCPDumpSymAddr(psMMUContext,
+                                             &aszPageCatBaseSymbolicAddr[0],
+                                             sizeof(aszPageCatBaseSymbolicAddr));
+    if (eError ==  PVRSRV_OK)
+    {
+               eError = PDumpWriteSymbAddress(pszSpaceName,
+                                                                                  uiOffset,
+                                                                                  aszPageCatBaseSymbolicAddr,
+                                                                                  0, /* offset -- Could be non-zero for var. pgsz */
+                                                                                  pszPDumpDevName,
+                                                                                  ui32WordSize,
+                                                                                  ui32AlignShift,
+                                                                                  ui32Shift,
+                                                                                  uiPdumpFlags | PDUMP_FLAGS_CONTINUOUS);
+    }
+
+    return eError;
+}
+
+/*
+       MMU_AcquirePDumpMMUContext
+*/
+PVRSRV_ERROR MMU_AcquirePDumpMMUContext(MMU_CONTEXT *psMMUContext,
+                                        IMG_UINT32 *pui32PDumpMMUContextID)
+{
+       PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psDevNode->sDevId;
+
+       if (!psMMUContext->ui32PDumpContextIDRefCount)
+       {
+               PDUMP_MMU_ALLOC_MMUCONTEXT(psDevId->pszPDumpDevName,
+                                                                       psMMUContext->sBaseLevelInfo.sMemDesc.sDevPAddr,
+                                                                       psMMUContext->psDevAttrs->eMMUType,
+                                                                       &psMMUContext->uiPDumpContextID);
+       }
+
+       psMMUContext->ui32PDumpContextIDRefCount++;
+       *pui32PDumpMMUContextID = psMMUContext->uiPDumpContextID;
+
+       return PVRSRV_OK;
+}
+
+/*
+       MMU_ReleasePDumpMMUContext
+*/ 
+PVRSRV_ERROR MMU_ReleasePDumpMMUContext(MMU_CONTEXT *psMMUContext)
+{
+       PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psDevNode->sDevId;
+
+       PVR_ASSERT(psMMUContext->ui32PDumpContextIDRefCount != 0);
+       psMMUContext->ui32PDumpContextIDRefCount--;
+
+       if (psMMUContext->ui32PDumpContextIDRefCount == 0)
+       {
+               PDUMP_MMU_FREE_MMUCONTEXT(psDevId->pszPDumpDevName,
+                                                                       psMMUContext->uiPDumpContextID);
+       }
+
+       return PVRSRV_OK;
+}
+#endif
+
+/******************************************************************************
+ End of file (mmu_common.c)
+******************************************************************************/
+
+
diff --git a/drivers/gpu/rogue_m/services/server/common/pdump_common.c b/drivers/gpu/rogue_m/services/server/common/pdump_common.c
new file mode 100644 (file)
index 0000000..42e1c87
--- /dev/null
@@ -0,0 +1,2933 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common Server PDump functions layer
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+   
+#if defined(PDUMP)
+#include <stdarg.h>
+
+#include "pvrversion.h"
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pvrsrv.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "pdump_physmem.h"
+#include "hash.h"
+#include "connection_server.h"
+#include "sync_server.h"
+
+/* pdump headers */
+#include "dbgdrvif_srv5.h"
+#include "pdump_osfunc.h"
+#include "pdump_km.h"
+
+/* Allow temporary buffer size override */
+#if !defined(PDUMP_TEMP_BUFFER_SIZE)
+#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
+#endif
+
+/* DEBUG */
+#if 0
+#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;
+
+#define PERSISTANT_MAGIC           ((IMG_UINTPTR_T) 0xe33ee33e)
+#define PDUMP_PERSISTENT_HASH_SIZE 10
+
+#define PDUMP_PRM_FILE_NAME_MAX        32         /*|< Size of parameter name used*/
+#define PRM_FILE_SIZE_MAX      0x7FDFFFFFU /*!< Default maximum file size to split output files, 2GB-2MB as fwrite limits it to 2GB-1 on 32bit systems */
+#define FRAME_UNSET                    0xFFFFFFFFU /*|< Used to signify no or invalid frame number */
+
+
+static HASH_TABLE *g_psPersistentHash = IMG_NULL;
+
+static IMG_BOOL                g_PDumpInitialised = IMG_FALSE;
+static IMG_UINT32      g_ConnectionCount = 0;
+
+
+typedef struct
+{
+       PDUMP_CHANNEL sCh;         /*!< Channel handles */
+} PDUMP_SCRIPT;
+
+typedef struct
+{
+       IMG_UINT32    ui32Init;    /*|< Count of bytes written to the init phase stream */
+       IMG_UINT32    ui32Main;    /*!< Count of bytes written to the main stream */
+       IMG_UINT32    ui32Deinit;  /*!< Count of bytes written to the deinit stream */
+} PDUMP_CHANNEL_WOFFSETS;
+
+typedef struct
+{
+       PDUMP_CHANNEL          sCh;             /*!< Channel handles */
+       PDUMP_CHANNEL_WOFFSETS sWOff;           /*!< Channel file write offsets */
+       IMG_UINT32             ui32FileIdx;     /*!< File index used when file size limit reached and a new file is started, parameter channel only */
+       IMG_UINT32             ui32MaxFileSize; /*!< Maximum file size for parameter files */
+
+       PDUMP_FILEOFFSET_T     uiZeroPageOffset; /*!< Offset of the zero page in the parameter file */
+       IMG_SIZE_T             uiZeroPageSize; /*!< Size of the zero page in the parameter file */
+       IMG_CHAR               szZeroPageFilename[PDUMP_PRM_FILE_NAME_MAX]; /*< PRM file name where the zero page was pdumped */
+} PDUMP_PARAMETERS;
+
+static PDUMP_SCRIPT     g_PDumpScript    = { { 0, 0, 0} };
+static PDUMP_PARAMETERS g_PDumpParameters = { { 0, 0, 0}, {0, 0, 0}, 0, PRM_FILE_SIZE_MAX};
+
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+/* counter increments each time debug write is called */
+IMG_UINT32 g_ui32EveryLineCounter = 1U;
+#endif
+
+#if defined(PDUMP_DEBUG) || defined(REFCOUNT_DEBUG)
+#define PDUMP_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__)
+#else
+#define PDUMP_REFCOUNT_PRINT(fmt, ...)
+#endif
+
+/* Prototype for the test/debug state dump rotuine used in debugging */
+IMG_VOID PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState);
+#undef PDUMP_TRACE_STATE
+
+
+/*****************************************************************************/
+/*     PDump Control Module Definitions                                         */
+/*****************************************************************************/
+
+typedef struct _PDUMP_CAPTURE_RANGE_
+{
+       IMG_UINT32 ui32Start;       /*!< Start frame number of range */
+       IMG_UINT32 ui32End;         /*!< Send frame number of range */
+       IMG_UINT32 ui32Interval;    /*!< Frame sample rate interval */
+} PDUMP_CAPTURE_RANGE;
+
+/* No direct access to members from outside the control module - please */
+typedef struct _PDUMP_CTRL_STATE_
+{
+       IMG_BOOL            bInitPhaseActive;   /*!< State of driver initialisation phase */
+       IMG_UINT32          ui32Flags;          /*!< Unused */
+
+       IMG_UINT32          ui32DefaultCapMode; /*!< Capture mode of the dump */
+       PDUMP_CAPTURE_RANGE sCaptureRange;      /*|< The capture range for capture mode 'framed' */
+       IMG_UINT32          ui32CurrentFrame;   /*!< Current frame number */
+
+       IMG_BOOL            bCaptureOn;         /*!< Current capture status, is current frame in range */
+       IMG_BOOL            bSuspended;         /*!< Suspend flag set on unrecoverable error */
+       IMG_BOOL            bInPowerTransition; /*!< Device power transition state */
+       POS_LOCK            hLock;              /*!< Exclusive lock to this structure */
+} PDUMP_CTRL_STATE;
+
+static PDUMP_CTRL_STATE g_PDumpCtrl =
+{
+       IMG_TRUE,
+       0,
+
+       0,              /*!< Value obtained from OS PDump layer during initialisation */
+       {
+               FRAME_UNSET,
+               FRAME_UNSET,
+               1
+       },
+       0,
+
+       IMG_FALSE,
+       IMG_FALSE,
+       IMG_FALSE,
+       IMG_NULL
+};
+
+static PVRSRV_ERROR PDumpCtrlInit(IMG_UINT32 ui32InitCapMode)
+{
+       g_PDumpCtrl.ui32DefaultCapMode = ui32InitCapMode;
+       PVR_ASSERT(g_PDumpCtrl.ui32DefaultCapMode != 0);
+
+       /* Create lock for PDUMP_CTRL_STATE struct, which is shared between pdump client
+          and PDumping app. This lock will help us serialize calls from pdump client
+          and PDumping app */
+       PVR_LOGR_IF_ERROR(OSLockCreate(&g_PDumpCtrl.hLock, LOCK_TYPE_PASSIVE), "OSLockCreate");
+       
+       return PVRSRV_OK;
+}
+
+static IMG_VOID PDumpCtrlDeInit(IMG_VOID)
+{
+       if (g_PDumpCtrl.hLock)
+       {
+               OSLockDestroy(g_PDumpCtrl.hLock);
+               g_PDumpCtrl.hLock = IMG_NULL;
+       }
+}
+
+static INLINE IMG_VOID PDumpCtrlLockAcquire(IMG_VOID)
+{
+       OSLockAcquire(g_PDumpCtrl.hLock);
+}
+
+static INLINE IMG_VOID PDumpCtrlLockRelease(IMG_VOID)
+{
+       OSLockRelease(g_PDumpCtrl.hLock);
+}
+
+/**********************************************************************************************************
+       NOTE:
+       The following PDumpCtrl*** functions require the PDUMP_CTRL_STATE lock be acquired BEFORE they are
+       called. This is because the PDUMP_CTRL_STATE data is shared between the PDumping App and the PDump
+       client, hence an exclusive access is required. The lock can be acquired and released by using the
+       PDumpCtrlLockAcquire & PDumpCtrlLockRelease functions respectively.
+**********************************************************************************************************/
+
+static IMG_VOID PDumpCtrlUpdateCaptureStatus(IMG_VOID)
+{
+       if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
+       {
+               if ((g_PDumpCtrl.ui32CurrentFrame >= g_PDumpCtrl.sCaptureRange.ui32Start) &&
+                       (g_PDumpCtrl.ui32CurrentFrame <= g_PDumpCtrl.sCaptureRange.ui32End) &&
+                       (((g_PDumpCtrl.ui32CurrentFrame - g_PDumpCtrl.sCaptureRange.ui32Start) % g_PDumpCtrl.sCaptureRange.ui32Interval) == 0))
+               {
+                       g_PDumpCtrl.bCaptureOn = IMG_TRUE;
+               }
+               else
+               {
+                       g_PDumpCtrl.bCaptureOn = IMG_FALSE;
+               }
+       }
+       else if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS)
+       {
+               g_PDumpCtrl.bCaptureOn = IMG_TRUE;
+       }
+       else
+       {
+               g_PDumpCtrl.bCaptureOn = IMG_FALSE;
+               PVR_DPF((PVR_DBG_ERROR, "PDumpCtrlSetCurrentFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
+       }
+
+}
+
+static IMG_VOID PDumpCtrlSetCurrentFrame(IMG_UINT32 ui32Frame)
+{
+       g_PDumpCtrl.ui32CurrentFrame = ui32Frame;
+       /* Mirror the value into the debug driver */
+       PDumpOSSetFrame(ui32Frame);
+
+       PDumpCtrlUpdateCaptureStatus();
+
+#if defined(PDUMP_TRACE_STATE) 
+       PDumpCommonDumpState(IMG_FALSE);
+#endif
+}
+
+static IMG_VOID PDumpCtrlSetDefaultCaptureParams(IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32End, IMG_UINT32 ui32Interval)
+{
+       PVR_ASSERT(ui32Interval > 0);
+       PVR_ASSERT(ui32End >= ui32Start);
+       PVR_ASSERT((ui32Mode == DEBUG_CAPMODE_FRAMED) || (ui32Mode == DEBUG_CAPMODE_CONTINUOUS));
+
+       /* Set the capture range to that supplied by the PDump client tool
+        */
+       g_PDumpCtrl.ui32DefaultCapMode = ui32Mode;
+       g_PDumpCtrl.sCaptureRange.ui32Start = ui32Start;
+       g_PDumpCtrl.sCaptureRange.ui32End = ui32End;
+       g_PDumpCtrl.sCaptureRange.ui32Interval = ui32Interval;
+
+       /* Reset the current frame on reset of the capture range, the helps to
+        * avoid inter-pdump start frame issues when the driver is not reloaded.
+        * No need to call PDumpCtrlUpdateCaptureStatus() direct as the set
+        * current frame call will.
+        */
+       PDumpCtrlSetCurrentFrame(0);
+}
+
+static INLINE IMG_BOOL PDumpCtrlCapModIsFramed(IMG_VOID)
+{
+       return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED;
+}
+
+static INLINE IMG_BOOL PDumpCtrlCapModIsContinuous(IMG_VOID)
+{
+       return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS;
+}
+
+static IMG_UINT32 PDumpCtrlGetCurrentFrame(IMG_VOID)
+{
+       return g_PDumpCtrl.ui32CurrentFrame;
+}
+
+static INLINE IMG_BOOL PDumpCtrlCaptureOn(IMG_VOID)
+{
+       return !g_PDumpCtrl.bSuspended && g_PDumpCtrl.bCaptureOn;
+}
+
+static INLINE IMG_BOOL PDumpCtrlCaptureRangePast(IMG_VOID)
+{
+       return (g_PDumpCtrl.ui32CurrentFrame > g_PDumpCtrl.sCaptureRange.ui32End);
+}
+
+/* Used to imply if the PDump client is connected or not. */
+static INLINE IMG_BOOL PDumpCtrlCaptureRangeUnset(IMG_VOID)
+{
+       return ((g_PDumpCtrl.sCaptureRange.ui32Start == FRAME_UNSET) &&
+                       (g_PDumpCtrl.sCaptureRange.ui32End == FRAME_UNSET));
+}
+
+static IMG_BOOL PDumpCtrlIsLastCaptureFrame(IMG_VOID)
+{
+       if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
+       {
+               /* Is the next capture frame within the range end limit? */
+               if ((g_PDumpCtrl.ui32CurrentFrame + g_PDumpCtrl.sCaptureRange.ui32Interval) > g_PDumpCtrl.sCaptureRange.ui32End)
+               {
+                       return IMG_TRUE;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpCtrIsLastCaptureFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
+       }
+
+       /* Return false for continuous capture mode or when in framed mode */
+       return IMG_FALSE;
+}
+
+static INLINE IMG_BOOL PDumpCtrlInitPhaseComplete(IMG_VOID)
+{
+       return !g_PDumpCtrl.bInitPhaseActive;
+}
+
+static INLINE IMG_VOID PDumpCtrlSetInitPhaseComplete(IMG_BOOL bIsComplete)
+{
+       if (bIsComplete)
+       {
+               g_PDumpCtrl.bInitPhaseActive = IMG_FALSE;
+               PDUMP_HEREA(102);
+       }
+       else
+       {
+               g_PDumpCtrl.bInitPhaseActive = IMG_TRUE;
+               PDUMP_HEREA(103);
+       }
+}
+
+static INLINE IMG_VOID PDumpCtrlSuspend(IMG_VOID)
+{
+       PDUMP_HEREA(104);
+       g_PDumpCtrl.bSuspended = IMG_TRUE;
+}
+
+static INLINE IMG_VOID PDumpCtrlResume(IMG_VOID)
+{
+       PDUMP_HEREA(105);
+       g_PDumpCtrl.bSuspended = IMG_FALSE;
+}
+
+static INLINE IMG_BOOL PDumpCtrlIsDumpSuspended(IMG_VOID)
+{
+       return g_PDumpCtrl.bSuspended;
+}
+
+static INLINE IMG_VOID PDumpCtrlPowerTransitionStart(IMG_VOID)
+{
+       g_PDumpCtrl.bInPowerTransition = IMG_TRUE;
+}
+
+static INLINE IMG_VOID PDumpCtrlPowerTransitionEnd(IMG_VOID)
+{
+       g_PDumpCtrl.bInPowerTransition = IMG_FALSE;
+}
+
+static INLINE IMG_BOOL PDumpCtrlInPowerTransition(IMG_VOID)
+{
+       return g_PDumpCtrl.bInPowerTransition;
+}
+
+static PVRSRV_ERROR PDumpCtrlIsCaptureFrame(IMG_BOOL *bIsCapturing)
+{
+       *bIsCapturing = PDumpCtrlCaptureOn();
+       return PVRSRV_OK;
+}
+
+/********************************************************************************
+       End of PDumpCtrl*** functions
+*********************************************************************************/
+
+/*
+       Wrapper functions which need to be exposed in pdump_km.h for use in other
+       pdump_*** modules safely. These functions call the specific PDumpCtrl layer
+       function after acquiring the PDUMP_CTRL_STATE lock, hence making the calls 
+       from other modules hassle free by avoiding the acquire/release CtrlLock
+       calls.
+*/
+
+IMG_VOID PDumpPowerTransitionStart(IMG_VOID)
+{
+       PDumpCtrlLockAcquire();
+       PDumpCtrlPowerTransitionStart();
+       PDumpCtrlLockRelease();
+}
+
+IMG_VOID PDumpPowerTransitionEnd(IMG_VOID)
+{
+       PDumpCtrlLockAcquire();
+       PDumpCtrlPowerTransitionEnd();
+       PDumpCtrlLockRelease();
+}
+
+IMG_BOOL PDumpInPowerTransition(IMG_VOID)
+{
+       IMG_BOOL bPDumpInPowerTransition = IMG_FALSE;
+       
+       PDumpCtrlLockAcquire();
+       bPDumpInPowerTransition = PDumpCtrlInPowerTransition();
+       PDumpCtrlLockRelease();
+
+       return bPDumpInPowerTransition;
+}
+
+IMG_BOOL PDumpIsDumpSuspended(IMG_VOID)
+{
+       IMG_BOOL bPDumpIsDumpSuspended;
+
+       PDumpCtrlLockAcquire();
+       bPDumpIsDumpSuspended = PDumpCtrlIsDumpSuspended();
+       PDumpCtrlLockRelease();
+
+       return bPDumpIsDumpSuspended;
+}
+
+/*****************************************************************************/
+/*     PDump Common Write Layer just above PDump OS Layer                       */
+/*****************************************************************************/
+
+
+/* 
+       Checks in this method were seeded from the original PDumpWriteILock()
+       and DBGDrivWriteCM() and have grown since to ensure PDump output
+       matches legacy output.
+       Note: the order of the checks in this method is important as some
+       writes have multiple pdump flags set!
+ */
+static IMG_BOOL PDumpWriteAllowed(IMG_UINT32 ui32Flags)
+{
+       /* Lock down the PDUMP_CTRL_STATE struct before calling the following
+          PDumpCtrl*** functions. This is to avoid updates to the Control data
+          while we are reading from it */
+       PDumpCtrlLockAcquire();
+
+       /* No writes if in framed mode and range pasted */
+       if (PDumpCtrlCaptureRangePast())
+       {
+               PDUMP_HERE(10);
+               goto unlockAndReturnFalse;
+       }
+
+       /* No writes while writing is suspended */
+       if (PDumpCtrlIsDumpSuspended())
+       {
+               PDUMP_HERE(11);
+               goto unlockAndReturnFalse;
+       }
+
+       /* Prevent PDumping during a power transition */
+       if (PDumpCtrlInPowerTransition())
+       {       /* except when it's flagged */
+               if (ui32Flags & PDUMP_FLAGS_POWER)
+               {
+                       PDUMP_HERE(20);
+                       goto unlockAndReturnTrue;
+               }
+               PDUMP_HERE(16);
+               goto unlockAndReturnFalse;
+       }
+
+       /* Always allow dumping in init phase and when persistent flagged */
+       if (ui32Flags & PDUMP_FLAGS_PERSISTENT)
+       {
+               PDUMP_HERE(12);
+               goto unlockAndReturnTrue;
+       }
+       if (!PDumpCtrlInitPhaseComplete())
+       {
+               PDUMP_HERE(15);
+               goto unlockAndReturnTrue;
+       }
+
+       /* The following checks are made when the driver has completed initialisation */
+
+       /* If PDump client connected allow continuous flagged writes */
+       if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+       {
+               if (PDumpCtrlCaptureRangeUnset()) /* Is client connected? */
+               {
+                       PDUMP_HERE(13);
+                       goto unlockAndReturnFalse;
+               }
+               PDUMP_HERE(14);
+               goto unlockAndReturnTrue;
+       }
+
+       /* No last/deinit statements allowed when not in initialisation phase */
+       if (ui32Flags & PDUMP_FLAGS_DEINIT)
+       {
+               if (PDumpCtrlInitPhaseComplete())
+               {
+                       PDUMP_HERE(17);
+                       PVR_DPF((PVR_DBG_ERROR, "PDumpWriteAllowed: DEINIT flag used at the wrong time outside of initialisation!"));
+                       goto unlockAndReturnFalse;
+               }
+       }
+
+       /* 
+               If no flags are provided then it is FRAMED output and the frame
+               range must be checked matching expected behaviour.
+        */
+       if (PDumpCtrlCapModIsFramed() && !PDumpCtrlCaptureOn())
+       {
+               PDUMP_HERE(18);
+               goto unlockAndReturnFalse;
+       }
+
+       PDUMP_HERE(19);
+
+unlockAndReturnTrue:
+       /* Allow the write to take place */
+       PDumpCtrlLockRelease();
+       return IMG_TRUE;
+
+unlockAndReturnFalse:
+       PDumpCtrlLockRelease();
+       return IMG_FALSE;
+}
+
+#undef PDUMP_DEBUG_SCRIPT_LINES
+
+#if defined(PDUMP_DEBUG_SCRIPT_LINES)
+#define PDUMPOSDEBUGDRIVERWRITE(a,b,c,d) _PDumpOSDebugDriverWrite(a,b,c,d)
+static IMG_UINT32 _PDumpOSDebugDriverWrite( IMG_HANDLE psStream,
+                                                                       IMG_UINT8 *pui8Data,
+                                                                       IMG_UINT32 ui32BCount,
+                                                                       IMG_UINT32 ui32Flags)
+{
+       IMG_CHAR tmp1[80];
+       IMG_CHAR* streamName = "unkn";
+
+       if (g_PDumpScript.sCh.hDeinit == psStream)
+               streamName = "dein";
+       else if (g_PDumpScript.sCh.hInit == psStream)
+               streamName = "init";
+       else if (g_PDumpScript.sCh.hMain == psStream)
+               streamName = "main";
+
+       (void) PDumpOSSprintf(tmp1, 80, "-- %s, %x\n", streamName, ui32Flags);
+       (void) PDumpOSDebugDriverWrite(psStream, tmp1, OSStringLength(tmp1));
+
+       return PDumpOSDebugDriverWrite(psStream, pui8Data, ui32BCount);
+}
+#else
+#define PDUMPOSDEBUGDRIVERWRITE(a,b,c,d) PDumpOSDebugDriverWrite(a,b,c)
+#endif
+
+
+/**************************************************************************/ /*!
+ @Function             PDumpWriteToBuffer
+ @Description  Write the supplied data to the PDump stream buffer and attempt
+                to handle any buffer full conditions to ensure all the data
+                requested to be written, is.
+
+ @Input                        psStream        The address of the PDump stream buffer to write to
+ @Input                        pui8Data    Pointer to the data to be written
+ @Input                        ui32BCount      Number of bytes to write
+ @Input                        ui32Flags       PDump statement flags.
+
+ @Return               IMG_UINT32  Actual number of bytes written, may be less than
+                                                       ui32BCount when buffer full condition could not
+                                                       be avoided.
+*/ /***************************************************************************/
+static IMG_UINT32 PDumpWriteToBuffer(IMG_HANDLE psStream, IMG_UINT8 *pui8Data,
+               IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
+{
+       IMG_UINT32      ui32BytesWritten = 0;
+       IMG_UINT32      ui32Off = 0;
+
+       while (ui32BCount > 0)
+       {
+               ui32BytesWritten = PDUMPOSDEBUGDRIVERWRITE(psStream, &pui8Data[ui32Off], ui32BCount, ui32Flags);
+
+               if (ui32BytesWritten == 0)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: Zero bytes written - release execution"));
+                       PDumpOSReleaseExecution();
+               }
+
+               if (ui32BytesWritten != 0xFFFFFFFFU)
+               {
+                       if (ui32BCount != ui32BytesWritten)
+                       {
+                               PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: partial write of %d bytes of %d bytes", ui32BytesWritten, ui32BCount));
+                       }
+                       ui32Off += ui32BytesWritten;
+                       ui32BCount -= ui32BytesWritten;
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToBuffer: Unrecoverable error received from the debug driver"));
+                       if( PDumpOSGetCtrlState(psStream, DBG_GET_STATE_FLAG_IS_READONLY) )
+                       {
+                               /* Fatal -suspend PDump to prevent flooding kernel log buffer */
+                               PVR_LOG(("PDump suspended, debug driver out of memory"));
+                               /*
+                                       Acquire the control lock before updating "suspended" state. This may not be required
+                                       because "this" is the context which checks the "suspended" state in PDumpWriteAllowed
+                                       before calling this function. So, this update is mainly for other contexts.
+                                       Also, all the other contexts which will/wish-to read the "suspended" state ought to be
+                                       waiting on the bridge lock first and then the PDUMP_OSLOCK (to pdump into script or 
+                                       parameter buffer). However, this acquire may be useful incase the PDump call is being
+                                       made from a direct bridge
+                               */
+                               PDumpCtrlLockAcquire();
+                               PDumpCtrlSuspend();
+                               PDumpCtrlLockRelease();
+                       }
+                       return 0;
+               }
+       }
+
+       /* reset buffer counters */
+       ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
+
+       return ui32BCount;
+}
+
+
+/**************************************************************************/ /*!
+ @Function             PDumpWriteToChannel
+ @Description  Write the supplied data to the PDump channel specified obeying
+                   flags to write to the necessary channel buffers.
+
+ @Input                        psChannel       The address of the script or parameter channel object
+ @Input/Output psWOff          The address of the channel write offsets object to
+                            update on successful writing
+ @Input                        pui8Data    Pointer to the data to be written
+ @Input                        ui32Size        Number of bytes to write
+ @Input                        ui32Flags       PDump statement flags, they may be clear (no flags)
+                            which implies framed data, continuous flagged,
+                            persistent flagged, or continuous AND persistent
+                            flagged and they determine how the data is output.
+                            On the first test app run after driver load, the
+                            Display Controller dumps a resource that is both
+                            continuous and persistent and this needs writing to
+                            both the init (persistent) and main (continuous)
+                            channel buffers to ensure the data is dumped in
+                            subsequent test runs without reloading the driver.
+                                               In subsequent runs the PDump client 'freezes' the
+                                               init buffer so that only one dump of persistent data
+                                               for the "extended init phase" is captured to the
+                                               init buffer.
+
+ @Return               IMG_BOOL    True when the data has been consumed, false otherwise
+*/ /***************************************************************************/
+static IMG_BOOL PDumpWriteToChannel(PDUMP_CHANNEL* psChannel, PDUMP_CHANNEL_WOFFSETS* psWOff,
+               IMG_UINT8* pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
+{
+       IMG_UINT32   ui32BytesWritten = 0;
+
+       PDUMP_HERE(210);
+
+       /* Dump data to deinit buffer when flagged as deinit */
+       if (ui32Flags & PDUMP_FLAGS_DEINIT)
+       {
+               PDUMP_HERE(211);
+               ui32BytesWritten = PDumpWriteToBuffer(psChannel->hDeinit, pui8Data, ui32Size, ui32Flags);
+               if (ui32BytesWritten != ui32Size)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: DEINIT Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
+                       PDUMP_HERE(212);
+                       return IMG_FALSE;
+               }
+
+               if (psWOff)
+               {
+                       psWOff->ui32Deinit += ui32Size;
+               }
+
+       }
+       else
+       {
+               IMG_BOOL bDumpedToInitAlready = IMG_FALSE;
+               IMG_HANDLE*  phStream = IMG_NULL;
+               IMG_UINT32*  pui32Offset = IMG_NULL;
+
+               /* Always append persistent data to init phase so it's available on
+                * subsequent app runs, but also to the main stream if client connected */
+               if (ui32Flags & PDUMP_FLAGS_PERSISTENT)
+               {
+                       PDUMP_HERE(213);
+                       ui32BytesWritten = PDumpWriteToBuffer(  psChannel->hInit, pui8Data, ui32Size, ui32Flags);
+                       if (ui32BytesWritten != ui32Size)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: PERSIST Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
+                               PDUMP_HERE(214);
+                               return IMG_FALSE;
+                       }
+
+                       bDumpedToInitAlready = IMG_TRUE;
+                       if (psWOff)
+                       {
+                               psWOff->ui32Init += ui32Size;
+                       }
+
+                       /* Don't write continuous data if client not connected */
+                       PDumpCtrlLockAcquire();
+                       if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) && PDumpCtrlCaptureRangeUnset())
+                       {
+                               PDumpCtrlLockRelease();
+                               return IMG_TRUE;
+                       }
+                       PDumpCtrlLockRelease();
+               }
+
+               /* Prepare to write the data to the main stream for
+                * persistent, continuous or framed data. Override and use init
+                * stream if driver still in init phase and we have not written 
+                * to it yet.*/
+               PDumpCtrlLockAcquire();
+               if (!PDumpCtrlInitPhaseComplete() && !bDumpedToInitAlready)
+               {
+                       PDUMP_HERE(215);
+                       phStream = &psChannel->hInit;
+                       if (psWOff)
+                       {
+                               pui32Offset = &psWOff->ui32Init;
+                       }
+               }
+               else
+               {
+                       PDUMP_HERE(216);
+                       phStream = &psChannel->hMain;
+                       if (psWOff)
+                       {
+                               pui32Offset = &psWOff->ui32Main;
+                       }
+               }
+               PDumpCtrlLockRelease();
+
+               /* Write the data to the stream */
+               ui32BytesWritten = PDumpWriteToBuffer(*phStream, pui8Data, ui32Size, ui32Flags);
+               if (ui32BytesWritten != ui32Size)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: MAIN Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
+                       PDUMP_HERE(217);
+                       return IMG_FALSE;
+               }
+
+               if (pui32Offset)
+               {
+                       *pui32Offset += ui32BytesWritten;
+               }
+       }
+
+       return IMG_TRUE;
+}
+
+
+PVRSRV_ERROR PDumpWriteParameter(IMG_UINT8 *pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags,
+               IMG_UINT32* pui32FileOffset, IMG_CHAR* aszFilenameStr)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       IMG_BOOL bPDumpCtrlInitPhaseComplete = IMG_FALSE;
+
+       PVR_ASSERT(pui8Data && (ui32Size!=0));
+       PVR_ASSERT(pui32FileOffset && aszFilenameStr);
+
+       PDUMP_HERE(1);
+
+       if (!PDumpWriteAllowed(ui32Flags))
+       {
+               /* Abort write for the above reasons but indicated it was OK to
+                * caller to avoid disrupting the driver */
+               return PVRSRV_OK;
+       }
+
+       PDUMP_HERE(2);
+
+       PDumpCtrlLockAcquire();
+       bPDumpCtrlInitPhaseComplete = PDumpCtrlInitPhaseComplete();
+       PDumpCtrlLockRelease();
+
+       if (!bPDumpCtrlInitPhaseComplete || (ui32Flags & PDUMP_FLAGS_PERSISTENT))
+       {
+               PDUMP_HERE(3);
+
+               /* Init phase stream not expected to get above the file size max */
+               PVR_ASSERT(g_PDumpParameters.sWOff.ui32Init < g_PDumpParameters.ui32MaxFileSize);
+
+               /* Return the file write offset at which the parameter data was dumped */
+               *pui32FileOffset = g_PDumpParameters.sWOff.ui32Init;
+       }
+       else
+       {
+               PDUMP_HERE(4);
+
+               /* Do we need to signal the PDump client that a split is required? */
+               if (g_PDumpParameters.sWOff.ui32Main + ui32Size > g_PDumpParameters.ui32MaxFileSize)
+               {
+                       PDUMP_HERE(5);
+                       PDumpOSSetSplitMarker(g_PDumpParameters.sCh.hMain, g_PDumpParameters.sWOff.ui32Main);
+                       g_PDumpParameters.ui32FileIdx++;
+                       g_PDumpParameters.sWOff.ui32Main = 0;
+               }
+
+               /* Return the file write offset at which the parameter data was dumped */
+               *pui32FileOffset = g_PDumpParameters.sWOff.ui32Main;
+       }
+
+       /* Create the parameter file name, based on index, to be used in the script */
+       if (g_PDumpParameters.ui32FileIdx == 0)
+       {
+               eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PRM_FILE_NAME_MAX, PDUMP_PARAM_0_FILE_NAME);
+       }
+       else
+       {
+               PDUMP_HERE(6);
+               eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PRM_FILE_NAME_MAX, PDUMP_PARAM_N_FILE_NAME, g_PDumpParameters.ui32FileIdx);
+       }
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSSprintf", errExit);
+
+       /* Write the parameter data to the parameter channel */
+       eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+       if (!PDumpWriteToChannel(&g_PDumpParameters.sCh, &g_PDumpParameters.sWOff, pui8Data, ui32Size, ui32Flags))
+       {
+               PDUMP_HERE(7);
+               PVR_LOGG_IF_ERROR(eError, "PDumpWrite", errExit);
+       }
+
+       return PVRSRV_OK;
+
+errExit:
+       return eError;
+}
+
+
+IMG_BOOL PDumpWriteScript(IMG_HANDLE hString, IMG_UINT32 ui32Flags)
+{
+       PVR_ASSERT(hString);
+
+       PDUMP_HERE(201);
+
+       if (!PDumpWriteAllowed(ui32Flags))
+       {
+               /* Abort write for the above reasons but indicated it was OK to
+                * caller to avoid disrupting the driver */
+               return IMG_TRUE;
+       }
+
+       return PDumpWriteToChannel(&g_PDumpScript.sCh, IMG_NULL, (IMG_UINT8*) hString, (IMG_UINT32) OSStringLength((IMG_CHAR*) hString), ui32Flags);
+}
+
+
+/*****************************************************************************/
+
+
+
+
+
+
+struct _PDUMP_CONNECTION_DATA_ {
+       IMG_UINT32                              ui32RefCount;
+       POS_LOCK                                hLock;
+       DLLIST_NODE                             sListHead;
+       IMG_BOOL                                bLastInto;
+       IMG_UINT32                              ui32LastSetFrameNumber;
+       IMG_BOOL                                bWasInCaptureRange;
+       IMG_BOOL                                bIsInCaptureRange;
+       IMG_BOOL                                bLastTransitionFailed;
+       SYNC_CONNECTION_DATA    *psSyncConnectionData;
+};
+
+static PDUMP_CONNECTION_DATA * _PDumpConnectionAcquire(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psPDumpConnectionData->hLock);
+       ui32RefCount = ++psPDumpConnectionData->ui32RefCount;
+       OSLockRelease(psPDumpConnectionData->hLock);
+
+       PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
+                                                __FUNCTION__, psPDumpConnectionData, ui32RefCount);
+
+       return psPDumpConnectionData;
+}
+
+static IMG_VOID _PDumpConnectionRelease(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psPDumpConnectionData->hLock);
+       ui32RefCount = --psPDumpConnectionData->ui32RefCount;
+       OSLockRelease(psPDumpConnectionData->hLock);
+
+       if (ui32RefCount == 0)
+       {
+               OSLockDestroy(psPDumpConnectionData->hLock);
+               PVR_ASSERT(dllist_is_empty(&psPDumpConnectionData->sListHead));
+               OSFreeMem(psPDumpConnectionData);
+       }
+
+       PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
+                                                __FUNCTION__, psPDumpConnectionData, ui32RefCount);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpIsPersistent)
+#endif
+
+IMG_BOOL PDumpIsPersistent(IMG_VOID)
+{
+       IMG_PID uiPID = OSGetCurrentProcessID();
+       IMG_UINTPTR_T puiRetrieve;
+
+       puiRetrieve = HASH_Retrieve(g_psPersistentHash, uiPID);
+       if (puiRetrieve != 0)
+       {
+               PVR_ASSERT(puiRetrieve == PERSISTANT_MAGIC);
+               PDUMP_HEREA(110);
+               return IMG_TRUE;
+       }
+       return IMG_FALSE;
+}
+
+
+/**************************************************************************
+ * Function Name  : GetTempBuffer
+ * Inputs         : None
+ * Outputs        : None
+ * Returns        : Temporary buffer address, or IMG_NULL
+ * Description    : Get temporary buffer address.
+**************************************************************************/
+static IMG_VOID *GetTempBuffer(IMG_VOID)
+{
+       /*
+        * Allocate the temporary buffer, it it hasn't been allocated already.
+        * Return the address of the temporary buffer, or IMG_NULL if it
+        * couldn't be allocated.
+        * It is expected that the buffer will be allocated once, at driver
+        * load time, and left in place until the driver unloads.
+        */
+
+       if (gpvTempBuffer == IMG_NULL)
+       {
+               gpvTempBuffer = OSAllocMem(PDUMP_TEMP_BUFFER_SIZE);
+               if (gpvTempBuffer == IMG_NULL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed"));
+               }
+       }
+
+       return gpvTempBuffer;
+}
+
+static IMG_VOID FreeTempBuffer(IMG_VOID)
+{
+
+       if (gpvTempBuffer != IMG_NULL)
+       {
+               OSFreeMem(gpvTempBuffer);
+               gpvTempBuffer = IMG_NULL;
+       }
+}
+
+/**************************************************************************
+ * Function Name  : PDumpParameterChannelZeroedPageBlock
+ * Inputs         : None
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Set up the zero page block in the parameter stream
+**************************************************************************/
+static PVRSRV_ERROR PDumpParameterChannelZeroedPageBlock(IMG_VOID)
+{
+       IMG_UINT8 aui8Zero[32] = { 0 };
+       IMG_SIZE_T uiBytesToWrite;
+       PVRSRV_ERROR eError;
+
+       g_PDumpParameters.uiZeroPageSize = OSGetPageSize();
+
+       /* ensure the zero page size of a multiple of the zero source on the stack */
+       PVR_ASSERT(g_PDumpParameters.uiZeroPageSize % sizeof(aui8Zero) == 0);
+
+       /* the first write gets the parameter file name and stream offset,
+        * then subsequent writes do not need to know this as the data is
+        * contiguous in the stream
+        */
+       PDUMP_LOCK();
+       eError = PDumpWriteParameter(aui8Zero,
+                                                       sizeof(aui8Zero),
+                                                       0,
+                                                       &g_PDumpParameters.uiZeroPageOffset,
+                                                       g_PDumpParameters.szZeroPageFilename);
+
+       if(eError != PVRSRV_OK)
+       {
+               goto err_write;
+       }
+
+       uiBytesToWrite = g_PDumpParameters.uiZeroPageSize - sizeof(aui8Zero);
+
+       while(uiBytesToWrite)
+       {
+               IMG_BOOL bOK;
+
+               bOK = PDumpWriteToChannel(&g_PDumpParameters.sCh, &g_PDumpParameters.sWOff,
+                                                                       aui8Zero,
+                                                                       sizeof(aui8Zero), 0);
+
+               if(!bOK)
+               {
+                       eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+                       goto err_write;
+               }
+
+               uiBytesToWrite -= sizeof(aui8Zero);
+       }
+
+err_write:
+       PDUMP_UNLOCK();
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to initialise parameter stream zero block"));
+       }
+
+       return eError;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpGetParameterZeroPageInfo
+ * Inputs         : None
+ * Outputs        : puiZeroPageOffset: will be set to the offset of the zero page
+ *                : puiZeroPageSize: will be set to the size of the zero page
+ *                : ppszZeroPageFilename: will be set to a pointer to the PRM file name
+ *                :                       containing the zero page
+ * Returns        : None
+ * Description    : Get information about the zero page
+**************************************************************************/
+IMG_VOID PDumpGetParameterZeroPageInfo(PDUMP_FILEOFFSET_T *puiZeroPageOffset,
+                                       IMG_SIZE_T *puiZeroPageSize,
+                                       const IMG_CHAR **ppszZeroPageFilename)
+{
+               *puiZeroPageOffset = g_PDumpParameters.uiZeroPageOffset;
+               *puiZeroPageSize = g_PDumpParameters.uiZeroPageSize;
+               *ppszZeroPageFilename = g_PDumpParameters.szZeroPageFilename;
+}
+
+PVRSRV_ERROR PDumpInitCommon(IMG_VOID)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 ui32InitCapMode = 0;
+       IMG_CHAR* pszEnvComment = IMG_NULL;
+
+       PDUMP_HEREA(2010);
+
+       /* Allocate temporary buffer for copying from user space */
+       (IMG_VOID) GetTempBuffer();
+
+       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       g_psPersistentHash = HASH_Create(PDUMP_PERSISTENT_HASH_SIZE);
+       PVR_LOGG_IF_FALSE((g_psPersistentHash != IMG_NULL), "Failed to create persistent process hash", errExit);
+
+       /* create the global PDump lock */
+       eError = PDumpCreateLockKM();
+       PVR_LOGG_IF_ERROR(eError, "PDumpCreateLockKM", errExit);
+
+       /* Call environment specific PDump initialisation */
+       eError = PDumpOSInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh, &ui32InitCapMode, &pszEnvComment);
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSInit", errExitLock);
+
+       /* Initialise PDump control module in common layer */
+       eError = PDumpCtrlInit(ui32InitCapMode);
+       PVR_LOGG_IF_ERROR(eError, "PDumpCtrlInit", errExitOSDeInit);
+
+       /* Test PDump initialised and ready by logging driver details */
+       eError = PDumpComment("Driver Product Name: %s", PVRSRVGetSystemName());
+       PVR_LOGG_IF_ERROR(eError, "PDumpComment", errExitCtrl);
+       eError = PDumpComment("Driver Product Version: %s - %s (%s)", PVRVERSION_STRING, PVR_BUILD_DIR, PVR_BUILD_TYPE);
+       PVR_LOGG_IF_ERROR(eError, "PDumpComment", errExitCtrl);
+       if (pszEnvComment != IMG_NULL)
+       {
+               eError = PDumpComment("%s", pszEnvComment);
+               PVR_LOGG_IF_ERROR(eError, "PDumpComment", errExitCtrl);
+       }
+       eError = PDumpComment("Start of Init Phase");
+       PVR_LOGG_IF_ERROR(eError, "PDumpComment", errExitCtrl);
+
+       eError = PDumpParameterChannelZeroedPageBlock();
+       PVR_LOGG_IF_ERROR(eError, "PDumpParameterChannelZeroedPageBlock", errExitCtrl);
+
+       g_PDumpInitialised = IMG_TRUE;
+
+       PDUMP_HEREA(2011);
+
+       return PVRSRV_OK;
+
+errExitCtrl:
+       PDumpCtrlDeInit();
+errExitOSDeInit:
+       PDUMP_HEREA(2018);
+       PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
+errExitLock:
+       PDUMP_HEREA(2019);
+       PDumpDestroyLockKM();
+errExit:
+       return eError;
+}
+
+IMG_VOID PDumpDeInitCommon(IMG_VOID)
+{
+       PDUMP_HEREA(2020);
+
+       g_PDumpInitialised = IMG_FALSE;
+
+       /* Free temporary buffer */
+       FreeTempBuffer();
+
+       /* DeInit the PDUMP_CTRL_STATE data */
+       PDumpCtrlDeInit();
+
+       /* Call environment specific PDump Deinitialisation */
+       PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
+
+       /* take down the global PDump lock */
+       PDumpDestroyLockKM();
+}
+
+IMG_BOOL PDumpReady(IMG_VOID)
+{
+       return g_PDumpInitialised;
+}
+
+
+PVRSRV_ERROR PDumpAddPersistantProcess(IMG_VOID)
+{
+       IMG_PID uiPID = OSGetCurrentProcessID();
+       IMG_UINTPTR_T puiRetrieve;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PDUMP_HEREA(121);
+
+       puiRetrieve = HASH_Retrieve(g_psPersistentHash, uiPID);
+       if (puiRetrieve == 0)
+       {
+               if (!HASH_Insert(g_psPersistentHash, uiPID, PERSISTANT_MAGIC))
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       else
+       {
+               PVR_ASSERT(puiRetrieve == PERSISTANT_MAGIC);
+       }
+       PDUMP_HEREA(122);
+
+       return eError;
+}
+
+PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID)
+{
+       PDUMPCOMMENT("Start Init Phase");
+       PDumpCtrlLockAcquire();
+       PDumpCtrlSetInitPhaseComplete(IMG_FALSE);
+       PDumpCtrlLockRelease();
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_MODULE_ID eModuleID)
+{
+       /* Check with the OS we a running on */
+       if (PDumpOSAllowInitPhaseToComplete(eModuleID))
+       {
+               PDUMPCOMMENT("Stop Init Phase");
+               PDumpCtrlLockAcquire();
+               PDumpCtrlSetInitPhaseComplete(IMG_TRUE);
+               PDumpCtrlLockRelease();
+       }
+
+       return PVRSRV_OK;
+}
+
+IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
+{
+       IMG_BOOL bIsLastCaptureFrame = IMG_FALSE;
+
+       PDumpCtrlLockAcquire();
+       bIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame();
+       PDumpCtrlLockRelease();
+
+       return bIsLastCaptureFrame;
+}
+
+
+
+typedef struct _PDUMP_Transition_DATA_ {
+       PFN_PDUMP_TRANSITION    pfnCallback;
+       IMG_PVOID                               hPrivData;
+       PDUMP_CONNECTION_DATA   *psPDumpConnectionData;
+       DLLIST_NODE                             sNode;
+} PDUMP_Transition_DATA;
+
+PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData,
+                                                                                         PFN_PDUMP_TRANSITION pfnCallback,
+                                                                                         IMG_PVOID hPrivData,
+                                                                                         IMG_PVOID *ppvHandle)
+{
+       PDUMP_Transition_DATA *psData;
+       PVRSRV_ERROR eError;
+
+       psData = OSAllocMem(sizeof(*psData));
+       if (psData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       /* Setup the callback and add it to the list for this process */
+       psData->pfnCallback = pfnCallback;
+       psData->hPrivData = hPrivData;
+       dllist_add_to_head(&psPDumpConnectionData->sListHead, &psData->sNode);
+
+       /* Take a reference on the connection so it doesn't get freed too early */
+       psData->psPDumpConnectionData =_PDumpConnectionAcquire(psPDumpConnectionData);
+       *ppvHandle = psData;
+
+       return PVRSRV_OK;
+
+fail_alloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+IMG_VOID PDumpUnregisterTransitionCallback(IMG_PVOID pvHandle)
+{
+       PDUMP_Transition_DATA *psData = pvHandle;
+
+       dllist_remove_node(&psData->sNode);
+       _PDumpConnectionRelease(psData->psPDumpConnectionData);
+       OSFreeMem(psData);
+}
+
+typedef struct _PTCB_DATA_ {
+       IMG_BOOL bInto;
+       IMG_BOOL bContinuous;
+       PVRSRV_ERROR eError;
+} PTCB_DATA;
+
+static IMG_BOOL _PDumpTransition(DLLIST_NODE *psNode, IMG_PVOID hData)
+{
+       PDUMP_Transition_DATA *psData = IMG_CONTAINER_OF(psNode, PDUMP_Transition_DATA, sNode);
+       PTCB_DATA *psPTCBData = (PTCB_DATA *) hData;
+
+       psPTCBData->eError = psData->pfnCallback(psData->hPrivData, psPTCBData->bInto, psPTCBData->bContinuous);
+       if (psPTCBData->eError != PVRSRV_OK)
+       {
+               /* Got an error, break out of the loop */
+               return IMG_FALSE;
+       }
+
+       return IMG_TRUE;
+}
+
+PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous)
+{
+       PTCB_DATA sPTCBData;
+
+       /* Only call the callbacks if we've really done a Transition */
+       if (bInto != psPDumpConnectionData->bLastInto)
+       {
+               /* We're Transitioning either into or out of capture range */
+               sPTCBData.bInto = bInto;
+               sPTCBData.bContinuous = bContinuous;
+               sPTCBData.eError = PVRSRV_OK;
+               dllist_foreach_node(&psPDumpConnectionData->sListHead, _PDumpTransition, &sPTCBData);
+               if (sPTCBData.eError != PVRSRV_OK)
+               {
+                       /* We failed so bail out leaving the state as it is ready for the retry */
+                       return sPTCBData.eError;
+               }
+
+               if (bInto)
+               {
+                       SyncConnectionPDumpSyncBlocks(psPDumpConnectionData->psSyncConnectionData);
+               }
+               psPDumpConnectionData->bLastInto = bInto;
+       }
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing)
+{
+       PDumpCtrlLockAcquire();
+       PDumpCtrlIsCaptureFrame(bIsCapturing);
+       PDumpCtrlLockRelease();
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _PDumpSetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32 ui32Frame)
+{
+       PDUMP_CONNECTION_DATA *psPDumpConnectionData = psConnection->psPDumpConnectionData;
+       IMG_BOOL bWasInCaptureRange = IMG_FALSE;
+       IMG_BOOL bIsInCaptureRange = IMG_FALSE;
+       PVRSRV_ERROR eError;
+
+       /*
+               Note:
+               As we can't test to see if the new frame will be in capture range
+               before we set the frame number and we don't want to roll back
+               the frame number if we fail then we have to save the "transient"
+               data which decides if we're entering or exiting capture range
+               along with a failure boolean so we know what to do on a retry
+       */
+       if (psPDumpConnectionData->ui32LastSetFrameNumber != ui32Frame)
+       {
+               /*
+                       The boolean values below decide if the PDump transition
+                       should trigger because of the current context setting the
+                       frame number, hence the functions below should execute
+                       atomically and do not give a chance to some other context
+                       to transition
+               */
+               PDumpCtrlLockAcquire(); 
+               
+               PDumpCtrlIsCaptureFrame(&bWasInCaptureRange);
+               PDumpCtrlSetCurrentFrame(ui32Frame);
+               PDumpCtrlIsCaptureFrame(&bIsInCaptureRange);
+
+               PDumpCtrlLockRelease();
+
+               psPDumpConnectionData->ui32LastSetFrameNumber = ui32Frame;
+
+               /* Save the Transition data incase we fail the Transition */
+               psPDumpConnectionData->bWasInCaptureRange = bWasInCaptureRange;
+               psPDumpConnectionData->bIsInCaptureRange = bIsInCaptureRange;
+       }
+       else if (psPDumpConnectionData->bLastTransitionFailed)
+       {
+               /* Load the Transition data so we can try again */
+               bWasInCaptureRange = psPDumpConnectionData->bWasInCaptureRange;
+               bIsInCaptureRange = psPDumpConnectionData->bIsInCaptureRange;
+       }
+       else
+       {
+               /* New frame is the same as the last frame set and the last
+                * transition succeeded, no need to perform another transition.
+                */
+               return PVRSRV_OK;
+       }
+
+       if (!bWasInCaptureRange && bIsInCaptureRange)
+       {
+               eError = PDumpTransition(psPDumpConnectionData, IMG_TRUE, IMG_FALSE);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_Transition;
+               }
+       }
+       else if (bWasInCaptureRange && !bIsInCaptureRange)
+       {
+               eError = PDumpTransition(psPDumpConnectionData, IMG_FALSE, IMG_FALSE);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_Transition;
+               }
+       }
+       else
+       {
+               /* Here both previous and current frames are in or out of range */
+               /* Should never reach here due to the above goto success */
+       }
+
+       psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
+       return PVRSRV_OK;
+
+fail_Transition:
+       psPDumpConnectionData->bLastTransitionFailed = IMG_TRUE;
+       return eError;
+}
+
+PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32 ui32Frame)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;        
+       
+
+#if defined(PDUMP_TRACE_STATE)
+       PVR_DPF((PVR_DBG_WARNING, "PDumpSetFrameKM: ui32Frame( %d )", ui32Frame));
+#endif
+
+       /* Ignore errors as it is not fatal if the comments do not appear */
+       (void) PDumpComment("Set pdump frame %u (pre)", ui32Frame);
+
+       eError = _PDumpSetFrameKM(psConnection, ui32Frame);
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_LOG_ERROR(eError, "_PDumpSetFrameKM");
+       }
+
+       (void) PDumpComment("Set pdump frame %u (post)", ui32Frame);
+
+       return eError;
+}
+
+PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32* pui32Frame)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+       /*
+               It may be safe to avoid acquiring this lock here as all the other calls
+               which read/modify current frame will wait on the PDump Control bridge
+               lock first. Also, in no way as of now, does the PDumping app modify the
+               current frame through a call which acquires the global bridge lock.
+               Still, as a legacy we acquire and then read.
+       */      
+       PDumpCtrlLockAcquire();
+
+       *pui32Frame = PDumpCtrlGetCurrentFrame();
+
+       PDumpCtrlLockRelease();
+       return eError;
+}
+
+PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(IMG_UINT32 ui32Mode,
+                                           IMG_UINT32 ui32Start,
+                                           IMG_UINT32 ui32End,
+                                           IMG_UINT32 ui32Interval,
+                                           IMG_UINT32 ui32MaxParamFileSize)
+{
+       /*
+               Acquire PDUMP_CTRL_STATE struct lock before modifications as a 
+               PDumping app may be reading the state data for some checks
+       */
+       PDumpCtrlLockAcquire();
+       PDumpCtrlSetDefaultCaptureParams(ui32Mode, ui32Start, ui32End, ui32Interval);
+       PDumpCtrlLockRelease();
+
+       if (ui32MaxParamFileSize == 0)
+       {
+               g_PDumpParameters.ui32MaxFileSize = PRM_FILE_SIZE_MAX;
+       }
+       else
+       {
+               g_PDumpParameters.ui32MaxFileSize = ui32MaxParamFileSize;
+       }
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpReg32
+ * Inputs         : pszPDumpDevName, Register offset, and value to write
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Create a PDUMP string, which represents a register write
+**************************************************************************/
+PVRSRV_ERROR PDumpReg32(IMG_CHAR       *pszPDumpRegName,
+                                               IMG_UINT32      ui32Reg,
+                                               IMG_UINT32      ui32Data,
+                                               IMG_UINT32      ui32Flags)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING()
+       PDUMP_DBG(("PDumpReg32"));
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", pszPDumpRegName, ui32Reg, ui32Data);
+
+       if (eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpReg64
+ * Inputs         : pszPDumpDevName, Register offset, and value to write
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Create a PDUMP string, which represents a register write
+**************************************************************************/
+PVRSRV_ERROR PDumpReg64(IMG_CHAR       *pszPDumpRegName,
+                                               IMG_UINT32      ui32Reg,
+                                               IMG_UINT64      ui64Data,
+                                               IMG_UINT32      ui32Flags)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING()
+       PDUMP_DBG(("PDumpRegKM"));
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X 0x%010llX", pszPDumpRegName, ui32Reg, ui64Data);
+
+       if (eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpLDW
+ * Inputs         : pcBuffer -- buffer to send to register bank
+ *                  ui32NumLoadBytes -- number of bytes in pcBuffer
+ *                  pszDevSpaceName -- devspace for register bank
+ *                  ui32Offset -- value of offset control register
+ *                  ui32PDumpFlags -- flags to pass to PDumpOSWriteScript
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Dumps the contents of pcBuffer to a .prm file and
+ *                  writes an LDW directive to the pdump output.
+ *                  NB: ui32NumLoadBytes must be divisible by 4
+**************************************************************************/
+PVRSRV_ERROR PDumpLDW(IMG_CHAR      *pcBuffer,
+                      IMG_CHAR      *pszDevSpaceName,
+                      IMG_UINT32    ui32OffsetBytes,
+                      IMG_UINT32    ui32NumLoadBytes,
+                      PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+       IMG_CHAR aszParamStreamFilename[PMR_MAX_PARAMSTREAM_FILENAME_LENGTH_DEFAULT];
+       IMG_UINT32 ui32ParamStreamFileOffset;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       eError = PDumpWriteBuffer((IMG_UINT8 *)pcBuffer,
+                                 ui32NumLoadBytes,
+                                 uiPDumpFlags,
+                                 &aszParamStreamFilename[0],
+                                 sizeof(aszParamStreamFilename),
+                                 &ui32ParamStreamFileOffset);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                                 ui32MaxLen,
+                                 "LDW :%s:0x%x 0x%x 0x%x %s\n",
+                                 pszDevSpaceName,
+                                 ui32OffsetBytes,
+                                 ui32NumLoadBytes / (IMG_UINT32)sizeof(IMG_UINT32),
+                                 ui32ParamStreamFileOffset,
+                                 aszParamStreamFilename);
+
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpSAW
+ * Inputs         : pszDevSpaceName -- device space from which to output
+ *                  ui32Offset -- offset value from register base
+ *                  ui32NumSaveBytes -- number of bytes to output
+ *                  pszOutfileName -- name of file to output to
+ *                  ui32OutfileOffsetByte -- offset into output file to write
+ *                  uiPDumpFlags -- flags to pass to PDumpOSWriteScript
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Dumps the contents of a register bank into a file
+ *                  NB: ui32NumSaveBytes must be divisible by 4
+**************************************************************************/
+PVRSRV_ERROR PDumpSAW(IMG_CHAR      *pszDevSpaceName,
+                      IMG_UINT32    ui32HPOffsetBytes,
+                      IMG_UINT32    ui32NumSaveBytes,
+                      IMG_CHAR      *pszOutfileName,
+                      IMG_UINT32    ui32OutfileOffsetByte,
+                      PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       PVR_DPF((PVR_DBG_ERROR, "PDumpSAW\n"));
+
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                                 ui32MaxLen,
+                                 "SAW :%s:0x%x 0x%x 0x%x %s\n",
+                                 pszDevSpaceName,
+                                 ui32HPOffsetBytes,
+                                 ui32NumSaveBytes / (IMG_UINT32)sizeof(IMG_UINT32),
+                                 ui32OutfileOffsetByte,
+                                 pszOutfileName);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpOSBufprintf failed: eError=%u\n", eError));
+               return eError;
+       }
+
+       PDUMP_LOCK();
+       if(! PDumpWriteScript(hScript, uiPDumpFlags))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpWriteScript failed!\n"));
+       }
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+       
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpRegPolKM
+ * Inputs         : Description of what this register read is trying to do
+ *                                     pszPDumpDevName
+ *                                     Register offset
+ *                                     expected value
+ *                                     mask for that value
+ * Outputs        : None
+ * Returns        : None
+ * Description    : Create a PDUMP string which represents a register read
+ *                                     with the expected value
+**************************************************************************/
+PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR                            *pszPDumpRegName,
+                                                  IMG_UINT32                   ui32RegAddr, 
+                                                  IMG_UINT32                   ui32RegValue, 
+                                                  IMG_UINT32                   ui32Mask,
+                                                  IMG_UINT32                   ui32Flags,
+                                                  PDUMP_POLL_OPERATOR  eOperator)
+{
+       /* Timings correct for linux and XP */
+       /* Timings should be passed in */
+       #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(("PDumpRegPolKM"));
+       if ( PDumpIsPersistent() )
+       {
+               /* Don't pdump-poll if the process is persistent */
+               return PVRSRV_OK;
+       }
+
+       ui32PollCount = POLL_COUNT_LONG;
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d",
+                                                       pszPDumpRegName, ui32RegAddr, ui32RegValue,
+                                                       ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
+       if(eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpCommentKM
+ * Inputs         : pszComment, ui32Flags
+ * Outputs        : None
+ * Returns        : None
+ * Description    : Dumps a comment
+**************************************************************************/
+PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
+{
+       PVRSRV_ERROR eErr;
+#if defined(PDUMP_DEBUG_OUTFILES)
+       IMG_CHAR pszTemp[256];
+#endif
+       PDUMP_GET_SCRIPT_STRING();
+       PDUMP_DBG(("PDumpCommentKM"));
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+       /* include comments in the "extended" init phase.
+        * default is to ignore them.
+        */
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+       if((pszComment == IMG_NULL) || (PDumpOSBuflen(pszComment, ui32MaxLen) == 0))
+       {
+               /* PDumpOSVerifyLineEnding silently fails if pszComment is too short to
+                  actually hold the line endings that it's trying to enforce, so
+                  short circuit it and force safety */
+               pszComment = "\n";
+       }
+       else
+       {
+               /* Put line ending sequence at the end if it isn't already there */
+               PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
+       }
+
+       PDUMP_LOCK();
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+       /* Prefix comment with PID and line number */
+       eErr = PDumpOSSprintf(pszTemp, 256, "%u %u:%lu %s: %s",
+               g_ui32EveryLineCounter,
+               OSGetCurrentProcessID(),
+               (unsigned long)OSGetCurrentThreadID(),
+               OSGetCurrentProcessName(),
+               pszComment);
+
+       /* Append the comment to the script stream */
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
+               pszTemp);
+#else
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
+               pszComment);
+#endif
+       if( (eErr != PVRSRV_OK) &&
+               (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
+       {
+               PVR_LOGG_IF_ERROR(eErr, "PDumpOSBufprintf", ErrUnlock);
+       }
+
+       if (!PDumpWriteScript(hScript, ui32Flags))
+       {
+               if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+               {
+                       eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+                       PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
+               }
+               else
+               {
+                       eErr = PVRSRV_ERROR_CMD_NOT_PROCESSED;
+                       PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
+               }
+       }
+
+ErrUnlock:
+       PDUMP_UNLOCK();
+       return eErr;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpCommentWithFlags
+ * Inputs         : psPDev - PDev for PDump device
+ *                               : pszFormat - format string for comment
+ *                               : ... - args for format string
+ * Outputs        : None
+ * Returns        : None
+ * Description    : PDumps a comments
+**************************************************************************/
+PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_va_list ap;
+       PDUMP_GET_MSG_STRING();
+
+       /* Construct the 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);
+}
+
+/**************************************************************************
+ * Function Name  : PDumpComment
+ * Inputs         : psPDev - PDev for PDump device
+ *                               : pszFormat - format string for comment
+ *                               : ... - args for format string
+ * Outputs        : None
+ * Returns        : None
+ * Description    : PDumps a comments
+**************************************************************************/
+PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_va_list ap;
+       PDUMP_GET_MSG_STRING();
+
+       /* Construct the string */
+       PDUMP_va_start(ap, pszFormat);
+       eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+       PDUMP_va_end(ap);
+       PVR_LOGR_IF_ERROR(eErr, "PDumpOSVSprintf");
+
+       return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
+}
+
+/*************************************************************************/ /*!
+ * Function Name  : PDumpPanic
+ * Inputs         : ui32PanicNo - Unique number for panic condition
+ *                               : pszPanicMsg - Panic reason message limited to ~90 chars
+ *                               : pszPPFunc   - Function name string where panic occurred
+ *                               : ui32PPline  - Source line number where panic occurred
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : PDumps a panic assertion. Used when the host driver
+ *                : detects a condition that will lead to an invalid PDump
+ *                : script that cannot be played back off-line.
+ */ /*************************************************************************/
+PVRSRV_ERROR PDumpPanic(IMG_UINT32      ui32PanicNo,
+                                               IMG_CHAR*       pszPanicMsg,
+                                               const IMG_CHAR* pszPPFunc,
+                                               IMG_UINT32      ui32PPline)
+{
+       PVRSRV_ERROR   eError = PVRSRV_OK;
+       PDUMP_FLAGS_T  uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS;
+       IMG_CHAR       pszConsoleMsg[] =
+"COM ***************************************************************************\n"
+"COM Script invalid and not compatible with off-line playback. Check test \n"
+"COM parameters and driver configuration, stop imminent.\n"
+"COM ***************************************************************************\n";
+       PDUMP_GET_SCRIPT_STRING();
+
+       /* Log the panic condition to the live kern.log in both REL and DEB mode 
+        * to aid user PDump trouble shooting. */
+       PVR_LOG(("PDUMP PANIC %08x: %s", ui32PanicNo, pszPanicMsg));
+       PVR_DPF((PVR_DBG_MESSAGE, "PDUMP PANIC start %s:%d", pszPPFunc, ui32PPline));
+
+       /* Check the supplied panic reason string is within length limits */
+       PVR_ASSERT(OSStringLength(pszPanicMsg)+sizeof("PANIC   ") < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
+
+       /* Add persistent flag if required and obtain lock to keep the multi-line
+        * panic statement together in a single atomic write */
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+       PDUMP_LOCK();
+
+       /* Write -- Panic start (Function:line) */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- Panic start (%s:%d)", pszPPFunc, ui32PPline);
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
+       (IMG_VOID)PDumpWriteScript(hScript, uiPDumpFlags);
+
+       /* Write COM <message> x4 */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, pszConsoleMsg);
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
+       (IMG_VOID)PDumpWriteScript(hScript, uiPDumpFlags);
+
+       /* Write PANIC no msg command */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, "PANIC %08x %s", ui32PanicNo, pszPanicMsg);
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
+       (IMG_VOID)PDumpWriteScript(hScript, uiPDumpFlags);
+
+       /* Write -- Panic end */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- Panic end");
+       PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
+       (IMG_VOID)PDumpWriteScript(hScript, uiPDumpFlags);
+
+e1:
+       PDUMP_UNLOCK();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PDumpBitmapKM
+
+ @Description
+
+ Dumps a bitmap from device memory to a file
+
+ @Input    psDevId
+ @Input    pszFileName
+ @Input    ui32FileOffset
+ @Input    ui32Width
+ @Input    ui32Height
+ @Input    ui32StrideInBytes
+ @Input    sDevBaseAddr
+ @Input    ui32Size
+ @Input    ePixelFormat
+ @Input    eMemFormat
+ @Input    ui32PDumpFlags
+
+ @Return   PVRSRV_ERROR                        :
+
+******************************************************************************/
+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_UINT32 ui32MMUContextID,
+                                                       IMG_UINT32 ui32Size,
+                                                       PDUMP_PIXEL_FORMAT ePixelFormat,
+                                                       IMG_UINT32 ui32AddrMode,
+                                                       IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
+       PVRSRV_ERROR eErr=0;
+       PDUMP_GET_SCRIPT_STRING();
+
+       if ( PDumpIsPersistent() )
+       {
+               return PVRSRV_OK;
+       }
+       
+       PDumpCommentWithFlags(ui32PDumpFlags, "Dump bitmap of render.");
+       
+       switch (ePixelFormat)
+       {
+               case PVRSRV_PDUMP_PIXEL_FORMAT_YUV8:
+               {
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YUV data. Switching from SII to SAB. Width=0x%08X Height=0x%08X Stride=0x%08X",
+                                                                                                       ui32Width, ui32Height, ui32StrideInBytes);
+                                                                                                       
+                       eErr = PDumpOSBufprintf(hScript,
+                                                                       ui32MaxLen,
+                                                                       "SAB :%s:v%x:0x%010llX 0x%08X 0x%08X %s.bin\n",
+                                                                       psDevId->pszPDumpDevName,
+                                                                       ui32MMUContextID,
+                                                                       sDevBaseAddr.uiAddr,
+                                                                       ui32Size,
+                                                                       ui32FileOffset,
+                                                                       pszFileName);
+                       
+                       if (eErr != PVRSRV_OK)
+                       {
+                               return eErr;
+                       }
+                       
+                       PDUMP_LOCK();
+                       PDumpWriteScript( hScript, ui32PDumpFlags);
+                       PDUMP_UNLOCK();         
+                       break;
+               }
+               case PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8: // YUV420 2 planes
+               {
+                       const IMG_UINT32 ui32Plane0Size = ui32StrideInBytes*ui32Height;
+                       const IMG_UINT32 ui32Plane1Size = ui32Plane0Size>>1; // YUV420
+                       const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32Plane0Size;
+                       const IMG_UINT32 ui32Plane1MemOffset = ui32Plane0Size;
+                       
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 2-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
+                                                                                                       ui32Width, ui32Height, ui32StrideInBytes);
+                       eErr = PDumpOSBufprintf(hScript,
+                                               ui32MaxLen,
+                                               "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
+                                               pszFileName,
+                                               pszFileName,
+                                               
+                                               // Plane 0 (Y)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // Context id
+                                               sDevBaseAddr.uiAddr,            // virtaddr
+                                               ui32Plane0Size,                         // size
+                                               ui32FileOffset,                         // fileoffset
+                                               
+                                               // Plane 1 (UV)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // Context id
+                                               sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
+                                               ui32Plane1Size,                         // size
+                                               ui32Plane1FileOffset,           // fileoffset
+                                               
+                                               ePixelFormat,
+                                               ui32Width,
+                                               ui32Height,
+                                               ui32StrideInBytes,
+                                               ui32AddrMode);
+                                               
+                       if (eErr != PVRSRV_OK)
+                       {
+                               return eErr;
+                       }
+                       
+                       PDUMP_LOCK();
+                       PDumpWriteScript( hScript, ui32PDumpFlags);
+                       PDUMP_UNLOCK();
+                       break;
+               }
+               
+               case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12: // YUV420 3 planes
+               {
+                       const IMG_UINT32 ui32Plane0Size = ui32StrideInBytes*ui32Height;
+                       const IMG_UINT32 ui32Plane1Size = ui32Plane0Size>>2; // YUV420
+                       const IMG_UINT32 ui32Plane2Size = ui32Plane1Size;
+                       const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32Plane0Size;
+                       const IMG_UINT32 ui32Plane2FileOffset = ui32Plane1FileOffset + ui32Plane1Size;
+                       const IMG_UINT32 ui32Plane1MemOffset = ui32Plane0Size;
+                       const IMG_UINT32 ui32Plane2MemOffset = ui32Plane0Size+ui32Plane1Size;
+       
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 3-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
+                                                                                                       ui32Width, ui32Height, ui32StrideInBytes);
+                       eErr = PDumpOSBufprintf(hScript,
+                                               ui32MaxLen,
+                                               "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
+                                               pszFileName,
+                                               pszFileName,
+                                               
+                                               // Plane 0 (Y)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr,            // virtaddr
+                                               ui32Plane0Size,                         // size
+                                               ui32FileOffset,                         // fileoffset
+                                               
+                                               // Plane 1 (U)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
+                                               ui32Plane1Size,                         // size
+                                               ui32Plane1FileOffset,           // fileoffset
+                                               
+                                               // Plane 2 (V)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane2MemOffset,        // virtaddr
+                                               ui32Plane2Size,                         // size
+                                               ui32Plane2FileOffset,           // fileoffset
+                                               
+                                               ePixelFormat,
+                                               ui32Width,
+                                               ui32Height,
+                                               ui32StrideInBytes,
+                                               ui32AddrMode);
+                                               
+                       if (eErr != PVRSRV_OK)
+                       {
+                               return eErr;
+                       }
+                       
+                       PDUMP_LOCK();
+                       PDumpWriteScript( hScript, ui32PDumpFlags);
+                       PDUMP_UNLOCK();
+                       break;
+               }
+               
+               case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32: // YV32 - 4 contiguous planes in the order VUYA, stride can be > width.
+               {
+                       const IMG_UINT32 ui32PlaneSize = ui32StrideInBytes*ui32Height; // All 4 planes are the same size
+                       const IMG_UINT32 ui32Plane0FileOffset = ui32FileOffset + (ui32PlaneSize<<1);            // SII plane 0 is Y, which is YV32 plane 2
+                       const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32PlaneSize;                         // SII plane 1 is U, which is YV32 plane 1
+                       const IMG_UINT32 ui32Plane2FileOffset = ui32FileOffset;                                                         // SII plane 2 is V, which is YV32 plane 0
+                       const IMG_UINT32 ui32Plane3FileOffset = ui32Plane0FileOffset + ui32PlaneSize;           // SII plane 3 is A, which is YV32 plane 3
+                       const IMG_UINT32 ui32Plane0MemOffset = ui32PlaneSize<<1;
+                       const IMG_UINT32 ui32Plane1MemOffset = ui32PlaneSize;
+                       const IMG_UINT32 ui32Plane2MemOffset = 0;
+                       const IMG_UINT32 ui32Plane3MemOffset = ui32Plane0MemOffset + ui32PlaneSize;
+                                                                                                       
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 4 planes. Width=0x%08X Height=0x%08X Stride=0x%08X",
+                                                                                                       ui32Width, ui32Height, ui32StrideInBytes);
+                       
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 plane size is 0x%08X", ui32PlaneSize);
+                       
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 0 Mem Offset=0x%08X", ui32Plane0MemOffset);
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 1 Mem Offset=0x%08X", ui32Plane1MemOffset);
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 2 Mem Offset=0x%08X", ui32Plane2MemOffset);
+                       PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 3 Mem Offset=0x%08X", ui32Plane3MemOffset);
+                       
+                       /*
+                               SII <imageset> <filename>       :<memsp1>:v<id1>:<virtaddr1> <size1> <fileoffset1>              Y
+                                                                                       :<memsp2>:v<id2>:<virtaddr2> <size2> <fileoffset2>              U
+                                                                                       :<memsp3>:v<id3>:<virtaddr3> <size3> <fileoffset3>              V
+                                                                                       :<memsp4>:v<id4>:<virtaddr4> <size4> <fileoffset4>              A
+                                                                                       <pixfmt> <width> <height> <stride> <addrmode>
+                       */
+                       eErr = PDumpOSBufprintf(hScript,
+                                               ui32MaxLen,
+                                               "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
+                                               pszFileName,
+                                               pszFileName,
+                                               
+                                               // Plane 0 (V)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane0MemOffset,        // virtaddr
+                                               ui32PlaneSize,                          // size
+                                               ui32Plane0FileOffset,           // fileoffset
+                                               
+                                               // Plane 1 (U)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
+                                               ui32PlaneSize,                          // size
+                                               ui32Plane1FileOffset,           // fileoffset
+                                               
+                                               // Plane 2 (Y)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane2MemOffset,        // virtaddr
+                                               ui32PlaneSize,                          // size
+                                               ui32Plane2FileOffset,           // fileoffset
+                                               
+                                               // Plane 3 (A)
+                                               psDevId->pszPDumpDevName,       // memsp
+                                               ui32MMUContextID,                       // MMU context id
+                                               sDevBaseAddr.uiAddr+ui32Plane3MemOffset,        // virtaddr
+                                               ui32PlaneSize,                          // size
+                                               ui32Plane3FileOffset,           // fileoffset
+                                               
+                                               ePixelFormat,
+                                               ui32Width,
+                                               ui32Height,
+                                               ui32StrideInBytes,
+                                               ui32AddrMode);
+                                               
+                       if (eErr != PVRSRV_OK)
+                       {
+                               return eErr;
+                       }
+                       
+                       PDUMP_LOCK();
+                       PDumpWriteScript( hScript, ui32PDumpFlags);
+                       PDUMP_UNLOCK();
+                       break;
+               }
+                               
+               default: // Single plane formats
+               {
+                       eErr = PDumpOSBufprintf(hScript,
+                                               ui32MaxLen,
+                                               "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
+                                               pszFileName,
+                                               pszFileName,
+                                               psDevId->pszPDumpDevName,
+                                               ui32MMUContextID,
+                                               sDevBaseAddr.uiAddr,
+                                               ui32Size,
+                                               ui32FileOffset,
+                                               ePixelFormat,
+                                               ui32Width,
+                                               ui32Height,
+                                               ui32StrideInBytes,
+                                               ui32AddrMode);
+                                               
+                       if (eErr != PVRSRV_OK)
+                       {
+                               return eErr;
+                       }
+
+                       PDUMP_LOCK();
+                       PDumpWriteScript( hScript, ui32PDumpFlags);
+                       PDUMP_UNLOCK();
+                       break;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PDumpReadRegKM
+
+ @Description
+
+ Dumps a read from a device register to a file
+
+ @Input    psConnection                : connection info
+ @Input    pszFileName
+ @Input    ui32FileOffset
+ @Input    ui32Address
+ @Input    ui32Size
+ @Input    ui32PDumpFlags
+
+ @Return   PVRSRV_ERROR                        :
+
+******************************************************************************/
+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",
+                       pszPDumpRegName,
+                       ui32Address,
+                       ui32FileOffset,
+                       pszFileName);
+       if(eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript( hScript, ui32PDumpFlags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name         PDumpRegRead32
+ @brief                Dump 32-bit register read to script
+ @param                pszPDumpDevName - pdump device name
+ @param                ui32RegOffset - register offset
+ @param                ui32Flags - pdump flags
+ @return       Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpRegRead32(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",
+                                                       pszPDumpRegName, 
+                                                       ui32RegOffset);
+       if(eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+       return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name         PDumpRegRead64
+ @brief                Dump 64-bit register read to script
+ @param                pszPDumpDevName - pdump device name
+ @param                ui32RegOffset - register offset
+ @param                ui32Flags - pdump flags
+ @return       Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpRegRead64(IMG_CHAR *pszPDumpRegName,
+                                                       const IMG_UINT32 ui32RegOffset,
+                                                       IMG_UINT32 ui32Flags)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING();
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW64 :%s:0x%X",
+                                                       pszPDumpRegName, 
+                                                       ui32RegOffset);
+       if(eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+       return PVRSRV_OK;
+}
+
+
+/*****************************************************************************
+ FUNCTION      : PDumpWriteShiftedMaskedValue
+
+ PURPOSE       : Emits the PDump commands for writing a masked shifted address
+              into another location
+
+ PARAMETERS    : PDump symbolic name and offset of target word
+              PDump symbolic name and offset of source address
+              right shift amount
+              left shift amount
+              mask
+
+ RETURNS       : None
+*****************************************************************************/
+PVRSRV_ERROR
+PDumpWriteShiftedMaskedValue(const IMG_CHAR *pszDestRegspaceName,
+                             const IMG_CHAR *pszDestSymbolicName,
+                             IMG_DEVMEM_OFFSET_T uiDestOffset,
+                             const IMG_CHAR *pszRefRegspaceName,
+                             const IMG_CHAR *pszRefSymbolicName,
+                             IMG_DEVMEM_OFFSET_T uiRefOffset,
+                             IMG_UINT32 uiSHRAmount,
+                             IMG_UINT32 uiSHLAmount,
+                             IMG_UINT32 uiMask,
+                             IMG_DEVMEM_SIZE_T uiWordSize,
+                             IMG_UINT32 uiPDumpFlags)
+{
+       PVRSRV_ERROR         eError;
+
+    /* Suffix of WRW command in PDump (i.e. WRW or WRW64) */
+    const IMG_CHAR       *pszWrwSuffix;
+
+    /* Internal PDump register used for interim calculation */
+    const IMG_CHAR       *pszPDumpIntRegSpace;
+    IMG_UINT32           uiPDumpIntRegNum;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+    if ((uiWordSize != 4) && (uiWordSize != 8))
+    {
+        return PVRSRV_ERROR_NOT_SUPPORTED;
+    }
+
+    pszWrwSuffix = (uiWordSize == 8) ? "64" : "";
+
+    /* Should really "Acquire" a pdump register here */
+    pszPDumpIntRegSpace = pszDestRegspaceName;
+    uiPDumpIntRegNum = 1;
+        
+    eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              /* Should this be "MOV" instead? */
+                              "WRW :%s:$%d :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
+                              /* dest */
+                              pszPDumpIntRegSpace,
+                              uiPDumpIntRegNum,
+                              /* src */
+                              pszRefRegspaceName,
+                              pszRefSymbolicName,
+                              uiRefOffset);
+    if (eError != PVRSRV_OK)
+    {
+        goto ErrOut;
+    }
+
+    PDUMP_LOCK();
+    PDumpWriteScript(hScript, uiPDumpFlags);
+
+    if (uiSHRAmount > 0)
+    {
+        eError = PDumpOSBufprintf(hScript,
+                                  ui32MaxLen,
+                                  "SHR :%s:$%d :%s:$%d 0x%X\n",
+                                  /* dest */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src A */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src B */
+                                  uiSHRAmount);
+        if (eError != PVRSRV_OK)
+        {
+            goto ErrUnlock;
+        }
+        PDumpWriteScript(hScript, uiPDumpFlags);
+    }
+    
+    if (uiSHLAmount > 0)
+    {
+        eError = PDumpOSBufprintf(hScript,
+                                  ui32MaxLen,
+                                  "SHL :%s:$%d :%s:$%d 0x%X\n",
+                                  /* dest */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src A */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src B */
+                                  uiSHLAmount);
+        if (eError != PVRSRV_OK)
+        {
+            goto ErrUnlock;
+        }
+        PDumpWriteScript(hScript, uiPDumpFlags);
+    }
+    
+    if (uiMask != (1ULL << (8*uiWordSize))-1)
+    {
+        eError = PDumpOSBufprintf(hScript,
+                                  ui32MaxLen,
+                                  "AND :%s:$%d :%s:$%d 0x%X\n",
+                                  /* dest */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src A */
+                                  pszPDumpIntRegSpace,
+                                  uiPDumpIntRegNum,
+                                  /* src B */
+                                  uiMask);
+        if (eError != PVRSRV_OK)
+        {
+            goto ErrUnlock;
+        }
+        PDumpWriteScript(hScript, uiPDumpFlags);
+    }
+
+    eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "WRW%s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " :%s:$%d\n",
+                              pszWrwSuffix,
+                              /* dest */
+                              pszDestRegspaceName,
+                              pszDestSymbolicName,
+                              uiDestOffset,
+                              /* src */
+                              pszPDumpIntRegSpace,
+                              uiPDumpIntRegNum);
+    if(eError != PVRSRV_OK)
+    {
+        goto ErrUnlock;
+    }
+    PDumpWriteScript(hScript, uiPDumpFlags);
+
+ErrUnlock:
+       PDUMP_UNLOCK();
+ErrOut:
+       return eError;
+}
+
+
+PVRSRV_ERROR
+PDumpWriteSymbAddress(const IMG_CHAR *pszDestSpaceName,
+                      IMG_DEVMEM_OFFSET_T uiDestOffset,
+                      const IMG_CHAR *pszRefSymbolicName,
+                      IMG_DEVMEM_OFFSET_T uiRefOffset,
+                      const IMG_CHAR *pszPDumpDevName,
+                      IMG_UINT32 ui32WordSize,
+                      IMG_UINT32 ui32AlignShift,
+                      IMG_UINT32 ui32Shift,
+                      IMG_UINT32 uiPDumpFlags)
+{
+    const IMG_CHAR       *pszWrwSuffix = "";
+       PVRSRV_ERROR         eError = PVRSRV_OK;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+    if (ui32WordSize == 8)
+    {
+        pszWrwSuffix = "64";
+    }
+
+    PDUMP_LOCK();
+
+    if (ui32AlignShift != ui32Shift)
+    {
+       /* Write physical address into a variable */
+       eError = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "WRW%s :%s:$1 %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
+                                                       pszWrwSuffix,
+                                                       /* dest */
+                                                       pszPDumpDevName,
+                                                       /* src */
+                                                       pszRefSymbolicName,
+                                                       uiRefOffset);
+               if (eError != PVRSRV_OK)
+               {
+                       goto symbAddress_error;
+               }
+       PDumpWriteScript(hScript, uiPDumpFlags);
+
+       /* apply address alignment  */
+       eError = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "SHR :%s:$1 :%s:$1 0x%X",
+                                                       /* dest */
+                                                       pszPDumpDevName,
+                                                       /* src A */
+                                                       pszPDumpDevName,
+                                                       /* src B */
+                                                       ui32AlignShift);
+               if (eError != PVRSRV_OK)
+               {
+                       goto symbAddress_error;
+               }
+       PDumpWriteScript(hScript, uiPDumpFlags);
+
+       /* apply address shift  */
+       eError = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "SHL :%s:$1 :%s:$1 0x%X",
+                                                       /* dest */
+                                                       pszPDumpDevName,
+                                                       /* src A */
+                                                       pszPDumpDevName,
+                                                       /* src B */
+                                                       ui32Shift);
+               if (eError != PVRSRV_OK)
+               {
+                       goto symbAddress_error;
+               }
+       PDumpWriteScript(hScript, uiPDumpFlags);
+
+
+       /* write result to register */
+       eError = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "WRW%s :%s:0x%08X :%s:$1",
+                                                       pszWrwSuffix,
+                                                       pszDestSpaceName,
+                                                       (IMG_UINT32)uiDestOffset,
+                                                       pszPDumpDevName);
+               if (eError != PVRSRV_OK)
+               {
+                       goto symbAddress_error;
+               }
+       PDumpWriteScript(hScript, uiPDumpFlags);
+    }
+    else
+    {
+               eError = PDumpOSBufprintf(hScript,
+                                                                 ui32MaxLen,
+                                                                 "WRW%s :%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
+                                                                 pszWrwSuffix,
+                                                                 /* dest */
+                                                                 pszDestSpaceName,
+                                                                 uiDestOffset,
+                                                                 /* src */
+                                                                 pszRefSymbolicName,
+                                                                 uiRefOffset);
+               if (eError != PVRSRV_OK)
+               {
+                       goto symbAddress_error;
+               }
+           PDumpWriteScript(hScript, uiPDumpFlags);
+    }
+
+symbAddress_error:
+
+    PDUMP_UNLOCK();
+
+       return eError;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpIDLWithFlags
+ * Inputs         : Idle time in clocks
+ * Outputs        : None
+ * Returns        : Error
+ * Description    : Dump IDL command to script
+**************************************************************************/
+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", ui32Clocks);
+       if(eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpIDL
+ * Inputs         : Idle time in clocks
+ * Outputs        : None
+ * Returns        : Error
+ * Description    : Dump IDL command to script
+**************************************************************************/
+PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
+{
+       return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
+}
+
+/*****************************************************************************
+ FUNCTION      : PDumpRegBasedCBP
+    
+ PURPOSE       : Dump CBP command to script
+
+ PARAMETERS    :
+                         
+ RETURNS       : None
+*****************************************************************************/
+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",
+                        pszPDumpRegName,
+                        ui32RegOffset,
+                        ui32WPosVal,
+                        ui32PacketSize,
+                        ui32BufferSize);
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+       
+       return PVRSRV_OK;               
+}
+
+PVRSRV_ERROR PDumpTRG(IMG_CHAR *pszMemSpace,
+                      IMG_UINT32 ui32MMUCtxID,
+                      IMG_UINT32 ui32RegionID,
+                      IMG_BOOL bEnable,
+                      IMG_UINT64 ui64VAddr,
+                      IMG_UINT64 ui64LenBytes,
+                      IMG_UINT32 ui32XStride,
+                      IMG_UINT32 ui32Flags)
+{
+       PDUMP_GET_SCRIPT_STRING();
+
+       if(bEnable)
+       {
+               PDumpOSBufprintf(hScript, ui32MaxLen,
+                                "TRG :%s:v%u %u 0x%08llX 0x%08llX %u",
+                                pszMemSpace, ui32MMUCtxID, ui32RegionID,
+                                ui64VAddr, ui64LenBytes, ui32XStride);
+       }
+       else
+       {
+               PDumpOSBufprintf(hScript, ui32MaxLen,
+                                "TRG :%s:v%u %u",
+                                pszMemSpace, ui32MMUCtxID, ui32RegionID);
+
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpConnectionNotify
+ * Description    : Called by the srvcore to tell PDump core that the
+ *                  PDump capture and control client has connected
+ **************************************************************************/
+IMG_VOID PDumpConnectionNotify(IMG_VOID)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_NODE      *psThis;
+
+       if (PDumpOSAllowInitPhaseToComplete(IMG_PDUMPCTRL))
+       {
+               /* No 'Stop Init Phase' comment here as in this case as the PDump
+                * client can connect multiple times and we don't want the comment
+                * appearing multiple times in out files.
+                */
+               PDumpCtrlLockAcquire();
+               PDumpCtrlSetInitPhaseComplete(IMG_TRUE);
+               PDumpCtrlLockRelease();
+       }
+
+       g_ConnectionCount++;
+       PVR_LOG(("PDump has connected (%u)", g_ConnectionCount));
+       
+       /* Reset the parameter file attributes */
+       g_PDumpParameters.sWOff.ui32Main = g_PDumpParameters.sWOff.ui32Init;
+       g_PDumpParameters.ui32FileIdx = 0;
+
+       /* Loop over all known devices */
+       psThis = psPVRSRVData->psDeviceNodeList;
+       while (psThis)
+       {
+               if (psThis->pfnPDumpInitDevice)
+               {
+                       /* Reset pdump according to connected device */
+                       psThis->pfnPDumpInitDevice(psThis);
+               }
+               psThis = psThis->psNext;
+       }
+}
+
+/**************************************************************************
+ * Function Name  : PDumpDisconnectionNotify
+ * Description    : Called by the connection_server to tell PDump core that
+ *                  the PDump capture and control client has disconnected
+ **************************************************************************/
+void PDumpDisconnectionNotify(void)
+{
+       PVRSRV_ERROR eErr;
+
+       if (PDumpCtrlCaptureOn())
+       {
+               PVR_LOG(("PDump killed, output files may be invalid or incomplete!"));
+
+               /* Disable capture in server, in case PDump client was killed and did
+                * not get a chance to reset the capture parameters.
+                */
+               eErr = PDumpSetDefaultCaptureParamsKM( DEBUG_CAPMODE_FRAMED,
+                                                      FRAME_UNSET, FRAME_UNSET, 1, 0);
+               PVR_LOG_IF_ERROR(eErr, "PVRSRVPDumpSetDefaultCaptureParams");
+       }
+       else
+       {
+               PVR_LOG(("PDump disconnected"));
+       }
+}
+
+/**************************************************************************
+ * Function Name  : PDumpIfKM
+ * Inputs         : pszPDumpCond - string for condition
+ * Outputs        : None
+ * Returns        : None
+ * Description    : Create a PDUMP string which represents IF command 
+                                       with condition.
+**************************************************************************/
+PVRSRV_ERROR PDumpIfKM(IMG_CHAR                *pszPDumpCond)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING()
+       PDUMP_DBG(("PDumpIfKM"));
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IF %s\n", pszPDumpCond);
+
+       if (eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpElseKM
+ * Inputs         : pszPDumpCond - string for condition
+ * Outputs        : None
+ * Returns        : None
+ * Description    : Create a PDUMP string which represents ELSE command 
+                                       with condition.
+**************************************************************************/
+PVRSRV_ERROR PDumpElseKM(IMG_CHAR              *pszPDumpCond)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING()
+       PDUMP_DBG(("PDumpElseKM"));
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "ELSE %s\n", pszPDumpCond);
+
+       if (eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpFiKM
+ * Inputs         : pszPDumpCond - string for condition
+ * Outputs        : None
+ * Returns        : None
+ * Description    : Create a PDUMP string which represents FI command 
+                                       with condition.
+**************************************************************************/
+PVRSRV_ERROR PDumpFiKM(IMG_CHAR                *pszPDumpCond)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING()
+       PDUMP_DBG(("PDumpFiKM"));
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FI %s\n", pszPDumpCond);
+
+       if (eErr != PVRSRV_OK)
+       {
+               return eErr;
+       }
+
+       PDUMP_LOCK();
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+       PDUMP_UNLOCK();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpCreateLockKM(IMG_VOID)
+{
+       return PDumpOSCreateLock();
+}
+
+IMG_VOID PDumpDestroyLockKM(IMG_VOID)
+{
+       PDumpOSDestroyLock();
+}
+
+IMG_VOID PDumpLockKM(IMG_VOID)
+{
+       PDumpOSLock();
+}
+
+IMG_VOID PDumpUnlockKM(IMG_VOID)
+{
+       PDumpOSUnlock();
+}
+
+#if defined(PVR_TESTING_UTILS)
+extern IMG_VOID PDumpOSDumpState(IMG_VOID);
+
+#if !defined(LINUX)
+IMG_VOID PDumpOSDumpState(IMG_BOOL bDumpOSLayerState)
+{
+       PVR_UNREFERENCED_PARAMETER(bDumpOSLayerState);
+}
+#endif
+
+IMG_VOID PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState)
+{
+       IMG_UINT32* ui32HashData = (IMG_UINT32*)g_psPersistentHash;
+
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpInitialised( %d )",
+                       g_PDumpInitialised) );
+       PVR_LOG(("--- PDUMP COMMON: g_psPersistentHash( %p ) uSize( %d ) uCount( %d )",
+                       g_psPersistentHash, ui32HashData[0], ui32HashData[1]) );
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.hInit( %p ) g_PDumpScript.sCh.hMain( %p ) g_PDumpScript.sCh.hDeinit( %p )",
+                       g_PDumpScript.sCh.hInit, g_PDumpScript.sCh.hMain, g_PDumpScript.sCh.hDeinit) );
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.hInit( %p ) g_PDumpParameters.sCh.hMain( %p ) g_PDumpParameters.sCh.hDeinit( %p )",
+                       g_PDumpParameters.sCh.hInit, g_PDumpParameters.sCh.hMain, g_PDumpParameters.sCh.hDeinit) );
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sWOff.ui32Init( %d ) g_PDumpParameters.sWOff.ui32Main( %d ) g_PDumpParameters.sWOff.ui32Deinit( %d )",
+                       g_PDumpParameters.sWOff.ui32Init, g_PDumpParameters.sWOff.ui32Main, g_PDumpParameters.sWOff.ui32Deinit) );
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.ui32FileIdx( %d )",
+                       g_PDumpParameters.ui32FileIdx) );
+
+       PVR_LOG(("--- PDUMP COMMON: g_PDumpCtrl( %p ) bInitPhaseActive( %d ) ui32Flags( %x )",
+                       &g_PDumpCtrl, g_PDumpCtrl.bInitPhaseActive, g_PDumpCtrl.ui32Flags) );
+       PVR_LOG(("--- PDUMP COMMON: ui32DefaultCapMode( %d ) ui32CurrentFrame( %d )",
+                       g_PDumpCtrl.ui32DefaultCapMode, g_PDumpCtrl.ui32CurrentFrame) );
+       PVR_LOG(("--- PDUMP COMMON: sCaptureRange.ui32Start( %x ) sCaptureRange.ui32End( %x ) sCaptureRange.ui32Interval( %u )",
+                       g_PDumpCtrl.sCaptureRange.ui32Start, g_PDumpCtrl.sCaptureRange.ui32End, g_PDumpCtrl.sCaptureRange.ui32Interval) );
+       PVR_LOG(("--- PDUMP COMMON: bCaptureOn( %d ) bSuspended( %d ) bInPowerTransition( %d )",
+                       g_PDumpCtrl.bCaptureOn, g_PDumpCtrl.bSuspended, g_PDumpCtrl.bInPowerTransition) );
+
+       if (bDumpOSLayerState)
+       {
+               PDumpOSDumpState();
+       }
+}
+#endif
+
+
+PVRSRV_ERROR PDumpRegisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData,
+                                                                        PDUMP_CONNECTION_DATA **ppsPDumpConnectionData)
+{
+       PDUMP_CONNECTION_DATA *psPDumpConnectionData;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(ppsPDumpConnectionData != IMG_NULL);
+
+       psPDumpConnectionData = OSAllocMem(sizeof(*psPDumpConnectionData));
+       if (psPDumpConnectionData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       eError = OSLockCreate(&psPDumpConnectionData->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_lockcreate;
+       }
+
+       dllist_init(&psPDumpConnectionData->sListHead);
+       psPDumpConnectionData->ui32RefCount = 1;
+       psPDumpConnectionData->bLastInto = IMG_FALSE;
+       psPDumpConnectionData->ui32LastSetFrameNumber = FRAME_UNSET;
+       psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
+
+       /*
+        * Although we don't take a ref count here, handle base destruction
+        * will ensure that any resource that might trigger us to do a
+        * Transition will have been freed before the sync blocks which
+        * are keeping the sync connection data alive.
+        */
+       psPDumpConnectionData->psSyncConnectionData = psSyncConnectionData;
+       *ppsPDumpConnectionData = psPDumpConnectionData;
+
+       return PVRSRV_OK;
+
+fail_lockcreate:
+       OSFreeMem(psPDumpConnectionData);
+fail_alloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+IMG_VOID PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
+{
+       _PDumpConnectionRelease(psPDumpConnectionData);
+}
+
+#else  /* defined(PDUMP) */
+/* disable warning about empty module */
+#ifdef _WIN32
+#pragma warning (disable:4206)
+#endif
+#endif /* defined(PDUMP) */
+/*****************************************************************************
+ End of file (pdump_common.c)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/common/pdump_mmu.c b/drivers/gpu/rogue_m/services/server/common/pdump_mmu.c
new file mode 100644 (file)
index 0000000..2efacb1
--- /dev/null
@@ -0,0 +1,1008 @@
+/*************************************************************************/ /*!
+@File
+@Title         MMU PDump functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Common PDump (MMU specific) functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if defined (PDUMP)
+
+#include "img_types.h"
+#include "pdump_mmu.h"
+#include "pdump_osfunc.h"
+#include "pdump_km.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#define MAX_PDUMP_MMU_CONTEXTS (10)
+static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1<<MAX_PDUMP_MMU_CONTEXTS)-1;
+
+/* arbitrary buffer length here. */
+#define MAX_SYMBOLIC_ADDRESS_LENGTH 40
+
+#define MMUPX_FMT(X) ((X<3) ? ((X<2) ?  "MMUPT_\0" : "MMUPD_\0") : "MMUPC_\0")
+
+
+/* Array used to look-up debug strings from MMU_LEVEL */
+static IMG_CHAR ai8MMULevelStringLookup[MMU_LEVEL_LAST][15] =
+               {
+                               "MMU_LEVEL_0",
+                               "PAGE_TABLE",
+                               "PAGE_DIRECTORY",
+                               "PAGE_CATALOGUE",
+               };
+
+static PVRSRV_ERROR 
+_ContiguousPDumpBytes(const IMG_CHAR *pszSymbolicName,
+                      IMG_UINT32 ui32SymAddrOffset,
+                      IMG_BOOL bFlush,
+                      IMG_UINT32 uiNumBytes,
+                      IMG_VOID *pvBytes,
+                      IMG_UINT32 ui32Flags)
+{
+    static const IMG_CHAR *pvBeyondLastPointer;
+    static const IMG_CHAR *pvBasePointer;
+    static IMG_UINT32 ui32BeyondLastOffset;
+    static IMG_UINT32 ui32BaseOffset;
+    static IMG_UINT32 uiAccumulatedBytes = 0;
+       IMG_UINT32 ui32ParamOutPos;
+    PVRSRV_ERROR eErr = PVRSRV_OK;
+
+       PDUMP_GET_SCRIPT_AND_FILE_STRING();
+       PVR_UNREFERENCED_PARAMETER(ui32MaxLenFileName);
+
+    if (!bFlush && uiAccumulatedBytes > 0)
+    {
+        /* do some tests for contiguity.  If it fails, we flush anyway */
+
+        if (pvBeyondLastPointer != pvBytes ||
+            ui32SymAddrOffset != ui32BeyondLastOffset
+            /* NB: ought to check that symbolic name agrees too, but
+               we know this always to be the case in the current use-case */
+            )
+        {
+            bFlush = IMG_TRUE;
+        }
+    }
+
+    /* Flush if necessary */
+    if (bFlush && uiAccumulatedBytes > 0)
+    {        
+        eErr = PDumpWriteParameter((IMG_UINT8 *)(IMG_UINTPTR_T)pvBasePointer,
+                               uiAccumulatedBytes, ui32Flags,
+                               &ui32ParamOutPos, pszFileName);
+       PVR_LOGG_IF_ERROR(eErr, "PDumpWriteParameter", ErrOut);
+
+        eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript,
+                                "LDB %s:0x%X 0x%X 0x%X %s",
+                                /* dest */
+                                pszSymbolicName,
+                                ui32BaseOffset,
+                                /* size */
+                                uiAccumulatedBytes,
+                                /* file offset */
+                                ui32ParamOutPos,
+                                /* filename */
+                                pszFileName);
+       PVR_LOGG_IF_ERROR(eErr, "PDumpOSBufprintf", ErrOut);
+
+        PDumpWriteScript(hScript, ui32Flags);
+
+        uiAccumulatedBytes = 0;
+    }
+
+    /* Initialise offsets and pointers if necessary */
+    if (uiAccumulatedBytes == 0)
+    {
+        ui32BaseOffset = ui32BeyondLastOffset = ui32SymAddrOffset;
+        pvBeyondLastPointer = pvBasePointer = (const IMG_CHAR *)pvBytes;
+    }
+
+    /* Accumulate some bytes */
+    ui32BeyondLastOffset += uiNumBytes;
+    pvBeyondLastPointer += uiNumBytes;
+    uiAccumulatedBytes += uiNumBytes;
+
+ErrOut:
+    return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpMMUMalloc
+ * Inputs         :
+ * Outputs        : 
+ * Returns        : PVRSRV_ERROR
+ * Description    : 
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUMalloc(const IMG_CHAR                     *pszPDumpDevName,
+                                                       MMU_LEVEL                               eMMULevel,
+                                                       IMG_DEV_PHYADDR                 *psDevPAddr,
+                                                       IMG_UINT32                              ui32Size,
+                                                       IMG_UINT32                              ui32Align)
+{
+       PVRSRV_ERROR eErr;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+       IMG_UINT64 ui64SymbolicAddr;
+       IMG_CHAR *pszMMUPX;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       if (eMMULevel >= MMU_LEVEL_LAST)
+       {
+               eErr = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ErrOut;
+       }
+
+       /*
+               Write a comment to the PDump2 script streams indicating the memory allocation
+       */
+       eErr = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "-- MALLOC :%s:%s Size=0x%08X Alignment=0x%08X DevPAddr=0x%08llX",
+                                                       pszPDumpDevName,
+                                                       ai8MMULevelStringLookup[eMMULevel],
+                                                       ui32Size,
+                                                       ui32Align,
+                                                       psDevPAddr->uiAddr);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+
+       /*
+               construct the symbolic address
+       */
+       ui64SymbolicAddr = (IMG_UINT64)psDevPAddr->uiAddr;
+
+       /*
+               Write to the MMU script stream indicating the memory allocation
+       */
+       pszMMUPX = MMUPX_FMT(eMMULevel);
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:%s%016llX 0x%X 0x%X",
+                                                                                       pszPDumpDevName,
+                                                                                       pszMMUPX,
+                                                                                       ui64SymbolicAddr,
+                                                                                       ui32Size,
+                                                                                       ui32Align
+                                                                                       /* don't need this sDevPAddr.uiAddr*/);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrUnlock;
+       }
+       PDumpWriteScript(hScript, ui32Flags);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpMMUFree
+ * Inputs         :
+ * Outputs        : 
+ * Returns        : PVRSRV_ERROR
+ * Description    : 
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUFree(const IMG_CHAR                               *pszPDumpDevName,
+                                                       MMU_LEVEL                                       eMMULevel,
+                                                       IMG_DEV_PHYADDR                         *psDevPAddr)
+{
+       PVRSRV_ERROR eErr;
+       IMG_UINT64 ui64SymbolicAddr;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+       IMG_CHAR *pszMMUPX;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       if (eMMULevel >= MMU_LEVEL_LAST)
+       {
+               eErr = PVRSRV_ERROR_INVALID_PARAMS;
+               goto ErrOut;
+       }
+
+       /*
+               Write a comment to the PDUMP2 script streams indicating the memory free
+       */
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:%s", 
+                                                       pszPDumpDevName, ai8MMULevelStringLookup[eMMULevel]);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+
+       /*
+               construct the symbolic address
+       */
+       ui64SymbolicAddr = (IMG_UINT64)psDevPAddr->uiAddr;
+
+       /*
+               Write to the MMU script stream indicating the memory free
+       */
+       pszMMUPX = MMUPX_FMT(eMMULevel);
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:%s%016llX",
+                                                       pszPDumpDevName,
+                                                       pszMMUPX,
+                                                       ui64SymbolicAddr);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrUnlock;
+       }
+       PDumpWriteScript(hScript, ui32Flags);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpMMUMalloc2
+ * Inputs         :
+ * Outputs        : 
+ * Returns        : PVRSRV_ERROR
+ * Description    : 
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUMalloc2(const IMG_CHAR                    *pszPDumpDevName,
+                                                       const IMG_CHAR                  *pszTableType,/* PAGE_CATALOGUE, PAGE_DIRECTORY, PAGE_TABLE */
+                             const IMG_CHAR *pszSymbolicAddr,
+                             IMG_UINT32                                ui32Size,
+                             IMG_UINT32                                ui32Align)
+{
+       PVRSRV_ERROR eErr;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       /*
+               Write a comment to the PDump2 script streams indicating the memory allocation
+       */
+       eErr = PDumpOSBufprintf(hScript,
+                                                       ui32MaxLen,
+                                                       "-- MALLOC :%s:%s Size=0x%08X Alignment=0x%08X\n",
+                                                       pszPDumpDevName,
+                                                       pszTableType,
+                                                       ui32Size,
+                                                       ui32Align);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+
+       /*
+               Write to the MMU script stream indicating the memory allocation
+       */
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:%s 0x%X 0x%X\n",
+                                                                                       pszPDumpDevName,
+                                                                                       pszSymbolicAddr,
+                                                                                       ui32Size,
+                                                                                       ui32Align
+                                                                                       /* don't need this sDevPAddr.uiAddr*/);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrUnlock;
+       }
+       PDumpWriteScript(hScript, ui32Flags);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpMMUFree2
+ * Inputs         :
+ * Outputs        : 
+ * Returns        : PVRSRV_ERROR
+ * Description    : 
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUFree2(const IMG_CHAR                              *pszPDumpDevName,
+                                                       const IMG_CHAR                          *pszTableType,/* PAGE_CATALOGUE, PAGE_DIRECTORY, PAGE_TABLE */
+                           const IMG_CHAR *pszSymbolicAddr)
+{
+       PVRSRV_ERROR eErr;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       /*
+               Write a comment to the PDUMP2 script streams indicating the memory free
+       */
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:%s\n", 
+                                                       pszPDumpDevName, pszTableType);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+
+       /*
+               Write to the MMU script stream indicating the memory free
+       */
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:%s\n",
+                            pszPDumpDevName,
+                                                       pszSymbolicAddr);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrUnlock;
+       }
+       PDumpWriteScript(hScript, ui32Flags);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpMMUDumpPxEntries
+ * Inputs         :
+ * Outputs        :
+ * Returns        : PVRSRV_ERROR
+ * Description    :
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUDumpPxEntries(MMU_LEVEL eMMULevel,
+                                                                  const IMG_CHAR *pszPDumpDevName,
+                                   IMG_VOID *pvPxMem,
+                                   IMG_DEV_PHYADDR sPxDevPAddr,
+                                   IMG_UINT32 uiFirstEntry,
+                                   IMG_UINT32 uiNumEntries,
+                                   const IMG_CHAR *pszMemspaceName,
+                                   const IMG_CHAR *pszSymbolicAddr,
+                                   IMG_UINT64 uiSymbolicAddrOffset,
+                                   IMG_UINT32 uiBytesPerEntry,
+                                   IMG_UINT32 uiLog2Align,
+                                   IMG_UINT32 uiAddrShift,
+                                   IMG_UINT64 uiAddrMask,
+                                   IMG_UINT64 uiPxEProtMask,
+                                   IMG_UINT32 ui32Flags)
+{
+       PVRSRV_ERROR eErr = PVRSRV_OK;
+    IMG_UINT64 ui64PxSymAddr;
+    IMG_UINT64 ui64PxEValueSymAddr;
+    IMG_UINT32 ui32SymAddrOffset = 0;
+    IMG_UINT32 *pui32PxMem;
+    IMG_UINT64 *pui64PxMem;
+    IMG_BOOL   bPxEValid;
+    IMG_UINT32 uiPxEIdx;
+    IMG_INT32  iShiftAmount;
+    IMG_CHAR   *pszWrwSuffix = 0;
+    IMG_VOID *pvRawBytes = 0;
+    IMG_CHAR aszPxSymbolicAddr[MAX_SYMBOLIC_ADDRESS_LENGTH];
+    IMG_UINT64 ui64PxE64;
+    IMG_UINT64 ui64Protflags64;
+    IMG_CHAR *pszMMUPX;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       if (!PDumpReady())
+       {
+               eErr = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+               goto ErrOut;
+       }
+
+
+       if (PDumpIsDumpSuspended())
+       {
+               eErr = PVRSRV_OK;
+               goto ErrOut;
+       }
+
+    if (pvPxMem == IMG_NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "PDUMPMMUDUMPPxENTRIES: PxMem is Null"));
+        eErr = PVRSRV_ERROR_INVALID_PARAMS;
+        goto ErrOut;
+    }
+
+
+       /*
+               create the symbolic address of the Px
+       */
+       ui64PxSymAddr = sPxDevPAddr.uiAddr;
+
+       pszMMUPX = MMUPX_FMT(eMMULevel);
+    OSSNPrintf(aszPxSymbolicAddr,
+               MAX_SYMBOLIC_ADDRESS_LENGTH,
+               ":%s:%s%016llX",
+               pszPDumpDevName,
+               pszMMUPX,
+               ui64PxSymAddr);
+
+    PDumpOSLock();
+
+       /*
+               traverse PxEs, dumping entries
+       */
+       for(uiPxEIdx = uiFirstEntry;
+        uiPxEIdx < uiFirstEntry + uiNumEntries;
+        uiPxEIdx++)
+       {
+               /* Calc the symbolic address offset of the PxE location
+                  This is what we have to add to the table address to get to a certain entry */
+               ui32SymAddrOffset = (uiPxEIdx*uiBytesPerEntry);
+
+               /* Calc the symbolic address of the PxE value and HW protflags */
+               /* just read it here */
+               switch(uiBytesPerEntry)
+               {
+                       case 4:
+                       {
+                               pui32PxMem = pvPxMem;
+                ui64PxE64 = pui32PxMem[uiPxEIdx];
+                pszWrwSuffix = "";
+                pvRawBytes = &pui32PxMem[uiPxEIdx];
+                               break;
+                       }
+                       case 8:
+                       {
+                               pui64PxMem = pvPxMem;
+                ui64PxE64 = pui64PxMem[uiPxEIdx];
+                pszWrwSuffix = "64";
+                pvRawBytes = &pui64PxMem[uiPxEIdx];
+                               break;
+                       }
+                       default:
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PDumpMMUPxEntries: error"));
+                               ui64PxE64 = 0;
+                //!!error
+                               break;
+                       }
+               }
+
+        ui64PxEValueSymAddr = (ui64PxE64 & uiAddrMask) >> uiAddrShift << uiLog2Align;
+        ui64Protflags64 = ui64PxE64 & uiPxEProtMask;
+
+        bPxEValid = (ui64Protflags64 & 1) ? IMG_TRUE : IMG_FALSE;
+
+        if(bPxEValid)
+        {
+            _ContiguousPDumpBytes(aszPxSymbolicAddr, ui32SymAddrOffset, IMG_TRUE,
+                                  0, 0,
+                                  ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+
+            iShiftAmount = (IMG_INT32)(uiLog2Align - uiAddrShift);
+
+            /* First put the symbolic representation of the actual
+               address of the entry into a pdump internal register */
+            /* MOV seemed cleaner here, since (a) it's 64-bit; (b) the
+               target is not memory.  However, MOV cannot do the
+               "reference" of the symbolic address.  Apparently WRW is
+               correct. */
+
+                       if (pszSymbolicAddr == IMG_NULL)
+                       {
+                               pszSymbolicAddr = "none";
+                       }
+
+            if (eMMULevel == MMU_LEVEL_1)
+            {
+               if (iShiftAmount == 0)
+                           {
+                       eErr = PDumpOSBufprintf(hScript,
+                                                                                       ui32MaxLen,
+                                                                                       "WRW%s :%s:%s%016llX:0x%08X :%s:%s:0x%llx | 0x%llX\n",
+                                                                                       pszWrwSuffix,
+                                                                                       /* dest */
+                                                                                       pszPDumpDevName,
+                                                                                       pszMMUPX,
+                                                                                       ui64PxSymAddr,
+                                                                                       ui32SymAddrOffset,
+                                                                                       /* src */
+                                                                                       pszMemspaceName,
+                                                                                       pszSymbolicAddr,
+                                                                                       uiSymbolicAddrOffset,
+                                                                                       /* ORing prot flags */
+                                                                                       ui64Protflags64);
+                }
+                else
+                {
+                       eErr = PDumpOSBufprintf(hScript,
+                                                               ui32MaxLen,
+                                                               "WRW :%s:$1 :%s:%s:0x%llx\n",
+                                                               /* dest */
+                                                               pszPDumpDevName,
+                                                                                   /* src */
+                                                                               pszMemspaceName,
+                                                                                       pszSymbolicAddr,
+                                                                                       uiSymbolicAddrOffset);
+                }
+            }
+            else
+            {
+               pszMMUPX = MMUPX_FMT(eMMULevel-1);
+               eErr = PDumpOSBufprintf(hScript,
+                                    ui32MaxLen,
+                                    "WRW :%s:$1 :%s:%s%016llX:0x0",
+                                    /* dest */
+                                    pszPDumpDevName,
+                                    /* src */
+                                    pszPDumpDevName,
+                                    pszMMUPX,
+                                    ui64PxEValueSymAddr);
+               pszMMUPX = MMUPX_FMT(eMMULevel);
+            }
+            if (eErr != PVRSRV_OK)
+            {
+                goto ErrUnlock;
+            }
+            PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+
+            /* Now shift it to the right place, if necessary: */
+            /* Now shift that value down, by the "Align shift"
+               amount, to get it into units (ought to assert that
+               we get an integer - i.e. we don't shift any bits
+               off the bottom, don't know how to do PDUMP
+               assertions yet) and then back up by the right
+               amount to get it into the position of the field.
+               This is optimised into a single shift right by the
+               difference between the two. */
+            if (iShiftAmount > 0)
+            {
+                /* Page X Address is specified in units larger
+                   than the position in the PxE would suggest.  */
+                eErr = PDumpOSBufprintf(hScript,
+                                        ui32MaxLen,
+                                        "SHR :%s:$1 :%s:$1 0x%X",
+                                        /* dest */
+                                        pszPDumpDevName,
+                                        /* src A */
+                                        pszPDumpDevName,
+                                        /* src B */
+                                        iShiftAmount);
+                if (eErr != PVRSRV_OK)
+                {
+                    goto ErrUnlock;
+                }
+                PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+            }
+            else if (iShiftAmount < 0)
+            {
+                /* Page X Address is specified in units smaller
+                   than the position in the PxE would suggest.  */
+                eErr = PDumpOSBufprintf(hScript,
+                                        ui32MaxLen,
+                                        "SHL :%s:$1 :%s:$1 0x%X",
+                                        /* dest */
+                                        pszPDumpDevName,
+                                        /* src A */
+                                        pszPDumpDevName,
+                                        /* src B */
+                                        -iShiftAmount);
+                if (eErr != PVRSRV_OK)
+                {
+                    goto ErrUnlock;
+                }
+                PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+            }
+
+            if (eMMULevel == MMU_LEVEL_1)
+            {
+               if( iShiftAmount != 0)
+               {
+                                       eErr = PDumpOSBufprintf(hScript,
+                                                                                       ui32MaxLen,
+                                                                                       "WRW%s :%s:%s%016llX:0x%08X :%s:$1  | 0x%llX",
+                                                                                       pszWrwSuffix,
+                                                                                       /* dest */
+                                                                                       pszPDumpDevName,
+                                                                                       pszMMUPX,
+                                                                                       ui64PxSymAddr,
+                                                                                       ui32SymAddrOffset,
+                                                                                       /* src */
+                                                                                       pszPDumpDevName,
+                                                                                       /* ORing prot flags */
+                                                                                       ui64Protflags64);
+                                       if(eErr != PVRSRV_OK)
+                                       {
+                                               goto ErrUnlock;
+                                       }
+                                       PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+               }
+             }
+            else
+            {
+               /* Now we can "or" in the protection flags */
+               eErr = PDumpOSBufprintf(hScript,
+                                       ui32MaxLen,
+                                       "OR :%s:$1 :%s:$1 0x%llX",
+                                       /* dest */
+                                       pszPDumpDevName,
+                                       /* src A */
+                                       pszPDumpDevName,
+                                       /* src B */
+                                        ui64Protflags64);
+               if (eErr != PVRSRV_OK)
+               {
+                       goto ErrUnlock;
+               }
+                PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+
+                /* Finally, we write the register into the actual PxE */
+               eErr = PDumpOSBufprintf(hScript,
+                                        ui32MaxLen,
+                                        "WRW%s :%s:%s%016llX:0x%08X :%s:$1",
+                                        pszWrwSuffix,
+                                        /* dest */
+                                        pszPDumpDevName,
+                                        pszMMUPX,
+                                        ui64PxSymAddr,
+                                        ui32SymAddrOffset,
+                                        /* src */
+                                        pszPDumpDevName);
+                               if(eErr != PVRSRV_OK)
+                               {
+                                       goto ErrUnlock;
+                               }
+                               PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+               }
+        }
+        else
+        {
+            /* If the entry was "invalid", simply write the actual
+               value found to the memory location */
+            eErr = _ContiguousPDumpBytes(aszPxSymbolicAddr, ui32SymAddrOffset, IMG_FALSE,
+                                         uiBytesPerEntry, pvRawBytes,
+                                         ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+            if (eErr != PVRSRV_OK)
+            {
+                goto ErrUnlock;
+            }
+        }
+       }
+
+    /* flush out any partly accumulated stuff for LDB */
+    _ContiguousPDumpBytes(aszPxSymbolicAddr, ui32SymAddrOffset, IMG_TRUE,
+                          0, 0,
+                          ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : _PdumpAllocMMUContext
+ * Inputs         : pui32MMUContextID
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : pdump util to allocate MMU contexts
+**************************************************************************/
+static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
+{
+       IMG_UINT32 i;
+
+       /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */
+       for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
+       {
+               if((guiPDumpMMUContextAvailabilityMask & (1U << i)))
+               {
+                       /* mark in use */
+                       guiPDumpMMUContextAvailabilityMask &= ~(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;
+}
+
+
+/**************************************************************************
+ * Function Name  : _PdumpFreeMMUContext
+ * Inputs         : ui32MMUContextID
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : pdump util to free MMU contexts
+**************************************************************************/
+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
+{
+       if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
+       {
+               /* free the id */
+        PVR_ASSERT (!(guiPDumpMMUContextAvailabilityMask & (1U << ui32MMUContextID)));
+               guiPDumpMMUContextAvailabilityMask |= (1U << ui32MMUContextID);
+               return PVRSRV_OK;
+       }
+
+       PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
+
+       return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpSetMMUContext
+ * Inputs         :
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Set MMU Context
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUAllocMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
+                                     IMG_DEV_PHYADDR sPCDevPAddr,
+                                     PDUMP_MMU_TYPE eMMUType,
+                                     IMG_UINT32 *pui32MMUContextID)
+{
+    IMG_UINT64 ui64PCSymAddr;
+    IMG_CHAR *pszMMUPX;
+
+       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));
+        PVR_DBG_BREAK;
+               goto ErrOut;
+       }
+
+       /*
+               create the symbolic address of the PC
+    */
+       ui64PCSymAddr = sPCDevPAddr.uiAddr;
+
+       pszMMUPX = MMUPX_FMT(3);
+       eErr = PDumpOSBufprintf(hScript,
+                            ui32MaxLen, 
+                            "MMU :%s:v%d %d :%s:%s%016llX",
+                            /* mmu context */
+                            pszPDumpMemSpaceName,
+                            ui32MMUContextID,
+                            /* mmu type */
+                            eMMUType,
+                            /* PC base address */
+                            pszPDumpMemSpaceName,
+                            pszMMUPX,
+                            ui64PCSymAddr);
+       if(eErr != PVRSRV_OK)
+       {
+        PVR_DBG_BREAK;
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+    PDumpOSUnlock();
+
+       /* return the MMU Context ID */
+       *pui32MMUContextID = ui32MMUContextID;
+
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpClearMMUContext
+ * Inputs         :
+ * Outputs        : None
+ * Returns        : PVRSRV_ERROR
+ * Description    : Clear MMU Context
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUFreeMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
+                                    IMG_UINT32 ui32MMUContextID)
+{
+       PVRSRV_ERROR eErr;
+       PDUMP_GET_SCRIPT_STRING();
+
+       eErr = PDumpOSBufprintf(hScript,
+                            ui32MaxLen,
+                            "-- Clear MMU Context for memory space %s", pszPDumpMemSpaceName);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+       eErr = PDumpOSBufprintf(hScript,
+                            ui32MaxLen, 
+                            "MMU :%s:v%d",
+                            pszPDumpMemSpaceName,
+                            ui32MMUContextID);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrUnlock;
+       }
+
+       PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+       eErr = _PdumpFreeMMUContext(ui32MMUContextID);
+       if(eErr != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
+               goto ErrUnlock;
+       }
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpMMUActivateCatalog
+ * Inputs         :
+ * Outputs        : 
+ * Returns        : PVRSRV_ERROR
+ * Description    : 
+**************************************************************************/
+PVRSRV_ERROR PDumpMMUActivateCatalog(const IMG_CHAR *pszPDumpRegSpaceName,
+                                     const IMG_CHAR *pszPDumpRegName,
+                                     IMG_UINT32 uiRegAddr,
+                                     const IMG_CHAR *pszPDumpPCSymbolicName)
+{
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+       PVRSRV_ERROR eErr;
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       if (!PDumpReady())
+       {
+               return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+       }
+
+
+       if (PDumpIsDumpSuspended())
+       {
+               return PVRSRV_OK;
+       }
+
+       eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+                                                       "-- Write Page Catalogue Address to %s",
+                                                       pszPDumpRegName);
+       if(eErr != PVRSRV_OK)
+       {
+               goto ErrOut;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+
+    eErr = PDumpOSBufprintf(hScript,
+                            ui32MaxLen,
+                            "WRW :%s:0x%04X %s:0",
+                            /* dest */
+                            pszPDumpRegSpaceName,
+                            uiRegAddr,
+                            /* src */
+                            pszPDumpPCSymbolicName);
+    if (eErr != PVRSRV_OK)
+    {
+        goto ErrUnlock;
+    }
+    PDumpWriteScript(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+
+ErrUnlock:
+       PDumpOSUnlock();
+ErrOut:
+       return eErr;
+}
+
+
+PVRSRV_ERROR
+PDumpMMUSAB(const IMG_CHAR *pszPDumpMemNamespace,
+               IMG_UINT32 uiPDumpMMUCtx,
+               IMG_DEV_VIRTADDR sDevAddrStart,
+               IMG_DEVMEM_SIZE_T uiSize,
+               const IMG_CHAR *pszFilename,
+               IMG_UINT32 uiFileOffset,
+                          IMG_UINT32 ui32PDumpFlags)
+{    
+    PVRSRV_ERROR eError;
+
+    //                                                 "SAB :%s:v%x:0x%010llX 0x%08X 0x%08X %s.bin",
+
+       PDUMP_GET_SCRIPT_STRING();
+
+       ui32PDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       if (!PDumpReady())
+       {
+               eError = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+               goto ErrOut;
+       }
+
+
+       if (PDumpIsDumpSuspended())
+       {
+               eError = PVRSRV_OK;
+               goto ErrOut;
+       }
+
+    eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "SAB :%s:v%x:" IMG_DEV_VIRTADDR_FMTSPEC " "
+                              IMG_DEVMEM_SIZE_FMTSPEC " "
+                              "0x%x %s.bin\n",
+                              pszPDumpMemNamespace,
+                              uiPDumpMMUCtx,
+                              sDevAddrStart.uiAddr,
+                              uiSize,
+                              uiFileOffset,
+                              pszFilename);
+    PVR_ASSERT(eError == PVRSRV_OK);
+    PDumpOSLock();
+    PDumpWriteScript(hScript, ui32PDumpFlags);
+    PDumpOSUnlock();
+
+ErrOut:
+    return eError;
+}
+
+#endif /* #if defined (PDUMP) */
+
diff --git a/drivers/gpu/rogue_m/services/server/common/pdump_physmem.c b/drivers/gpu/rogue_m/services/server/common/pdump_physmem.c
new file mode 100644 (file)
index 0000000..79349b9
--- /dev/null
@@ -0,0 +1,479 @@
+/*************************************************************************/ /*!
+@File
+@Title         Physmem PDump functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Common PDump (PMR specific) functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if defined(PDUMP)
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "pdump_physmem.h"
+#include "pdump_osfunc.h"
+#include "pdump_km.h"
+
+#include "allocmem.h"
+#include "osfunc.h"
+
+/* #define MAX_PDUMP_MMU_CONTEXTS      (10) */
+/* static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1<<MAX_PDUMP_MMU_CONTEXTS)-1; */
+
+
+/* arbitrary buffer length here. */
+#define MAX_SYMBOLIC_ADDRESS_LENGTH 40
+
+struct _PDUMP_PHYSMEM_INFO_T_
+{
+    IMG_CHAR aszSymbolicAddress[MAX_SYMBOLIC_ADDRESS_LENGTH];
+    IMG_UINT64 ui64Size;
+    IMG_UINT32 ui32Align;
+    IMG_UINT32 ui32SerialNum;
+};
+
+
+/**************************************************************************
+ * Function Name  : PDumpPMRMalloc
+ * Inputs         :
+ * Outputs        :
+ * Returns        : PVRSRV_ERROR
+ * Description    :
+**************************************************************************/
+PVRSRV_ERROR PDumpPMRMalloc(const IMG_CHAR *pszDevSpace,
+                            const IMG_CHAR *pszSymbolicAddress,
+                            IMG_UINT64 ui64Size,
+                            IMG_DEVMEM_ALIGN_T uiAlign,
+                            IMG_BOOL bForcePersistent,
+                            IMG_HANDLE *phHandlePtr)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+    PDUMP_PHYSMEM_INFO_T *psPDumpAllocationInfo;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+    psPDumpAllocationInfo = OSAllocMem(sizeof*psPDumpAllocationInfo);
+    PVR_ASSERT(psPDumpAllocationInfo != IMG_NULL);
+
+       if (bForcePersistent)
+       {
+               ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+       }
+       else
+       {
+               ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+       }
+
+       /*
+               construct the symbolic address
+       */
+
+    OSSNPrintf(psPDumpAllocationInfo->aszSymbolicAddress,
+               sizeof(psPDumpAllocationInfo->aszSymbolicAddress),
+               ":%s:%s",
+               pszDevSpace,
+               pszSymbolicAddress);
+
+       /*
+               Write to the MMU script stream indicating the memory allocation
+       */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC %s 0x%llX 0x%llX\n",
+                            psPDumpAllocationInfo->aszSymbolicAddress,
+                            ui64Size,
+                            uiAlign);
+       if(eError != PVRSRV_OK)
+       {
+               OSFreeMem(psPDumpAllocationInfo);
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDumpOSUnlock();
+
+    psPDumpAllocationInfo->ui64Size = ui64Size;
+    psPDumpAllocationInfo->ui32Align = TRUNCATE_64BITS_TO_32BITS(uiAlign);
+
+    *phHandlePtr = (IMG_HANDLE)psPDumpAllocationInfo;
+
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name  : PDumpPMRFree
+ * Inputs         :
+ * Outputs        :
+ * Returns        : PVRSRV_ERROR
+ * Description    :
+**************************************************************************/
+PVRSRV_ERROR PDumpPMRFree(IMG_HANDLE hPDumpAllocationInfoHandle)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+    PDUMP_PHYSMEM_INFO_T *psPDumpAllocationInfo;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+    psPDumpAllocationInfo = (PDUMP_PHYSMEM_INFO_T *)hPDumpAllocationInfoHandle;
+
+       ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       /*
+               Write to the MMU script stream indicating the memory free
+       */
+       eError = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE %s\n",
+                              psPDumpAllocationInfo->aszSymbolicAddress);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       PDumpOSLock();
+       PDumpWriteScript(hScript, ui32Flags);
+       PDumpOSUnlock();
+
+    OSFreeMem(psPDumpAllocationInfo);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpPMRWRW32(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT32 ui32Value,
+            PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "WRW :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              PMR_VALUE32_FMTSPEC " ",
+                              pszDevSpace,
+                              pszSymbolicName,
+                              uiOffset,
+                              ui32Value);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpPMRWRW64(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT64 ui64Value,
+            PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "WRW64 :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              PMR_VALUE64_FMTSPEC " ",
+                              pszDevSpace,
+                              pszSymbolicName,
+                              uiOffset,
+                              ui64Value);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpPMRLDB(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_DEVMEM_SIZE_T uiSize,
+            const IMG_CHAR *pszFilename,
+            IMG_UINT32 uiFileOffset,
+            PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       PDumpOSLock();
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "LDB :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              IMG_DEVMEM_SIZE_FMTSPEC " "
+                              PDUMP_FILEOFFSET_FMTSPEC " %s\n",
+                              pszDevSpace,
+                              pszSymbolicName,
+                              uiOffset,
+                              uiSize,
+                              uiFileOffset,
+                              pszFilename);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpPMRSAB(const IMG_CHAR *pszDevSpace,
+                         const IMG_CHAR *pszSymbolicName,
+                         IMG_DEVMEM_OFFSET_T uiOffset,
+                         IMG_DEVMEM_SIZE_T uiSize,
+                         const IMG_CHAR *pszFileName,
+                         IMG_UINT32 uiFileOffset)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 uiPDumpFlags;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+    uiPDumpFlags = 0; //PDUMP_FLAGS_CONTINUOUS;
+       uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "SAB :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              IMG_DEVMEM_SIZE_FMTSPEC " "
+                              "0x%08X %s.bin\n",
+                              pszDevSpace,
+                              pszSymbolicName,
+                              uiOffset,
+                              uiSize,
+                              uiFileOffset,
+                              pszFileName);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpPMRPOL(const IMG_CHAR *pszMemspaceName,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT32 ui32Value,
+            IMG_UINT32 ui32Mask,
+            PDUMP_POLL_OPERATOR eOperator,
+            IMG_UINT32 uiCount,
+            IMG_UINT32 uiDelay,
+            PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+
+       uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "POL :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              "0x%08X 0x%08X %d %d %d\n",
+                              pszMemspaceName,
+                              pszSymbolicName,
+                              uiOffset,
+                              ui32Value,
+                              ui32Mask,
+                              eOperator,
+                              uiCount,
+                              uiDelay);
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpPMRCBP(const IMG_CHAR *pszMemspaceName,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiReadOffset,
+            IMG_DEVMEM_OFFSET_T uiWriteOffset,
+            IMG_DEVMEM_SIZE_T uiPacketSize,
+            IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVRSRV_ERROR eError;
+       PDUMP_FLAGS_T uiPDumpFlags = 0;
+
+       PDUMP_GET_SCRIPT_STRING()
+
+       uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+       eError = PDumpOSBufprintf(hScript,
+                              ui32MaxLen,
+                              "CBP :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " "
+                              IMG_DEVMEM_OFFSET_FMTSPEC " " IMG_DEVMEM_SIZE_FMTSPEC " " IMG_DEVMEM_SIZE_FMTSPEC "\n",
+                              pszMemspaceName,
+                              pszSymbolicName,
+                              uiReadOffset,
+                              uiWriteOffset,
+                              uiPacketSize,
+                              uiBufferSize);
+
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       PDumpOSLock();
+       PDumpWriteScript(hScript, uiPDumpFlags);
+       PDumpOSUnlock();
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PDumpWriteBuffer(IMG_UINT8 *pcBuffer,
+                 IMG_SIZE_T uiNumBytes,
+                 PDUMP_FLAGS_T uiPDumpFlags,
+                 IMG_CHAR *pszFilenameOut,
+                 IMG_SIZE_T uiFilenameBufSz,
+                 PDUMP_FILEOFFSET_T *puiOffsetOut)
+{
+       PVRSRV_ERROR eError;
+       PVR_UNREFERENCED_PARAMETER(uiFilenameBufSz);
+
+       if (!PDumpReady())
+       {
+               eError = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+        goto e0;
+       }
+
+    PVR_ASSERT(uiNumBytes > 0);
+
+       /* PRQA S 3415 1 */ /* side effects desired */
+       if (PDumpIsDumpSuspended())
+       {
+               return PVRSRV_OK;
+       }
+
+       PDumpOSLock();
+
+       eError = PDumpWriteParameter(pcBuffer, uiNumBytes, uiPDumpFlags, puiOffsetOut, pszFilenameOut);
+
+       PDumpOSUnlock();
+
+       PVR_LOGG_IF_ERROR(eError, "PDumpWriteParameter", e0);
+
+       return PVRSRV_OK;
+
+ e0:
+       /* Die on debug builds */
+       PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL IMG_VOID
+PDumpPMRMallocPMR(const PMR *psPMR,
+                  IMG_DEVMEM_SIZE_T uiSize,
+                  IMG_DEVMEM_ALIGN_T uiBlockSize,
+                  IMG_BOOL bForcePersistent,
+                  IMG_HANDLE *phPDumpAllocInfoPtr)
+{
+    PVRSRV_ERROR eError;
+    IMG_HANDLE hPDumpAllocInfo;
+    IMG_CHAR aszMemspaceName[30];
+    IMG_CHAR aszSymbolicName[30];
+    IMG_DEVMEM_OFFSET_T uiOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    uiOffset = 0;
+    eError = PMR_PDumpSymbolicAddr(psPMR,
+                                   uiOffset,
+                                   sizeof(aszMemspaceName),
+                                   &aszMemspaceName[0],
+                                   sizeof(aszSymbolicName),
+                                   &aszSymbolicName[0],
+                                   &uiOffset,
+                                  &uiNextSymName);
+    PVR_ASSERT(eError == PVRSRV_OK);
+    PVR_ASSERT(uiOffset == 0);
+    PVR_ASSERT((uiOffset + uiSize) <= uiNextSymName);
+
+       PDumpPMRMalloc(aszMemspaceName,
+                                  aszSymbolicName,
+                                  uiSize,
+                                  uiBlockSize,
+                                  bForcePersistent,
+                                  &hPDumpAllocInfo);
+
+       *phPDumpAllocInfoPtr = hPDumpAllocInfo;
+}
+#endif /* PDUMP */
diff --git a/drivers/gpu/rogue_m/services/server/common/physheap.c b/drivers/gpu/rogue_m/services/server/common/physheap.c
new file mode 100644 (file)
index 0000000..d80c9da
--- /dev/null
@@ -0,0 +1,275 @@
+/*************************************************************************/ /*!
+@File           physheap.c
+@Title          Physical heap management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Management functions for the physical heap(s). A heap contains
+                all the information required by services when using memory from
+                that heap (such as CPU <> Device physical address translation).
+                A system must register one heap but can have more then one which
+                is why a heap must register with a (system) unique ID.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+#include "img_types.h"
+#include "physheap.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "osfunc.h"
+
+struct _PHYS_HEAP_
+{
+       /*! ID of this physcial memory heap */
+       IMG_UINT32                                      ui32PhysHeapID;
+       /*! The type of this heap */
+       PHYS_HEAP_TYPE                  eType;
+
+       /*! Start address of the physcial memory heap (LMA only) */
+       IMG_CPU_PHYADDR                         sStartAddr;
+       /*! Size of the physcial memory heap (LMA only) */
+       IMG_UINT64                                      uiSize;
+
+       /*! PDump name of this physcial memory heap */
+       IMG_CHAR                                        *pszPDumpMemspaceName;
+       /*! Private data for the translate routines */
+       IMG_HANDLE                                      hPrivData;
+       /*! Function callbacks */
+       PHYS_HEAP_FUNCTIONS                     *psMemFuncs;
+
+
+       /*! Refcount */
+       IMG_UINT32                                      ui32RefCount;
+       /*! Pointer to next physcial heap */
+       struct _PHYS_HEAP_              *psNext;
+};
+
+PHYS_HEAP *g_psPhysHeapList;
+
+#if defined(REFCOUNT_DEBUG)
+#define PHYSHEAP_REFCOUNT_PRINT(fmt, ...)      \
+       PVRSRVDebugPrintf(PVR_DBG_WARNING,      \
+                         __FILE__,             \
+                         __LINE__,             \
+                         fmt,                  \
+                         __VA_ARGS__)
+#else
+#define PHYSHEAP_REFCOUNT_PRINT(fmt, ...)
+#endif
+
+
+PVRSRV_ERROR PhysHeapRegister(PHYS_HEAP_CONFIG *psConfig,
+                                                         PHYS_HEAP **ppsPhysHeap)
+{
+       PHYS_HEAP *psNew;
+       PHYS_HEAP *psTmp;
+
+       PVR_DPF_ENTERED;
+
+       if (psConfig->eType == PHYS_HEAP_TYPE_UNKNOWN)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Check this heap ID isn't already in use */
+       psTmp = g_psPhysHeapList;
+       while (psTmp)
+       {
+               if (psTmp->ui32PhysHeapID == psConfig->ui32PhysHeapID)
+               {
+                       return PVRSRV_ERROR_PHYSHEAP_ID_IN_USE;
+               }
+               psTmp = psTmp->psNext;
+       }
+
+       psNew = OSAllocMem(sizeof(PHYS_HEAP));
+       if (psNew == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psNew->ui32PhysHeapID = psConfig->ui32PhysHeapID;
+       psNew->eType = psConfig->eType;
+       psNew->sStartAddr = psConfig->sStartAddr;
+       psNew->uiSize = psConfig->uiSize;
+       psNew->psMemFuncs = psConfig->psMemFuncs;
+       psNew->hPrivData = psConfig->hPrivData;
+       psNew->ui32RefCount = 0;
+       psNew->pszPDumpMemspaceName = psConfig->pszPDumpMemspaceName;
+
+       psNew->psNext = g_psPhysHeapList;
+       g_psPhysHeapList = psNew;
+
+       *ppsPhysHeap = psNew;
+
+       PVR_DPF_RETURN_RC1(PVRSRV_OK, *ppsPhysHeap);
+}
+
+IMG_VOID PhysHeapUnregister(PHYS_HEAP *psPhysHeap)
+{
+       PVR_DPF_ENTERED1(psPhysHeap);
+
+       PVR_ASSERT(psPhysHeap->ui32RefCount == 0);
+
+       if (g_psPhysHeapList == psPhysHeap)
+       {
+               g_psPhysHeapList = psPhysHeap->psNext;
+       }
+       else
+       {
+               PHYS_HEAP *psTmp = g_psPhysHeapList;
+
+               while(psTmp->psNext != psPhysHeap)
+               {
+                       psTmp = psTmp->psNext;
+               }
+               psTmp->psNext = psPhysHeap->psNext;
+       }
+
+       OSFreeMem(psPhysHeap);
+
+       PVR_DPF_RETURN;
+}
+
+PVRSRV_ERROR PhysHeapAcquire(IMG_UINT32 ui32PhysHeapID,
+                                                        PHYS_HEAP **ppsPhysHeap)
+{
+       PHYS_HEAP *psTmp = g_psPhysHeapList;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_DPF_ENTERED1(ui32PhysHeapID);
+
+       while (psTmp)
+       {
+               if (psTmp->ui32PhysHeapID == ui32PhysHeapID)
+               {
+                       break;
+               }
+               psTmp = psTmp->psNext;
+       }
+       
+       if (psTmp == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_PHYSHEAP_ID_INVALID;
+       }
+       else
+       {
+               psTmp->ui32RefCount++;
+               PHYSHEAP_REFCOUNT_PRINT("%s: Heap %p, refcount = %d", __FUNCTION__, psTmp, psTmp->ui32RefCount);
+       }
+
+       *ppsPhysHeap = psTmp;
+       PVR_DPF_RETURN_RC1(eError, *ppsPhysHeap);
+}
+
+IMG_VOID PhysHeapRelease(PHYS_HEAP *psPhysHeap)
+{
+       PVR_DPF_ENTERED1(psPhysHeap);
+
+       psPhysHeap->ui32RefCount--;
+       PHYSHEAP_REFCOUNT_PRINT("%s: Heap %p, refcount = %d", __FUNCTION__, psPhysHeap, psPhysHeap->ui32RefCount);
+
+       PVR_DPF_RETURN;
+}
+
+PHYS_HEAP_TYPE PhysHeapGetType(PHYS_HEAP *psPhysHeap)
+{
+       return psPhysHeap->eType;
+}
+
+PVRSRV_ERROR PhysHeapGetAddress(PHYS_HEAP *psPhysHeap,
+                                                               IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA)
+       {
+               *psCpuPAddr = psPhysHeap->sStartAddr;
+               return PVRSRV_OK;
+       }
+
+       return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap,
+                                                          IMG_UINT64 *puiSize)
+{
+       if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA)
+       {
+               *puiSize = psPhysHeap->uiSize;
+               return PVRSRV_OK;
+       }
+
+       return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+IMG_VOID PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap,
+                                                                       IMG_UINT32 ui32NumOfAddr,
+                                                                       IMG_DEV_PHYADDR *psDevPAddr,
+                                                                       IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       psPhysHeap->psMemFuncs->pfnCpuPAddrToDevPAddr(psPhysHeap->hPrivData,
+                                                                                                ui32NumOfAddr,
+                                                                                                psDevPAddr,
+                                                                                                psCpuPAddr);
+}
+
+IMG_VOID PhysHeapDevPAddrToCpuPAddr(PHYS_HEAP *psPhysHeap,
+                                                                       IMG_UINT32 ui32NumOfAddr,
+                                                                       IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                       IMG_DEV_PHYADDR *psDevPAddr)
+{
+       psPhysHeap->psMemFuncs->pfnDevPAddrToCpuPAddr(psPhysHeap->hPrivData,
+                                                                                                ui32NumOfAddr,
+                                                                                                psCpuPAddr,
+                                                                                                psDevPAddr);
+}
+
+IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap)
+{
+       return psPhysHeap->pszPDumpMemspaceName;
+}
+
+PVRSRV_ERROR PhysHeapInit(IMG_VOID)
+{
+       g_psPhysHeapList = IMG_NULL;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PhysHeapDeinit(IMG_VOID)
+{
+       PVR_ASSERT(g_psPhysHeapList == IMG_NULL);
+
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/physmem.c b/drivers/gpu/rogue_m/services/server/common/physmem.c
new file mode 100644 (file)
index 0000000..61bbbe9
--- /dev/null
@@ -0,0 +1,130 @@
+/*************************************************************************/ /*!
+@File           physmem.c
+@Title          Physmem
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Common entry point for creation of RAM backed PMR's
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+#include "device.h"
+#include "physmem.h"
+#include "pvrsrv.h"
+
+#if defined(DEBUG)
+IMG_UINT32 gPMRAllocFail = 0;
+#endif /* defined(DEBUG) */
+
+PVRSRV_ERROR
+PhysmemNewRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                                               IMG_DEVMEM_SIZE_T uiSize,
+                                               PMR_SIZE_T uiChunkSize,
+                                               IMG_UINT32 ui32NumPhysChunks,
+                                               IMG_UINT32 ui32NumVirtChunks,
+                                               IMG_BOOL *pabMappingTable,
+                                               IMG_UINT32 uiLog2PageSize,
+                                               PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                               PMR **ppsPMRPtr)
+{
+       PVRSRV_DEVICE_PHYS_HEAP ePhysHeapIdx = (uiFlags & PVRSRV_MEMALLOCFLAG_CPU_LOCAL) ? 1: 0;
+       PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE pfnCheckMemAllocSize = \
+                                                                               psDevNode->psDevConfig->pfnCheckMemAllocSize;
+#if defined(DEBUG)
+       static IMG_UINT32 ui32AllocCount = 1;
+#endif /* defined(DEBUG) */
+       /********************************
+        * Sanity check the cache flags *
+        ********************************/
+       /* Check if we can honour cached cache-coherent allocations */
+       if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT) &&
+               (!PVRSRVSystemHasCacheSnooping()))
+       {
+               return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
+       }
+
+       /* Both or neither have to be cache-coherent */
+       if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) ^
+               (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT))
+       {
+               return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
+       }
+
+       if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT) ^
+               (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT))
+       {
+               return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
+       }
+
+       /* Apply memory budgeting policy */
+       if (pfnCheckMemAllocSize)
+       {
+               PVRSRV_ERROR eError = \
+                                               pfnCheckMemAllocSize(psDevNode, (IMG_UINT64)uiChunkSize*ui32NumPhysChunks);
+               if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+#if defined(DEBUG)
+       if (gPMRAllocFail > 0)
+       {
+               if (ui32AllocCount < gPMRAllocFail)
+               {
+                       ui32AllocCount++;
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s failed on %d allocation.",
+                                __func__, ui32AllocCount));
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+       }
+#endif /* defined(DEBUG) */
+
+       return psDevNode->pfnCreateRamBackedPMR[ePhysHeapIdx](psDevNode,
+                                                                                       uiSize,
+                                                                                       uiChunkSize,
+                                                                                       ui32NumPhysChunks,
+                                                                                       ui32NumVirtChunks,
+                                                                                       pabMappingTable,
+                                                                                       uiLog2PageSize,
+                                                                                       uiFlags,
+                                                                                       ppsPMRPtr);
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/physmem_lma.c b/drivers/gpu/rogue_m/services/server/common/physmem_lma.c
new file mode 100644 (file)
index 0000000..2e64a8e
--- /dev/null
@@ -0,0 +1,1104 @@
+/*************************************************************************/ /*!
+@File           physmem_lma.c
+@Title          Local card memory allocator
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management. This module is responsible for
+                implementing the function callbacks for local card memory.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pvrsrv.h"
+#include "physmem_lma.h"
+#include "pdump_physmem.h"
+#include "pdump_km.h"
+#include "pmr.h"
+#include "pmr_impl.h"
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "rgxutils.h"
+#endif
+
+typedef struct _PMR_LMALLOCARRAY_DATA_ {
+       PVRSRV_DEVICE_NODE *psDevNode;
+       IMG_UINT32 uiNumAllocs;
+       IMG_UINT32 uiLog2AllocSize;
+       IMG_UINT32 uiAllocSize;
+       IMG_DEV_PHYADDR *pasDevPAddr;
+
+       IMG_BOOL bZeroOnAlloc;
+       IMG_BOOL bPoisonOnAlloc;
+
+       /* Tells if allocation is physically backed */
+       IMG_BOOL bHasLMPages;
+       IMG_BOOL bOnDemand;
+
+       /*
+         for pdump...
+       */
+       IMG_BOOL bPDumpMalloced;
+       IMG_HANDLE hPDumpAllocInfo;
+
+       /*
+         record at alloc time whether poisoning will be required when the
+         PMR is freed.
+       */
+       IMG_BOOL bPoisonOnFree;
+} PMR_LMALLOCARRAY_DATA;
+
+static PVRSRV_ERROR _MapAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_DEV_PHYADDR *psDevPAddr,
+                                                               IMG_SIZE_T uiSize, IMG_VOID **pvPtr, PMR_FLAGS_T ulFlags)
+{
+       IMG_CPU_PHYADDR sCpuPAddr;
+
+       PhysHeapDevPAddrToCpuPAddr(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], 1, &sCpuPAddr, psDevPAddr);
+       *pvPtr = OSMapPhysToLin(sCpuPAddr,
+                                                       uiSize,
+                                                       ulFlags);
+
+       if (*pvPtr == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       else
+       {
+               return PVRSRV_OK;
+       }
+}
+
+static IMG_VOID _UnMapAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize, IMG_VOID *pvPtr)
+{
+       OSUnMapPhysToLin(pvPtr, uiSize, 0);
+}
+
+static PVRSRV_ERROR
+_PoisonAlloc(PVRSRV_DEVICE_NODE *psDevNode,
+                        IMG_DEV_PHYADDR *psDevPAddr,
+                        IMG_UINT32 uiAllocSize,
+                        const IMG_CHAR *pacPoisonData,
+                        IMG_SIZE_T uiPoisonSize)
+{
+       IMG_UINT32 uiSrcByteIndex;
+       IMG_UINT32 uiDestByteIndex;
+       IMG_VOID *pvKernLin = IMG_NULL;
+       IMG_CHAR *pcDest = IMG_NULL;
+
+       PVRSRV_ERROR eError;
+
+       eError = _MapAlloc(psDevNode, psDevPAddr, uiAllocSize, &pvKernLin, 0);
+       if (eError != PVRSRV_OK)
+       {
+               goto map_failed;
+       }
+       pcDest = pvKernLin;
+
+       uiSrcByteIndex = 0;
+       for(uiDestByteIndex=0; uiDestByteIndex<uiAllocSize; uiDestByteIndex++)
+       {
+               pcDest[uiDestByteIndex] = pacPoisonData[uiSrcByteIndex];
+               uiSrcByteIndex++;
+               if (uiSrcByteIndex == uiPoisonSize)
+               {
+                       uiSrcByteIndex = 0;
+               }
+       }
+
+       _UnMapAlloc(psDevNode, uiAllocSize, pvKernLin);
+       return PVRSRV_OK;
+
+map_failed:
+       PVR_DPF((PVR_DBG_ERROR, "Failed to poison allocation"));
+       return eError;
+}
+
+static PVRSRV_ERROR
+_ZeroAlloc(PVRSRV_DEVICE_NODE *psDevNode,
+                  IMG_DEV_PHYADDR *psDevPAddr,
+                  IMG_UINT32 uiAllocSize)
+{
+       IMG_VOID *pvKernLin = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       eError = _MapAlloc(psDevNode, psDevPAddr, uiAllocSize, &pvKernLin, 0);
+       if (eError != PVRSRV_OK)
+       {
+               goto map_failed;
+       }
+
+       OSMemSet(pvKernLin, 0, uiAllocSize);
+
+       _UnMapAlloc(psDevNode, uiAllocSize, pvKernLin);
+       return PVRSRV_OK;
+
+map_failed:
+       PVR_DPF((PVR_DBG_ERROR, "Failed to zero allocation"));
+       return eError;
+}
+
+static const IMG_CHAR _AllocPoison[] = "^PoIsOn";
+static const IMG_UINT32 _AllocPoisonSize = 7;
+static const IMG_CHAR _FreePoison[] = "<DEAD-BEEF>";
+static const IMG_UINT32 _FreePoisonSize = 11;
+
+static PVRSRV_ERROR
+_AllocLMPageArray(PVRSRV_DEVICE_NODE *psDevNode,
+                         PMR_SIZE_T uiSize,
+                         PMR_SIZE_T uiChunkSize,
+                         IMG_UINT32 ui32NumPhysChunks,
+                         IMG_UINT32 ui32NumVirtChunks,
+                         IMG_BOOL *pabMappingTable,
+                         IMG_UINT32 uiLog2PageSize,
+                         IMG_BOOL bZero,
+                         IMG_BOOL bPoisonOnAlloc,
+                         IMG_BOOL bPoisonOnFree,
+                         IMG_BOOL bContig,
+                         IMG_BOOL bOnDemand,
+                         PMR_LMALLOCARRAY_DATA **ppsPageArrayDataPtr
+                         )
+{
+       PMR_LMALLOCARRAY_DATA *psPageArrayData = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(!bZero || !bPoisonOnAlloc);
+
+       if (uiSize >= 0x1000000000ULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                                "physmem_lma.c: Do you really want 64GB of physical memory in one go?  This is likely a bug"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto errorOnParam;
+       }
+
+       PVR_ASSERT(OSGetPageShift() <= uiLog2PageSize);
+
+       if ((uiSize & ((1ULL << uiLog2PageSize) - 1)) != 0)
+       {
+               eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+               goto errorOnParam;
+       }
+
+       psPageArrayData = OSAllocMem(sizeof(PMR_LMALLOCARRAY_DATA));
+       if (psPageArrayData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto errorOnAllocArray;
+       }
+       OSMemSet(psPageArrayData, 0, sizeof(PMR_LMALLOCARRAY_DATA));
+
+       if (bContig)
+       {
+               /*
+                       Some allocations require kernel mappings in which case in order
+                       to be virtually contiguous we also have to be physically contiguous.
+               */
+               psPageArrayData->uiNumAllocs = 1;
+               psPageArrayData->uiAllocSize = TRUNCATE_64BITS_TO_32BITS(uiSize);
+               psPageArrayData->uiLog2AllocSize = uiLog2PageSize;
+       }
+       else
+       {
+               IMG_UINT32 uiNumPages;
+
+               /* Use of cast below is justified by the assertion that follows to
+               prove that no significant bits have been truncated */
+               uiNumPages = (IMG_UINT32)(((uiSize-1)>>uiLog2PageSize) + 1);
+               PVR_ASSERT(((PMR_SIZE_T)uiNumPages << uiLog2PageSize) == uiSize);
+
+               psPageArrayData->uiNumAllocs = uiNumPages;
+               psPageArrayData->uiAllocSize = 1 << uiLog2PageSize;
+               psPageArrayData->uiLog2AllocSize = uiLog2PageSize;
+       }
+       psPageArrayData->psDevNode = psDevNode;
+       psPageArrayData->pasDevPAddr = OSAllocMem(sizeof(IMG_DEV_PHYADDR)*
+                                                                                               psPageArrayData->uiNumAllocs);
+       if (psPageArrayData->pasDevPAddr == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto errorOnAllocAddr;
+       }
+       OSMemSet(psPageArrayData->pasDevPAddr, 0, sizeof(IMG_DEV_PHYADDR)*
+                                                                                               psPageArrayData->uiNumAllocs);
+
+       /* N.B.  We have a window of opportunity where a failure in
+          createPMR the finalize function can be called before the PMR
+          MALLOC and thus the hPDumpAllocInfo won't be set.  So we have
+          to conditionally call the PDumpFree function. */
+       psPageArrayData->bPDumpMalloced = IMG_FALSE;
+
+       psPageArrayData->bZeroOnAlloc = bZero;
+       psPageArrayData->bPoisonOnAlloc = bPoisonOnAlloc;
+       psPageArrayData->bPoisonOnFree = bPoisonOnFree;
+       psPageArrayData->bHasLMPages = IMG_FALSE;
+       psPageArrayData->bOnDemand = bOnDemand;
+
+       *ppsPageArrayDataPtr = psPageArrayData;
+
+       return PVRSRV_OK;
+
+       /*
+         error exit paths follow:
+       */
+
+errorOnAllocAddr:
+       OSFreeMem(psPageArrayData);
+
+errorOnAllocArray:
+errorOnParam:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+static PVRSRV_ERROR
+_AllocLMPages(PMR_LMALLOCARRAY_DATA *psPageArrayDataPtr)
+{
+       IMG_UINT32 uiAllocSize = psPageArrayDataPtr->uiAllocSize;
+       IMG_UINT32 uiLog2AllocSize = psPageArrayDataPtr->uiLog2AllocSize;
+       PVRSRV_DEVICE_NODE *psDevNode = psPageArrayDataPtr->psDevNode;
+       IMG_BOOL bPoisonOnAlloc =  psPageArrayDataPtr->bPoisonOnAlloc;
+       IMG_BOOL bZeroOnAlloc =  psPageArrayDataPtr->bZeroOnAlloc;
+       PVRSRV_ERROR eError;
+       IMG_BOOL bAllocResult;
+       RA_BASE_T uiCardAddr;
+       RA_LENGTH_T uiActualSize;
+       IMG_UINT32 i;
+       RA_ARENA *pArena=psDevNode->psLocalDevMemArena;
+
+       PVR_ASSERT(!psPageArrayDataPtr->bHasLMPages);
+
+       for(i=0;i<psPageArrayDataPtr->uiNumAllocs;i++)
+       {
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+               IMG_UINT32  ui32OSid=0, ui32OSidReg=0;
+               IMG_PID     pId;
+
+               pId=OSGetCurrentProcessID();
+               RetrieveOSidsfromPidList(pId, &ui32OSid, &ui32OSidReg);
+
+               pArena=psDevNode->psOSidSubArena[ui32OSid];
+               PVR_DPF((PVR_DBG_MESSAGE,"(GPU Virtualization Validation): Giving from OS slot %d",ui32OSid));
+}
+#endif
+
+               bAllocResult = RA_Alloc(pArena,
+                                                               uiAllocSize,
+                                                               0,                                      /* No flags */
+                                                               1ULL << uiLog2AllocSize,
+                                                               &uiCardAddr,
+                                                               &uiActualSize,
+                                                               IMG_NULL);                      /* No private handle */
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+               PVR_DPF((PVR_DBG_MESSAGE,"(GPU Virtualization Validation): Address: %llu \n",uiCardAddr));
+}
+#endif
+
+               if (!bAllocResult)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto errorOnRAAlloc;
+               }
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+               /* Allocation is done a page at a time */
+               PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, uiActualSize);
+#else
+               {
+                       IMG_CPU_PHYADDR sLocalCpuPAddr;
+
+                       sLocalCpuPAddr.uiAddr = (IMG_UINT64)uiCardAddr;
+                       PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES,
+                                                                        IMG_NULL,
+                                                                        sLocalCpuPAddr,
+                                                                        uiActualSize,
+                                                                        IMG_NULL);
+               }
+#endif
+#endif
+
+               psPageArrayDataPtr->pasDevPAddr[i].uiAddr = uiCardAddr;
+
+               if (bPoisonOnAlloc)
+               {
+                       eError = _PoisonAlloc(psDevNode,
+                                                                 &psPageArrayDataPtr->pasDevPAddr[i],
+                                                                 uiAllocSize,
+                                                                 _AllocPoison,
+                                                                 _AllocPoisonSize);
+                       if (eError !=PVRSRV_OK)
+                       {
+                               goto errorOnPoison;
+                       }
+               }
+
+               if (bZeroOnAlloc)
+               {
+                       eError = _ZeroAlloc(psDevNode,
+                                                               &psPageArrayDataPtr->pasDevPAddr[i],
+                                                               uiAllocSize);
+                       if (eError !=PVRSRV_OK)
+                       {
+                               goto errorOnZero;
+                       }
+               }
+       }
+
+       psPageArrayDataPtr->bHasLMPages = IMG_TRUE;
+
+       return PVRSRV_OK;
+
+       /*
+         error exit paths follow:
+       */
+errorOnZero:
+errorOnPoison:
+errorOnRAAlloc:
+       while (i)
+       {
+               i--;
+               RA_Free(psDevNode->psLocalDevMemArena,
+                               psPageArrayDataPtr->pasDevPAddr[i].uiAddr);
+       }
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+static PVRSRV_ERROR
+_FreeLMPageArray(PMR_LMALLOCARRAY_DATA *psPageArrayData)
+{
+       OSFreeMem(psPageArrayData->pasDevPAddr);
+
+       PVR_DPF((PVR_DBG_MESSAGE, "physmem_lma.c: freed local memory array structure for PMR @0x%p", psPageArrayData));
+
+       OSFreeMem(psPageArrayData);
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_FreeLMPages(PMR_LMALLOCARRAY_DATA *psPageArrayData)
+{
+       IMG_UINT32 uiAllocSize;
+       IMG_UINT32 i;
+
+       PVR_ASSERT(psPageArrayData->bHasLMPages);
+
+       uiAllocSize = psPageArrayData->uiAllocSize;
+
+       for (i = 0;i < psPageArrayData->uiNumAllocs;i++)
+       {
+               if (psPageArrayData->bPoisonOnFree)
+               {
+                       _PoisonAlloc(psPageArrayData->psDevNode,
+                                                &psPageArrayData->pasDevPAddr[i],
+                                                uiAllocSize,
+                                                _FreePoison,
+                                                _FreePoisonSize);
+               }
+               RA_Free(psPageArrayData->psDevNode->psLocalDevMemArena,
+                               psPageArrayData->pasDevPAddr[i].uiAddr);
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+               /* Allocation is done a page at a time */
+               PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, uiAllocSize);
+#else
+        {
+                       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES, psPageArrayData->pasDevPAddr[i].uiAddr);
+        }
+#endif
+#endif
+       }
+
+       psPageArrayData->bHasLMPages = IMG_FALSE;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "physmem_lma.c: freed local memory for PMR @0x%p", psPageArrayData));
+
+       return PVRSRV_OK;
+}
+
+/*
+ *
+ * Implementation of callback functions
+ *
+ */
+
+/* destructor func is called after last reference disappears, but
+   before PMR itself is freed. */
+static PVRSRV_ERROR
+PMRFinalizeLocalMem(PMR_IMPL_PRIVDATA pvPriv
+                                )
+{
+       PVRSRV_ERROR eError;
+       PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = IMG_NULL;
+
+       psLMAllocArrayData = pvPriv;
+
+       /* Conditionally do the PDump free, because if CreatePMR failed we
+          won't have done the PDump MALLOC.  */
+       if (psLMAllocArrayData->bPDumpMalloced)
+       {
+               PDumpPMRFree(psLMAllocArrayData->hPDumpAllocInfo);
+       }
+
+       /*  We can't free pages until now. */
+       if (psLMAllocArrayData->bHasLMPages)
+       {
+               eError = _FreeLMPages(psLMAllocArrayData);
+               PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */
+       }
+
+       eError = _FreeLMPageArray(psLMAllocArrayData);
+       PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */
+
+       return PVRSRV_OK;
+}
+
+/* callback function for locking the system physical page addresses.
+   As we are LMA there is nothing to do as we control physical memory. */
+static PVRSRV_ERROR
+PMRLockSysPhysAddressesLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                                        IMG_UINT32 uiLog2DevPageSize)
+{
+
+    PVRSRV_ERROR eError;
+    PMR_LMALLOCARRAY_DATA *psLMAllocArrayData;
+
+    psLMAllocArrayData = pvPriv;
+
+    if (psLMAllocArrayData->bOnDemand)
+    {
+               /* Allocate Memory for deferred allocation */
+       eError = _AllocLMPages(psLMAllocArrayData);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+    }
+
+       PVR_UNREFERENCED_PARAMETER(uiLog2DevPageSize);
+
+       return PVRSRV_OK;
+
+}
+
+static PVRSRV_ERROR
+PMRUnlockSysPhysAddressesLocalMem(PMR_IMPL_PRIVDATA pvPriv
+                                                          )
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    PMR_LMALLOCARRAY_DATA *psLMAllocArrayData;
+
+    psLMAllocArrayData = pvPriv;
+
+       if (psLMAllocArrayData->bOnDemand)
+    {
+               /* Free Memory for deferred allocation */
+       eError = _FreeLMPages(psLMAllocArrayData);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+    }
+
+       PVR_ASSERT(eError == PVRSRV_OK);
+       return eError;
+}
+
+/* N.B.  It is assumed that PMRLockSysPhysAddressesLocalMem() is called _before_ this function! */
+static PVRSRV_ERROR
+PMRSysPhysAddrLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                          IMG_UINT32 ui32NumOfPages,
+                                          IMG_DEVMEM_OFFSET_T *puiOffset,
+                                          IMG_BOOL *pbValid,
+                                          IMG_DEV_PHYADDR *psDevPAddr)
+{
+       IMG_UINT32 idx;
+       IMG_UINT32 uiLog2AllocSize;
+       IMG_UINT32 uiNumAllocs;
+       IMG_UINT64 uiAllocIndex;
+       IMG_DEVMEM_OFFSET_T uiInAllocOffset;
+       PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = pvPriv;
+
+       uiNumAllocs = psLMAllocArrayData->uiNumAllocs;
+       if (uiNumAllocs > 1)
+       {
+               PVR_ASSERT(psLMAllocArrayData->uiLog2AllocSize != 0);
+               uiLog2AllocSize = psLMAllocArrayData->uiLog2AllocSize;
+
+               for (idx=0; idx < ui32NumOfPages; idx++)
+               {
+                       if (pbValid[idx])
+                       {
+                               uiAllocIndex = puiOffset[idx] >> uiLog2AllocSize;
+                               uiInAllocOffset = puiOffset[idx] - (uiAllocIndex << uiLog2AllocSize);
+
+                               PVR_ASSERT(uiAllocIndex < uiNumAllocs);
+                               PVR_ASSERT(uiInAllocOffset < (1ULL << uiLog2AllocSize));
+
+                               psDevPAddr[idx].uiAddr = psLMAllocArrayData->pasDevPAddr[uiAllocIndex].uiAddr + uiInAllocOffset;
+                       }
+               }
+       }
+       else
+       {
+               for (idx=0; idx < ui32NumOfPages; idx++)
+               {
+                       if (pbValid[idx])
+                       {
+                               psDevPAddr[idx].uiAddr = psLMAllocArrayData->pasDevPAddr[0].uiAddr + puiOffset[idx];
+                       }
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRAcquireKernelMappingDataLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                                                IMG_SIZE_T uiOffset,
+                                                                IMG_SIZE_T uiSize,
+                                                                IMG_VOID **ppvKernelAddressOut,
+                                                                IMG_HANDLE *phHandleOut,
+                                                                PMR_FLAGS_T ulFlags)
+{
+       PVRSRV_ERROR eError;
+       PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = IMG_NULL;
+       IMG_VOID *pvKernLinAddr = IMG_NULL;
+       IMG_UINT32 ui32PageIndex = 0;
+
+       PVR_UNREFERENCED_PARAMETER(ulFlags);
+
+       psLMAllocArrayData = pvPriv;
+
+       /* Check that we can map this in contiguously */
+       if (psLMAllocArrayData->uiNumAllocs != 1)
+       {
+               IMG_SIZE_T uiStart = uiOffset;
+               IMG_SIZE_T uiEnd = uiOffset + uiSize - 1;
+               IMG_SIZE_T uiPageMask = ~((1 << psLMAllocArrayData->uiLog2AllocSize) - 1);
+
+               /* We can still map if only one page is required */
+               if ((uiStart & uiPageMask) != (uiEnd & uiPageMask))
+               {
+                       eError = PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
+                       goto e0;
+               }
+
+               /* Locate the desired physical page to map in */
+               ui32PageIndex = uiOffset >> psLMAllocArrayData->uiLog2AllocSize;
+       }
+
+       PVR_ASSERT(ui32PageIndex < psLMAllocArrayData->uiNumAllocs);
+
+       eError = _MapAlloc(psLMAllocArrayData->psDevNode,
+                                               &psLMAllocArrayData->pasDevPAddr[ui32PageIndex],
+                                               psLMAllocArrayData->uiAllocSize,
+                                               &pvKernLinAddr, 
+                                               ulFlags);
+
+       *ppvKernelAddressOut = ((IMG_CHAR *) pvKernLinAddr) + (uiOffset & ((1U << psLMAllocArrayData->uiLog2AllocSize) - 1));
+       *phHandleOut = pvKernLinAddr;
+
+       return eError;
+
+       /*
+         error exit paths follow
+       */
+
+ e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static IMG_VOID PMRReleaseKernelMappingDataLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                                                                                IMG_HANDLE hHandle)
+{
+       PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = IMG_NULL;
+       IMG_VOID *pvKernLinAddr = IMG_NULL;
+
+       psLMAllocArrayData = (PMR_LMALLOCARRAY_DATA *) pvPriv;
+       pvKernLinAddr = (IMG_VOID *) hHandle;
+
+       _UnMapAlloc(psLMAllocArrayData->psDevNode,
+                               psLMAllocArrayData->uiAllocSize, pvKernLinAddr);
+}
+
+
+static PVRSRV_ERROR
+CopyBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                 IMG_UINT8 *pcBuffer,
+                                 IMG_SIZE_T uiBufSz,
+                                 IMG_SIZE_T *puiNumBytes,
+                                 IMG_VOID (*pfnCopyBytes)(IMG_UINT8 *pcBuffer,
+                                                                                  IMG_UINT8 *pcPMR,
+                                                                                  IMG_SIZE_T uiSize))
+{
+       PMR_LMALLOCARRAY_DATA *psLMAllocArrayData = IMG_NULL;
+       IMG_SIZE_T uiBytesCopied;
+       IMG_SIZE_T uiBytesToCopy;
+       IMG_SIZE_T uiBytesCopyableFromAlloc;
+       IMG_VOID *pvMapping = IMG_NULL;
+       IMG_UINT8 *pcKernelPointer = IMG_NULL;
+       IMG_SIZE_T uiBufferOffset;
+       IMG_UINT64 uiAllocIndex;
+       IMG_DEVMEM_OFFSET_T uiInAllocOffset;
+       PVRSRV_ERROR eError;
+
+       psLMAllocArrayData = pvPriv;
+
+       uiBytesCopied = 0;
+       uiBytesToCopy = uiBufSz;
+       uiBufferOffset = 0;
+
+       if (psLMAllocArrayData->uiNumAllocs > 1)
+       {
+               while (uiBytesToCopy > 0)
+               {
+                       /* we have to map one alloc in at a time */
+                       PVR_ASSERT(psLMAllocArrayData->uiLog2AllocSize != 0);
+                       uiAllocIndex = uiOffset >> psLMAllocArrayData->uiLog2AllocSize;
+                       uiInAllocOffset = uiOffset - (uiAllocIndex << psLMAllocArrayData->uiLog2AllocSize);
+                       uiBytesCopyableFromAlloc = uiBytesToCopy;
+                       if (uiBytesCopyableFromAlloc + uiInAllocOffset > (1ULL << psLMAllocArrayData->uiLog2AllocSize))
+                       {
+                               uiBytesCopyableFromAlloc = TRUNCATE_64BITS_TO_SIZE_T((1ULL << psLMAllocArrayData->uiLog2AllocSize)-uiInAllocOffset);
+                       }
+
+                       PVR_ASSERT(uiBytesCopyableFromAlloc != 0);
+                       PVR_ASSERT(uiAllocIndex < psLMAllocArrayData->uiNumAllocs);
+                       PVR_ASSERT(uiInAllocOffset < (1ULL << psLMAllocArrayData->uiLog2AllocSize));
+
+                       eError = _MapAlloc(psLMAllocArrayData->psDevNode,
+                                                               &psLMAllocArrayData->pasDevPAddr[uiAllocIndex],
+                                                               psLMAllocArrayData->uiAllocSize,
+                                                               &pvMapping, 0);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto e0;
+                       }
+                       pcKernelPointer = pvMapping;
+                       pfnCopyBytes(&pcBuffer[uiBufferOffset], &pcKernelPointer[uiInAllocOffset], uiBytesCopyableFromAlloc);
+                       _UnMapAlloc(psLMAllocArrayData->psDevNode, psLMAllocArrayData->uiAllocSize, pvMapping);
+                       uiBufferOffset += uiBytesCopyableFromAlloc;
+                       uiBytesToCopy -= uiBytesCopyableFromAlloc;
+                       uiOffset += uiBytesCopyableFromAlloc;
+                       uiBytesCopied += uiBytesCopyableFromAlloc;
+               }
+       }
+       else
+       {
+                       PVR_ASSERT((uiOffset + uiBufSz) <= psLMAllocArrayData->uiAllocSize);
+                       PVR_ASSERT(psLMAllocArrayData->uiAllocSize != 0);
+                       eError = _MapAlloc(psLMAllocArrayData->psDevNode,
+                                                               &psLMAllocArrayData->pasDevPAddr[0],
+                                                               psLMAllocArrayData->uiAllocSize,
+                                                               &pvMapping, 0);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto e0;
+                       }
+                       pcKernelPointer = pvMapping;
+                       pfnCopyBytes(pcBuffer, &pcKernelPointer[uiOffset], uiBufSz);
+                       _UnMapAlloc(psLMAllocArrayData->psDevNode, psLMAllocArrayData->uiAllocSize, pvMapping);
+                       uiBytesCopied = uiBufSz;
+       }
+       *puiNumBytes = uiBytesCopied;
+       return PVRSRV_OK;
+e0:
+       *puiNumBytes = uiBytesCopied;
+       return eError;
+}
+
+static IMG_VOID ReadLocalMem(IMG_UINT8 *pcBuffer,
+                                                        IMG_UINT8 *pcPMR,
+                                                        IMG_SIZE_T uiSize)
+{
+       OSMemCopy(pcBuffer, pcPMR, uiSize);
+}
+
+static PVRSRV_ERROR
+PMRReadBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                 IMG_UINT8 *pcBuffer,
+                                 IMG_SIZE_T uiBufSz,
+                                 IMG_SIZE_T *puiNumBytes)
+{
+       return CopyBytesLocalMem(pvPriv,
+                                                        uiOffset,
+                                                        pcBuffer,
+                                                        uiBufSz,
+                                                        puiNumBytes,
+                                                        ReadLocalMem);
+}
+
+static IMG_VOID WriteLocalMem(IMG_UINT8 *pcBuffer,
+                                                         IMG_UINT8 *pcPMR,
+                                                         IMG_SIZE_T uiSize)
+{
+       OSMemCopy(pcPMR, pcBuffer, uiSize);
+}
+
+static PVRSRV_ERROR
+PMRWriteBytesLocalMem(PMR_IMPL_PRIVDATA pvPriv,
+                                         IMG_DEVMEM_OFFSET_T uiOffset,
+                                         IMG_UINT8 *pcBuffer,
+                                         IMG_SIZE_T uiBufSz,
+                                         IMG_SIZE_T *puiNumBytes)
+{
+       return CopyBytesLocalMem(pvPriv,
+                                                        uiOffset,
+                                                        pcBuffer,
+                                                        uiBufSz,
+                                                        puiNumBytes,
+                                                        WriteLocalMem);
+}
+
+static PMR_IMPL_FUNCTAB _sPMRLMAFuncTab = {
+       /* pfnLockPhysAddresses */
+       &PMRLockSysPhysAddressesLocalMem,
+       /* pfnUnlockPhysAddresses */
+       &PMRUnlockSysPhysAddressesLocalMem,
+       /* pfnDevPhysAddr */
+       &PMRSysPhysAddrLocalMem,
+       /* pfnPDumpSymbolicAddr */
+       IMG_NULL,
+       /* pfnAcquireKernelMappingData */
+       &PMRAcquireKernelMappingDataLocalMem,
+       /* pfnReleaseKernelMappingData */
+       &PMRReleaseKernelMappingDataLocalMem,
+       /* pfnReadBytes */
+       &PMRReadBytesLocalMem,
+       /* pfnWriteBytes */
+       &PMRWriteBytesLocalMem,
+       /* pfnFinalize */
+       &PMRFinalizeLocalMem
+};
+
+PVRSRV_ERROR
+PhysmemNewLocalRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                                                       IMG_DEVMEM_SIZE_T uiSize,
+                                                       IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                       IMG_UINT32 ui32NumPhysChunks,
+                                                       IMG_UINT32 ui32NumVirtChunks,
+                                                       IMG_BOOL *pabMappingTable,
+                                                       IMG_UINT32 uiLog2PageSize,
+                                                       PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                       PMR **ppsPMRPtr)
+{
+       PVRSRV_ERROR eError;
+       PVRSRV_ERROR eError2;
+       PMR *psPMR = IMG_NULL;
+       PMR_LMALLOCARRAY_DATA *psPrivData = IMG_NULL;
+       IMG_HANDLE hPDumpAllocInfo = IMG_NULL;
+       PMR_FLAGS_T uiPMRFlags;
+       IMG_BOOL bZero;
+       IMG_BOOL bPoisonOnAlloc;
+       IMG_BOOL bPoisonOnFree;
+       IMG_BOOL bOnDemand = ((uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) > 0);
+       IMG_BOOL bContig;
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+       {
+               bZero = IMG_TRUE;
+       }
+       else
+       {
+               bZero = IMG_FALSE;
+       }
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)
+       {
+               bPoisonOnAlloc = IMG_TRUE;
+       }
+       else
+       {
+               bPoisonOnAlloc = IMG_FALSE;
+       }
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE)
+       {
+               bPoisonOnFree = IMG_TRUE;
+       }
+       else
+       {
+               bPoisonOnFree = IMG_FALSE;
+       }
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE)
+       {
+               bContig = IMG_TRUE;
+       }
+       else
+       {
+               bContig = IMG_FALSE;
+       }
+
+       if ((uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
+               (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+       {
+               /* Zero on Alloc and Poison on Alloc are mutually exclusive */
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto errorOnParam;
+       }
+
+       /* Silently round up alignment/pagesize if request was less that
+          PAGE_SHIFT, because it would never be harmful for memory to be
+          _more_ contiguous that was desired */
+
+       uiLog2PageSize = OSGetPageShift() > uiLog2PageSize
+               ? OSGetPageShift()
+               : uiLog2PageSize;
+
+       /* Create Array structure that holds the physical pages */
+       eError = _AllocLMPageArray(psDevNode,
+                                                  uiChunkSize * ui32NumPhysChunks,
+                                                  uiChunkSize,
+                           ui32NumPhysChunks,
+                           ui32NumVirtChunks,
+                           pabMappingTable,
+                                                  uiLog2PageSize,
+                                                  bZero,
+                                                  bPoisonOnAlloc,
+                                                  bPoisonOnFree,
+                                                  bContig,
+                                                  bOnDemand,
+                                                  &psPrivData);
+       if (eError != PVRSRV_OK)
+       {
+               goto errorOnAllocPageArray;
+       }
+
+
+       if (!bOnDemand)
+       {
+               /* Allocate the physical pages */
+               eError = _AllocLMPages(psPrivData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto errorOnAllocPages;
+               }
+       }
+
+       /* In this instance, we simply pass flags straight through.
+
+          Generically, uiFlags can include things that control the PMR
+          factory, but we don't need any such thing (at the time of
+          writing!), and our caller specifies all PMR flags so we don't
+          need to meddle with what was given to us.
+       */
+       uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
+       /* check no significant bits were lost in cast due to different
+          bit widths for flags */
+       PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
+
+    if (bOnDemand)
+    {
+       PDUMPCOMMENT("Deferred Allocation PMR (LMA)");
+    }
+       eError = PMRCreatePMR(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL],
+                                                 uiSize,
+                          uiChunkSize,
+                          ui32NumPhysChunks,
+                          ui32NumVirtChunks,
+                          pabMappingTable,
+                                                 uiLog2PageSize,
+                                                 uiPMRFlags,
+                                                 "PMRLMA",
+                                                 &_sPMRLMAFuncTab,
+                                                 psPrivData,
+                                                 &psPMR,
+                                                 &hPDumpAllocInfo,
+                                                 IMG_FALSE);
+       if (eError != PVRSRV_OK)
+       {
+               goto errorOnCreate;
+       }
+
+       psPrivData->hPDumpAllocInfo = hPDumpAllocInfo;
+       psPrivData->bPDumpMalloced = IMG_TRUE;
+
+       *ppsPMRPtr = psPMR;
+       return PVRSRV_OK;
+
+errorOnCreate:
+       if(!bOnDemand)
+       {
+               eError2 = _FreeLMPages(psPrivData);
+               PVR_ASSERT(eError2 == PVRSRV_OK);
+       }
+
+errorOnAllocPages:
+       eError2 = _FreeLMPageArray(psPrivData);
+       PVR_ASSERT(eError2 == PVRSRV_OK);
+
+errorOnAllocPageArray:
+errorOnParam:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+
+struct PidOSidCouplingList
+{
+       IMG_PID     pId;
+       IMG_UINT32  ui32OSid;
+       IMG_UINT32      ui32OSidReg;
+
+       struct PidOSidCouplingList *psNext;
+};
+typedef struct PidOSidCouplingList PidOSidCouplingList;
+
+static PidOSidCouplingList *psPidOSidHead=NULL;
+static PidOSidCouplingList *psPidOSidTail=NULL;
+
+IMG_VOID InsertPidOSidsCoupling(IMG_PID pId, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg)
+{
+       PidOSidCouplingList *psTmp;
+
+       PVR_DPF((PVR_DBG_MESSAGE,"(GPU Virtualization Validation): Inserting (PID/ OSid/ OSidReg) (%d/ %d/ %d) into list",pId,ui32OSid, ui32OSidReg));
+
+       psTmp=OSAllocMem(sizeof(PidOSidCouplingList));
+
+       if (psTmp==IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"(GPU Virtualization Validation): Memory allocation failed. No list insertion => program will execute normally.\n"));
+               return ;
+       }
+
+       psTmp->pId=pId;
+       psTmp->ui32OSid=ui32OSid;
+       psTmp->ui32OSidReg=ui32OSidReg;
+
+       psTmp->psNext=NULL;
+       if (psPidOSidHead==NULL)
+       {
+               psPidOSidHead=psTmp;
+               psPidOSidTail=psTmp;
+       }
+       else
+       {
+               psPidOSidTail->psNext=psTmp;
+               psPidOSidTail=psTmp;
+       }
+
+       return ;
+}
+
+IMG_VOID RetrieveOSidsfromPidList(IMG_PID pId, IMG_UINT32 *pui32OSid, IMG_UINT32 * pui32OSidReg)
+{
+       PidOSidCouplingList *psTmp;
+
+       for (psTmp=psPidOSidHead;psTmp!=NULL;psTmp=psTmp->psNext)
+       {
+               if (psTmp->pId==pId)
+               {
+                       (*pui32OSid) = psTmp->ui32OSid;
+                       (*pui32OSidReg) = psTmp->ui32OSidReg;
+
+                       return ;
+               }
+       }
+
+       (*pui32OSid)=0;
+       (*pui32OSidReg)=0;
+       return ;
+}
+
+IMG_VOID    RemovePidOSidCoupling(IMG_PID pId)
+{
+       PidOSidCouplingList *psTmp, *psPrev=NULL;
+
+       for (psTmp=psPidOSidHead; psTmp!=NULL; psTmp=psTmp->psNext)
+       {
+               if (psTmp->pId==pId) break;
+               psPrev=psTmp;
+       }
+
+       if (psTmp==NULL)
+       {
+               return ;
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE,"(GPU Virtualization Validation): Deleting Pairing %d / (%d - %d) from list",psTmp->pId, psTmp->ui32OSid, psTmp->ui32OSidReg));
+
+       if (psTmp==psPidOSidHead)
+       {
+               if (psPidOSidHead->psNext==NULL)
+               {
+                       psPidOSidHead=NULL;
+                       psPidOSidTail=NULL;
+                       OSFreeMem(psTmp);
+
+                       return ;
+               }
+
+               psPidOSidHead=psPidOSidHead->psNext;
+               OSFreeMem(psTmp);
+               return ;
+       }
+
+       if (psPrev==NULL) return ;
+
+       psPrev->psNext=psTmp->psNext;
+       if (psTmp==psPidOSidTail)
+       {
+               psPidOSidTail=psPrev;
+       }
+
+       OSFreeMem(psTmp);
+
+       return ;
+}
+
+#endif
+
diff --git a/drivers/gpu/rogue_m/services/server/common/pmr.c b/drivers/gpu/rogue_m/services/server/common/pmr.c
new file mode 100644 (file)
index 0000000..ed310b2
--- /dev/null
@@ -0,0 +1,2786 @@
+/*************************************************************************/ /*!
+@File
+@Title          Physmem (PMR) abstraction
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management.  This module is responsible for
+                the "PMR" abstraction.  A PMR (Physical Memory Resource)
+                represents some unit of physical memory which is
+                allocated/freed/mapped/unmapped as an indivisible unit
+                (higher software levels provide an abstraction above that
+                to deal with dividing this down into smaller manageable units).
+                Importantly, this module knows nothing of virtual memory, or
+                of MMUs etc., with one excuseable exception.  We have the
+                concept of a "page size", which really means nothing in
+                physical memory, but represents a "contiguity quantum" such
+                that the higher level modules which map this memory are able
+                to verify that it matches the needs of the page size for the
+                virtual realm into which it is being mapped.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "pdump.h"
+
+#include "osfunc.h"
+#include "pdump_km.h"
+#include "pdump_physmem.h"
+#include "pmr_impl.h"
+#include "pvrsrv.h"
+
+#include "allocmem.h"
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC) && defined(LINUX)
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+#endif
+#include "lock.h"
+
+#if defined(SUPPORT_SECURE_EXPORT)
+#include "secure_export.h"
+#include "ossecure_export.h"
+#endif
+
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif 
+
+/* ourselves */
+#include "pmr.h"
+
+/* A "context" for the physical memory block resource allocator.
+
+   Context is probably the wrong word.
+
+   There is almost certainly only one of these, ever, in the system.
+   But, let's keep the notion of a context anyway, "just-in-case".
+*/
+struct _PMR_CTX_
+{
+    /* For debugging, and PDump, etc., let's issue a forever
+       incrementing serial number to each allocation. */
+    IMG_UINT64 uiNextSerialNum;
+
+    /* For security, we only allow a PMR to be mapped if the caller
+       knows its key.  We can pseudo-randomly generate keys */
+    IMG_UINT64 uiNextKey;
+
+    /* For debugging only, I guess:  Number of live PMRs */
+    IMG_UINT32 uiNumLivePMRs;
+
+       /* Lock for this structure */
+       POS_LOCK hLock;
+
+    /* In order to seed the uiNextKey, we enforce initialisation at
+       driver load time.  Also, we can debug check at driver unload
+       that the PMR count is zero. */
+  IMG_BOOL bModuleInitialised;
+} _gsSingletonPMRContext = { 1, 0, 0, IMG_NULL, IMG_FALSE };
+
+
+typedef struct _PMR_MAPPING_TABLE_
+{
+       PMR_SIZE_T      uiChunkSize;                    /*!< Size of a "chunk" */
+       IMG_UINT32      ui32NumPhysChunks;              /*!< Number of physical chunks that are valid */
+       IMG_UINT32      ui32NumVirtChunks;              /*!< Number of virtual chunks in the mapping */
+       /* Must be last */
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+       IMG_UINT32      *aui32Translation;      /*!< Translation mapping for "logical" to physical */
+#else
+       IMG_UINT32      aui32Translation[1];    /*!< Translation mapping for "logical" to physical */
+#endif
+} PMR_MAPPING_TABLE;
+
+#define TRANSLATION_INVALID 0xFFFFFFFFL
+
+/* A PMR. One per physical allocation.  May be "shared".
+
+   "shared" is ambiguous.  We need to be careful with terminology.
+   There are two ways in which a PMR may be "shared" and we need to be
+   sure that we are clear which we mean.
+
+   i)   multiple small allocations living together inside one PMR;
+
+   ii)  one single allocation filling a PMR but mapped into multiple
+        memory contexts.
+
+   This is more important further up the stack - at this level, all we
+   care is that the PMR is being referenced multiple times.
+*/
+struct _PMR_
+{
+    /* This object is strictly refcounted.  References include:
+       - mapping
+       - live handles (to this object)
+       - live export handles
+       (thus it is normal for allocated and exported memory to have a refcount of 3)
+       The object is destroyed when and only when the refcount reaches 0
+    */
+    /*
+       Physical address translation (device <> cpu) is done on a per device
+       basis which means we need the physcial heap info
+    */
+    PHYS_HEAP *psPhysHeap;
+
+    IMG_UINT32 uiRefCount;
+
+    /* lock count - this is the number of times
+       PMRLockSysPhysAddresses() has been called, less the number of
+       PMRUnlockSysPhysAddresses() calls.  This is arguably here for
+       debug reasons only, as the refcount is already incremented as a
+       matter of course.  Really, this just allows us to trap protocol
+       errors: i.e. calling PMRSysPhysAddr(),
+       without a lock, or calling PMRUnlockSysPhysAddresses() too many
+       or too few times. */
+    IMG_UINT32 uiLockCount;
+
+       /* Lock for this structure */
+       POS_LOCK hLock;
+
+    /* Incrementing serial number to each allocation. */
+    IMG_UINT64 uiSerialNum;
+
+    /* For security, we only allow a PMR to be mapped if the caller
+       knows its key.  We can pseudo-randomly generate keys */
+    PMR_PASSWORD_T uiKey;
+
+    /* Callbacks for per-flavour functions */
+    const PMR_IMPL_FUNCTAB *psFuncTab;
+
+    /* Data associated with the "subtype" */
+    PMR_IMPL_PRIVDATA pvFlavourData;
+
+    /* And for pdump */
+    const IMG_CHAR *pszPDumpDefaultMemspaceName;
+    const IMG_CHAR *pszPDumpFlavour;
+
+    /* Logical size of allocation.  "logical", because a PMR can
+       represent memory that will never physically exist.  This is the
+       amount of virtual space that the PMR would consume when it's
+       mapped into a virtual allocation. */
+    PMR_SIZE_T uiLogicalSize;
+
+       /* Mapping table for the allocation.
+          PMR's can be sparse in which case not all the "logic" addresses
+          in it are valid. We need to know which addresses are and aren't
+          valid when mapping or reading the PMR.
+          The mapping table translates "logical" offsets into physical
+          offsets which is what we always pass to the PMR factory
+          (so it doesn't have to be concerned about sparseness issues) */
+    PMR_MAPPING_TABLE *psMappingTable;
+
+    /* Minimum Physical Contiguity Guarantee.  Might be called "page
+       size", but that would be incorrect, as page size is something
+       meaningful only in virtual realm.  This contiguity guarantee
+       provides an inequality that can be verified/asserted/whatever
+       to ensure that this PMR conforms to the page size requirement
+       of the place the PMR gets mapped.  (May be used to select an
+       appropriate heap in variable page size systems)
+
+       The absolutely necessary condition is this:
+
+       device MMU page size <= actual physical contiguity.
+
+       We go one step further in order to be able to provide an early warning / early compatibility check and say this:
+
+       device MMU page size <= 2**(uiLog2ContiguityGuarantee) <= actual physical contiguity.
+
+       In this way, it is possible to make the page table reservation
+       in the device MMU without even knowing the granularity of the
+       physical memory (i.e. useful for being able to allocate virtual
+       before physical)
+    */
+    PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee;
+
+    /* Flags.  We store a copy of the "PMR flags" (usually a subset of
+       the flags given at allocation time) and return them to any
+       caller of PMR_Flags().  The intention of these flags is that
+       the ones stored here are used to represent permissions, such
+       that noone is able to map a PMR in a mode in which they are not
+       allowed, e.g. writeable for a read-only PMR, etc. */
+    PMR_FLAGS_T uiFlags;
+
+    /* Do we really need this? For now we'll keep it, until we know we don't. */
+    /* NB: this is not the "memory context" in client terms - this is
+       _purely_ the "PMR" context, of which there is almost certainly only
+       ever one per system as a whole, but we'll keep the concept
+       anyway, just-in-case. */
+    struct _PMR_CTX_ *psContext;
+
+#if defined(PVR_RI_DEBUG)
+    /*
+        * Stored handle to PMR RI entry
+        */
+       IMG_PVOID       hRIHandle;
+#endif
+
+       /* Whether PDumping of this PMR must be persistent
+        * (i.e. it must be present in every future PDump stream as well)
+        */
+       IMG_BOOL        bForcePersistent;
+};
+
+/* do we need a struct for the export handle?  I'll use one for now, but if nothing goes in it, we'll lose it */
+struct _PMR_EXPORT_
+{
+    struct _PMR_ *psPMR;
+};
+
+struct _PMR_PAGELIST_
+{
+       struct _PMR_ *psReferencePMR;
+};
+
+/*
+ * This Lock is used to protect the sequence of operation used in MMapPMR and in
+ * the memory management bridge. This should make possible avoid the use of the bridge
+ * lock in mmap.c avoiding regressions.
+ */
+
+/* this structure tracks the current owner of the PMR lock, avoiding use of
+ * the Linux (struct mutex).owner field which is not guaranteed to be up to date.
+ * there is Linux-specific code to provide an opimised approach for Linux,
+ * using the kernel (struct task_struct *) instead of a PID/TID combination.
+ */
+typedef struct _PMR_LOCK_OWNER_
+{
+#if defined(LINUX)
+       struct task_struct *task;
+#else
+       POS_LOCK hPIDTIDLock;
+       IMG_PID uiPID;
+       IMG_UINTPTR_T uiTID;
+#endif
+} PMR_LOCK_OWNER;
+
+POS_LOCK gGlobalLookupPMRLock;
+static PMR_LOCK_OWNER gsPMRLockOwner;
+
+static IMG_VOID _SetPMRLockOwner(IMG_VOID)
+{
+#if defined(LINUX)
+       gsPMRLockOwner.task = current;
+#else
+       OSLockAcquire(gsPMRLockOwner.hPIDTIDLock);
+       gsPMRLockOwner.uiPID = OSGetCurrentProcessID();
+       gsPMRLockOwner.uiTID = OSGetCurrentThreadID();
+       OSLockRelease(gsPMRLockOwner.hPIDTIDLock);
+#endif
+}
+
+/* Must only be called by the thread which owns the PMR lock */
+static IMG_VOID _ClearPMRLockOwner(IMG_VOID)
+{
+#if defined(LINUX)
+       gsPMRLockOwner.task = IMG_NULL;
+#else
+       OSLockAcquire(gsPMRLockOwner.hPIDTIDLock);
+       gsPMRLockOwner.uiPID = 0;
+       gsPMRLockOwner.uiTID = 0;
+       OSLockRelease(gsPMRLockOwner.hPIDTIDLock);
+#endif
+}
+
+static IMG_BOOL _ComparePMRLockOwner(IMG_VOID)
+{
+#if defined(LINUX)
+       return gsPMRLockOwner.task == current;
+#else
+       IMG_BOOL bRet;
+
+       OSLockAcquire(gsPMRLockOwner.hPIDTIDLock);
+       bRet = (gsPMRLockOwner.uiPID == OSGetCurrentProcessID()) &&
+                       (gsPMRLockOwner.uiTID == OSGetCurrentThreadID());
+       OSLockRelease(gsPMRLockOwner.hPIDTIDLock);
+       return bRet;
+#endif
+}
+
+IMG_VOID PMRLock()
+{
+       OSLockAcquire(gGlobalLookupPMRLock);
+       _SetPMRLockOwner();
+}
+
+IMG_VOID PMRUnlock()
+{
+       _ClearPMRLockOwner();
+       OSLockRelease(gGlobalLookupPMRLock);
+}
+
+IMG_BOOL PMRIsLocked(void)
+{
+       return OSLockIsLocked(gGlobalLookupPMRLock);
+}
+
+
+IMG_BOOL PMRIsLockedByMe(void)
+{
+       return PMRIsLocked() && _ComparePMRLockOwner();
+}
+
+#define MIN3(a,b,c)    (((a) < (b)) ? (((a) < (c)) ? (a):(c)) : (((b) < (c)) ? (b):(c)))
+
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+#if defined(LINUX)
+static INLINE IMG_BOOL _IsVmallocAddr(const IMG_VOID *pvAddr)
+{
+       unsigned long lAddr = (unsigned long) pvAddr;
+       return (lAddr >= VMALLOC_START) && (lAddr < VMALLOC_END);
+}
+#endif
+
+static INLINE IMG_VOID *_AllocMem(const IMG_SIZE_T size)
+{
+#if defined(LINUX)
+       if (size > OSGetPageSize())
+               return vmalloc(size);
+       else
+               return OSAllocMem(size);
+#else
+       return OSAllocMem(size);
+#endif
+}
+
+static INLINE IMG_VOID _FreeMem(IMG_VOID *pvAddr)
+{
+#if defined(LINUX)
+       if (_IsVmallocAddr(pvAddr))
+               vfree(pvAddr);
+       else
+               OSFreeMem(pvAddr);
+#else
+       OSFreeMem(pvAddr);
+#endif
+}
+#endif
+
+static PVRSRV_ERROR
+_PMRCreate(PMR_SIZE_T uiLogicalSize,
+           PMR_SIZE_T uiChunkSize,
+           IMG_UINT32 ui32NumPhysChunks,
+           IMG_UINT32 ui32NumVirtChunks,
+           IMG_BOOL *pabMappingTable,
+           PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee,
+           PMR_FLAGS_T uiFlags,
+           PMR **ppsPMR)
+{
+    IMG_VOID *pvPMRLinAddr;
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+    IMG_VOID *pvMapLinAddr;
+#endif
+    PMR *psPMR;
+    PMR_MAPPING_TABLE *psMappingTable;
+    struct _PMR_CTX_ *psContext;
+    IMG_UINT32 i;
+    IMG_UINT32 ui32ValidCount = 0;
+    IMG_UINT32 ui32Remainder;
+    PVRSRV_ERROR eError;
+    IMG_UINT32 ui32PhysIndex = 0;
+
+    psContext = &_gsSingletonPMRContext;
+
+
+       /* Extra checks required for sparse PMRs */
+       if (uiLogicalSize != uiChunkSize)
+       {
+               /* Check the logical size and chunk information agree with each other */
+               if (uiLogicalSize != (uiChunkSize * ui32NumVirtChunks))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Bad mapping size (uiLogicalSize = 0x%llx, uiChunkSize = 0x%llx, ui32NumVirtChunks = %d)",
+                                       __FUNCTION__, (unsigned long long)uiLogicalSize, (unsigned long long)uiChunkSize, ui32NumVirtChunks));
+                       return PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE;
+               }
+
+               /* Check that the chunk size is a multiple of the contiguity */
+               OSDivide64(uiChunkSize, (1<< uiLog2ContiguityGuarantee), &ui32Remainder);
+               if (ui32Remainder)
+               {
+                       return PVRSRV_ERROR_PMR_BAD_CHUNK_SIZE;
+               }
+
+               /* Check the mapping table */
+               for (i = 0; i<ui32NumVirtChunks;i++)
+               {
+                       if (pabMappingTable[i])
+                       {
+                               ui32ValidCount++;
+                       }
+               }
+       
+               if (ui32ValidCount != ui32NumPhysChunks)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "%s: Mismatch in mapping table, expecting %d valid entries but found %d",
+                                        __FUNCTION__,
+                                        ui32NumPhysChunks,
+                                        ui32ValidCount));
+                       return PVRSRV_ERROR_PMR_MAPPINGTABLE_MISMATCH;
+               }
+       }
+
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+       pvPMRLinAddr = OSAllocMem(sizeof(*psPMR) + sizeof(*psMappingTable));
+#else
+       pvPMRLinAddr = OSAllocMem(sizeof(*psPMR) + sizeof(*psMappingTable) + sizeof(IMG_UINT32) * ui32NumVirtChunks);
+#endif
+       if (pvPMRLinAddr == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+       pvMapLinAddr = _AllocMem(sizeof(IMG_UINT32) * ui32NumVirtChunks);
+       if (pvMapLinAddr == IMG_NULL)
+       {
+               OSFreeMem(pvPMRLinAddr);
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psPMR = (PMR *) pvPMRLinAddr;
+       psMappingTable = (PMR_MAPPING_TABLE *) (((IMG_CHAR *) pvPMRLinAddr) + sizeof(*psPMR));
+       psMappingTable->aui32Translation = (IMG_UINT32 *) pvMapLinAddr;
+#else
+       psPMR = (PMR *) pvPMRLinAddr;
+       psMappingTable = (PMR_MAPPING_TABLE *) (((IMG_CHAR *) pvPMRLinAddr) + sizeof(*psPMR));
+#endif
+
+       eError = OSLockCreate(&psPMR->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+               _FreeMem(psMappingTable->aui32Translation);
+#endif
+               OSFreeMem(psPMR);
+               return eError;
+       }
+
+       /* Setup the mapping table */
+       psMappingTable->uiChunkSize = uiChunkSize;
+       psMappingTable->ui32NumVirtChunks = ui32NumVirtChunks;
+       psMappingTable->ui32NumPhysChunks = ui32NumPhysChunks;
+       for (i=0;i<ui32NumVirtChunks;i++)
+       {
+               if (pabMappingTable[i])
+               {
+                       psMappingTable->aui32Translation[i] = ui32PhysIndex++;
+               }
+               else
+               {
+                       psMappingTable->aui32Translation[i] = TRANSLATION_INVALID;
+               }
+       }
+
+       /* Setup the PMR */
+       psPMR->uiRefCount = 0;
+       psPMR->uiLockCount = 0;
+       psPMR->psContext = psContext;
+       psPMR->uiLogicalSize = uiLogicalSize;
+       psPMR->uiLog2ContiguityGuarantee = uiLog2ContiguityGuarantee;
+       psPMR->uiFlags = uiFlags;
+       psPMR->psMappingTable = psMappingTable;
+       psPMR->uiKey = psContext->uiNextKey;
+       psPMR->uiSerialNum = psContext->uiNextSerialNum;
+
+#if defined(PVR_RI_DEBUG)
+       psPMR->hRIHandle = IMG_NULL;
+#endif
+
+       OSLockAcquire(psContext->hLock);
+       psContext->uiNextKey = (0x80200003 * psContext->uiNextKey)
+               ^ (0xf00f0081 * (IMG_UINTPTR_T)pvPMRLinAddr);
+       psContext->uiNextSerialNum ++;
+       *ppsPMR = psPMR;
+       PVR_DPF((PVR_DBG_MESSAGE, "pmr.c: created PMR @0x%p", psPMR));
+       /* Increment live PMR count */
+       psContext->uiNumLivePMRs ++;
+       OSLockRelease(psContext->hLock);
+
+       return PVRSRV_OK;
+}
+
+static IMG_UINT32
+_RefNoLock(PMR *psPMR)
+{
+       psPMR->uiRefCount++;
+       return psPMR->uiRefCount;
+}
+
+static IMG_UINT32
+_UnrefNoLock(PMR *psPMR)
+{
+    PVR_ASSERT(psPMR->uiRefCount > 0);
+       psPMR->uiRefCount--;
+       return psPMR->uiRefCount;
+}
+
+static IMG_VOID
+_Ref(PMR *psPMR)
+{
+       OSLockAcquire(psPMR->hLock);
+       _RefNoLock(psPMR);
+       OSLockRelease(psPMR->hLock);
+}
+
+static IMG_VOID
+_UnrefAndMaybeDestroy(PMR *psPMR)
+{
+    PVRSRV_ERROR eError2;
+    struct _PMR_CTX_ *psCtx;
+    IMG_UINT32 uiRefCount;
+
+    PVR_ASSERT(psPMR != IMG_NULL);
+    PVR_ASSERT(psPMR->uiRefCount > 0);
+
+    OSLockAcquire(psPMR->hLock);
+       uiRefCount = _UnrefNoLock(psPMR);
+    OSLockRelease(psPMR->hLock);
+
+    if (uiRefCount == 0)
+    {
+        if (psPMR->psFuncTab->pfnFinalize != IMG_NULL)
+        {
+            eError2 = psPMR->psFuncTab->pfnFinalize(psPMR->pvFlavourData);
+            PVR_ASSERT (eError2 == PVRSRV_OK); /* can we do better? */
+        }
+
+#ifdef PVRSRV_NEED_PVR_ASSERT
+        OSLockAcquire(psPMR->hLock);
+        PVR_ASSERT(psPMR->uiLockCount == 0);
+        OSLockRelease(psPMR->hLock);
+#endif
+
+#if defined(PVR_RI_DEBUG)
+               {
+            PVRSRV_ERROR eError;
+
+                       /* Delete RI entry */
+            if (psPMR->hRIHandle)
+            {
+               eError = RIDeletePMREntryKM (psPMR->hRIHandle);
+            }
+               }
+#endif /* if defined(PVR_RI_DEBUG) */
+               psCtx = psPMR->psContext;
+
+               OSLockDestroy(psPMR->hLock);
+#if defined(PVRSRV_SPLIT_LARGE_OSMEM_ALLOC)
+               _FreeMem(psPMR->psMappingTable->aui32Translation);
+#endif
+        OSFreeMem(psPMR);
+
+        /* Decrement live PMR count.  Probably only of interest for debugging */
+        PVR_ASSERT(psCtx->uiNumLivePMRs > 0);
+
+        OSLockAcquire(psCtx->hLock);
+        psCtx->uiNumLivePMRs --;
+        OSLockRelease(psCtx->hLock);
+    }
+}
+
+static IMG_BOOL _PMRIsSparse(const PMR *psPMR)
+{
+       if (psPMR->psMappingTable->ui32NumVirtChunks == psPMR->psMappingTable->ui32NumPhysChunks)
+       {
+               return IMG_FALSE;
+       }
+
+       return IMG_TRUE;
+}
+
+PVRSRV_ERROR
+PMRCreatePMR(PHYS_HEAP *psPhysHeap,
+             PMR_SIZE_T uiLogicalSize,
+             PMR_SIZE_T uiChunkSize,
+             IMG_UINT32 ui32NumPhysChunks,
+             IMG_UINT32 ui32NumVirtChunks,
+             IMG_BOOL *pabMappingTable,
+             PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee,
+             PMR_FLAGS_T uiFlags,
+             const IMG_CHAR *pszPDumpFlavour,
+             const PMR_IMPL_FUNCTAB *psFuncTab,
+             PMR_IMPL_PRIVDATA pvPrivData,
+             PMR **ppsPMRPtr,
+             IMG_HANDLE *phPDumpAllocInfo,
+             IMG_BOOL bForcePersistent)
+{
+    PMR *psPMR = IMG_NULL;
+    PVRSRV_ERROR eError;
+
+    eError = _PMRCreate(uiLogicalSize,
+                                               uiChunkSize,
+                                               ui32NumPhysChunks,
+                                               ui32NumVirtChunks,
+                                               pabMappingTable,
+                                               uiLog2ContiguityGuarantee,
+                                               uiFlags,
+                        &psPMR);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    psPMR->psPhysHeap = psPhysHeap;
+    psPMR->psFuncTab = psFuncTab;
+    psPMR->pszPDumpDefaultMemspaceName = PhysHeapPDumpMemspaceName(psPhysHeap);
+    psPMR->pszPDumpFlavour = pszPDumpFlavour;
+    psPMR->pvFlavourData = pvPrivData;
+    psPMR->uiRefCount = 1;
+    psPMR->bForcePersistent = bForcePersistent;
+
+    *ppsPMRPtr = psPMR;
+
+
+       if (phPDumpAllocInfo)
+       {
+               PDumpPMRMallocPMR(psPMR,
+                                                 (uiChunkSize * ui32NumPhysChunks),
+                                                 1ULL<<uiLog2ContiguityGuarantee,
+                                                 bForcePersistent,
+                                                 phPDumpAllocInfo);
+       }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR PMRLockSysPhysAddressesNested(PMR *psPMR,
+                        IMG_UINT32 uiLog2RequiredContiguity,
+                        IMG_UINT32 ui32NestingLevel)
+{
+    PVRSRV_ERROR eError;
+
+    PVR_ASSERT(psPMR != IMG_NULL);
+
+    if (uiLog2RequiredContiguity > psPMR->uiLog2ContiguityGuarantee)
+    {
+        eError = PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
+        goto e0;
+    }
+
+       OSLockAcquireNested(psPMR->hLock, ui32NestingLevel);
+    /* We also count the locks as references, so that the PMR is not
+       freed while someone is using a physical address. */
+    /* "lock" here simply means incrementing the refcount.  It means
+       the refcount is multipurpose, but that's okay.  We only have to
+       promise that physical addresses are valid after this point, and
+       remain valid until the corresponding
+       PMRUnlockSysPhysAddressesOSMem() */
+    _RefNoLock(psPMR);
+
+    /* Also count locks separately from other types of references, to
+       allow for debug assertions */
+    psPMR->uiLockCount++;
+
+    /* Only call callback if lockcount transitions from 0 to 1 */
+    if (psPMR->uiLockCount == 1)
+    {
+        if (psPMR->psFuncTab->pfnLockPhysAddresses != IMG_NULL)
+        {
+            /* must always have lock and unlock in pairs! */
+            PVR_ASSERT(psPMR->psFuncTab->pfnUnlockPhysAddresses != IMG_NULL);
+
+            eError = psPMR->psFuncTab->pfnLockPhysAddresses(psPMR->pvFlavourData,
+                                                            uiLog2RequiredContiguity);
+
+            if (eError != PVRSRV_OK)
+            {
+                goto e1;
+            }
+        }
+    }
+       OSLockRelease(psPMR->hLock);
+
+    return PVRSRV_OK;
+
+ e1:
+    psPMR->uiLockCount--;
+    _UnrefNoLock(psPMR);
+    PVR_ASSERT(psPMR->uiRefCount != 0);
+    OSLockRelease(psPMR->hLock);
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMRLockSysPhysAddresses(PMR *psPMR,
+                        IMG_UINT32 uiLog2RequiredContiguity)
+{
+       return PMRLockSysPhysAddressesNested(psPMR, uiLog2RequiredContiguity, 0);
+}
+
+PVRSRV_ERROR
+PMRUnlockSysPhysAddresses(PMR *psPMR)
+{
+    PVRSRV_ERROR eError;
+
+    PVR_ASSERT(psPMR != IMG_NULL);
+
+       OSLockAcquire(psPMR->hLock);
+       PVR_ASSERT(psPMR->uiLockCount > 0);
+       psPMR->uiLockCount--;
+
+    if (psPMR->uiLockCount == 0)
+    {
+        if (psPMR->psFuncTab->pfnUnlockPhysAddresses != IMG_NULL)
+        {
+            PVR_ASSERT(psPMR->psFuncTab->pfnLockPhysAddresses != IMG_NULL);
+
+            eError = psPMR->psFuncTab->pfnUnlockPhysAddresses(psPMR->pvFlavourData);
+            /* must never fail */
+            PVR_ASSERT(eError == PVRSRV_OK);
+        }
+    }
+
+    OSLockRelease(psPMR->hLock);
+
+    /* We also count the locks as references, so that the PMR is not
+       freed while someone is using a physical address. */
+    _UnrefAndMaybeDestroy(psPMR);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRExportPMR(PMR *psPMR,
+             PMR_EXPORT **ppsPMRExportPtr,
+             PMR_SIZE_T *puiSize,
+             PMR_LOG2ALIGN_T *puiLog2Contig,
+             PMR_PASSWORD_T *puiPassword)
+{
+    IMG_UINT64 uiPassword;
+    PMR_EXPORT *psPMRExport;
+
+    uiPassword = psPMR->uiKey;
+
+    psPMRExport = OSAllocMem(sizeof(*psPMRExport));
+    if (psPMRExport == IMG_NULL)
+    {
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+
+    psPMRExport->psPMR = psPMR;
+    _Ref(psPMR);
+
+    *ppsPMRExportPtr = psPMRExport;
+    *puiSize = psPMR->uiLogicalSize;
+    *puiLog2Contig = psPMR->uiLog2ContiguityGuarantee;
+    *puiPassword = uiPassword;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRMakeServerExportClientExport(DEVMEM_EXPORTCOOKIE *psPMRExportIn,
+                                                               PMR_EXPORT **ppsPMRExportPtr,
+                                                               PMR_SIZE_T *puiSize,
+                                                               PMR_LOG2ALIGN_T *puiLog2Contig,
+                                                               PMR_PASSWORD_T *puiPassword)
+{
+       *ppsPMRExportPtr = (PMR_EXPORT *) psPMRExportIn->hPMRExportHandle;
+       *puiSize = psPMRExportIn->uiSize;
+       *puiLog2Contig = psPMRExportIn->uiLog2ContiguityGuarantee;
+       *puiPassword = psPMRExportIn->uiPMRExportPassword;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRUnmakeServerExportClientExport(PMR_EXPORT *psPMRExport)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMRExport);
+
+       /*
+        * There is nothing to do here, the server will call unexport
+        * regardless of the type of shutdown. In order to play ball
+        * with the handle manager (where it's used) we need to pair
+        * functions and this is PMRMakeServerExportClientExport
+        * counterpart.
+        */
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRUnexportPMR(PMR_EXPORT *psPMRExport)
+{
+    /* FIXME: probably shouldn't be assertions? */
+    PVR_ASSERT(psPMRExport != IMG_NULL);
+    PVR_ASSERT(psPMRExport->psPMR != IMG_NULL);
+    PVR_ASSERT(psPMRExport->psPMR->uiRefCount > 0);
+
+    _UnrefAndMaybeDestroy(psPMRExport->psPMR);
+
+    OSFreeMem(psPMRExport);
+
+    return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+PMRImportPMR(PMR_EXPORT *psPMRExport,
+             PMR_PASSWORD_T uiPassword,
+             PMR_SIZE_T uiSize,
+             PMR_LOG2ALIGN_T uiLog2Contig,
+             PMR **ppsPMR)
+{
+    PMR *psPMR;
+
+    /* FIXME: probably shouldn't be assertions? */
+    PVR_ASSERT(psPMRExport != IMG_NULL);
+    PVR_ASSERT(psPMRExport->psPMR != IMG_NULL);
+    PVR_ASSERT(psPMRExport->psPMR->uiRefCount > 0);
+
+    psPMR = psPMRExport->psPMR;
+
+    if (psPMR->uiKey != uiPassword)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+                 "PMRImport: password given = %016llx, expected = %016llx\n",
+                 uiPassword,
+                 psPMR->uiKey));
+        return PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR;
+    }
+
+    if (psPMR->uiLogicalSize != uiSize || psPMR->uiLog2ContiguityGuarantee != uiLog2Contig)
+    {
+        return PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES;
+    }
+
+    _Ref(psPMR);
+
+    *ppsPMR = psPMR;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRUnimportPMR(PMR *psPMR)
+{
+    _UnrefAndMaybeDestroy(psPMR);
+
+    return PVRSRV_OK;
+}
+
+/*
+       Note:
+       We pass back the PMR as it was passed in as a different handle type
+       (DEVMEM_MEM_IMPORT) and it allows us to change the import structure
+       type if we should need to embed any meta data in it.
+*/
+PVRSRV_ERROR
+PMRLocalImportPMR(PMR *psPMR,
+                                 PMR **ppsPMR,
+                                 IMG_DEVMEM_SIZE_T *puiSize,
+                                 IMG_DEVMEM_ALIGN_T *puiAlign)
+{
+        _Ref(psPMR);
+
+       /* Return the PMR */
+       *ppsPMR = psPMR;
+       *puiSize = psPMR->uiLogicalSize;
+       *puiAlign = 1ULL << psPMR->uiLog2ContiguityGuarantee;
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRGetUID(PMR *psPMR,
+                 IMG_UINT64 *pui64UID)
+{
+       PVR_ASSERT(psPMR != IMG_NULL);
+
+       *pui64UID = psPMR->uiSerialNum;
+
+       return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_SECURE_EXPORT)
+PVRSRV_ERROR PMRSecureExportPMR(CONNECTION_DATA *psConnection,
+                                                               PMR *psPMR,
+                                                               IMG_SECURE_TYPE *phSecure,
+                                                               PMR **ppsPMR,
+                                                               CONNECTION_DATA **ppsSecureConnection)
+{
+       PVRSRV_ERROR eError;
+
+       /* We are acquiring reference to PMR here because OSSecureExport
+        * releases bridge lock and PMR lock for a moment and we don't want PMR
+        * to be removed by other thread in the meantime. */
+       _Ref(psPMR);
+
+       eError = OSSecureExport(psConnection,
+                                                       (IMG_PVOID) psPMR,
+                                                       phSecure,
+                                                       ppsSecureConnection);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       *ppsPMR = psPMR;
+
+       return PVRSRV_OK;
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       _UnrefAndMaybeDestroy(psPMR);
+       return eError;
+}
+
+PVRSRV_ERROR PMRSecureUnexportPMR(PMR *psPMR)
+{
+       _UnrefAndMaybeDestroy(psPMR);
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PMRSecureImportPMR(IMG_SECURE_TYPE hSecure,
+                                                               PMR **ppsPMR,
+                                                               IMG_DEVMEM_SIZE_T *puiSize,
+                                                               IMG_DEVMEM_ALIGN_T *puiAlign)
+{
+       PVRSRV_ERROR eError;
+       PMR *psPMR;
+
+       eError = OSSecureImport(hSecure, (IMG_PVOID *) &psPMR);
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       _Ref(psPMR);
+
+       /* Return the PMR */
+       *ppsPMR = psPMR;
+       *puiSize = psPMR->uiLogicalSize;
+       *puiAlign = 1 << psPMR->uiLog2ContiguityGuarantee;
+       return PVRSRV_OK;
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+PVRSRV_ERROR PMRSecureUnimportPMR(PMR *psPMR)
+{
+       _UnrefAndMaybeDestroy(psPMR);
+       return PVRSRV_OK;
+}
+#endif
+
+#if defined(PVR_RI_DEBUG)
+PVRSRV_ERROR
+PMRStoreRIHandle(PMR *psPMR,
+                                IMG_PVOID hRIHandle)
+{
+    PVR_ASSERT(psPMR != IMG_NULL);
+
+    psPMR->hRIHandle = hRIHandle;
+    return PVRSRV_OK;
+}
+#endif
+
+static PVRSRV_ERROR
+_PMRAcquireKernelMappingData(PMR *psPMR,
+                            IMG_SIZE_T uiLogicalOffset,
+                            IMG_SIZE_T uiSize,
+                            IMG_VOID **ppvKernelAddressOut,
+                            IMG_SIZE_T *puiLengthOut,
+                            IMG_HANDLE *phPrivOut,
+                            IMG_BOOL bMapSparse)
+{
+    PVRSRV_ERROR eError;
+    IMG_VOID *pvKernelAddress;
+    IMG_HANDLE hPriv;
+    PMR_FLAGS_T ulFlags;
+
+    PVR_ASSERT(psPMR != IMG_NULL);
+
+    if (_PMRIsSparse(psPMR) && !bMapSparse)
+    {
+        /* Generally we don't support mapping of sparse allocations but if there
+           is a justified need we can do that by passing IMG_TRUE in bMapSparse.
+           Although the callback is supported by the PMR it will always map
+           the physical 1:1 as sparseness issues are handled here in the core */
+        return PVRSRV_ERROR_PMR_NOT_PERMITTED;
+    }
+
+    /* Acquire/Release functions must be overridden in pairs */
+    if (psPMR->psFuncTab->pfnAcquireKernelMappingData == IMG_NULL)
+    {
+        PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData == IMG_NULL);
+
+        /* If PMR implementation does not supply this pair of
+           functions, it means they do not permit the PMR to be mapped
+           into kernel memory at all */
+        eError = PVRSRV_ERROR_PMR_NOT_PERMITTED;
+        goto e0;
+    }
+    PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData != IMG_NULL);
+
+    PMR_Flags(psPMR, &ulFlags);
+
+    eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData,
+                                                           uiLogicalOffset,
+                                                           uiSize,
+                                                           &pvKernelAddress,
+                                                           &hPriv,
+                                                           ulFlags);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    *ppvKernelAddressOut = pvKernelAddress;
+    if (uiSize == 0)
+    {
+        /* Zero size means map the whole PMR in ...*/
+        *puiLengthOut = (IMG_SIZE_T)psPMR->uiLogicalSize;
+    }
+    else if (uiSize > (1 << psPMR->uiLog2ContiguityGuarantee))
+    {
+       /* ... map in the requested pages ...*/
+               *puiLengthOut = uiSize;
+    }
+    else
+    {
+        /* ... otherwise we just map in one page */
+        *puiLengthOut = 1 << psPMR->uiLog2ContiguityGuarantee;
+    }
+    *phPrivOut = hPriv;
+
+    return PVRSRV_OK;
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMRAcquireKernelMappingData(PMR *psPMR,
+                            IMG_SIZE_T uiLogicalOffset,
+                            IMG_SIZE_T uiSize,
+                            IMG_VOID **ppvKernelAddressOut,
+                            IMG_SIZE_T *puiLengthOut,
+                            IMG_HANDLE *phPrivOut)
+{
+    return _PMRAcquireKernelMappingData(psPMR,
+                                        uiLogicalOffset,
+                                        uiSize,
+                                        ppvKernelAddressOut,
+                                        puiLengthOut,
+                                        phPrivOut,
+                                        IMG_FALSE);
+}
+
+PVRSRV_ERROR
+PMRAcquireSparseKernelMappingData(PMR *psPMR,
+                                  IMG_SIZE_T uiLogicalOffset,
+                                  IMG_SIZE_T uiSize,
+                                  IMG_VOID **ppvKernelAddressOut,
+                                  IMG_SIZE_T *puiLengthOut,
+                                  IMG_HANDLE *phPrivOut)
+{
+    return _PMRAcquireKernelMappingData(psPMR,
+                                        uiLogicalOffset,
+                                        uiSize,
+                                        ppvKernelAddressOut,
+                                        puiLengthOut,
+                                        phPrivOut,
+                                        IMG_TRUE);
+}
+
+PVRSRV_ERROR
+PMRReleaseKernelMappingData(PMR *psPMR,
+                            IMG_HANDLE hPriv)
+{
+    PVR_ASSERT (psPMR->psFuncTab->pfnAcquireKernelMappingData != IMG_NULL);
+    PVR_ASSERT (psPMR->psFuncTab->pfnReleaseKernelMappingData != IMG_NULL);
+
+    psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData,
+                                                  hPriv);
+
+    return PVRSRV_OK;
+}
+
+/*
+       _PMRLogicalOffsetToPhysicalOffset
+
+       Translate between the "logical" offset which the upper levels
+       provide and the physical offset which is what the PMR
+       factories works on.
+
+       As well as returning the physical offset we return the number of
+       bytes remaining till the next chunk and if this chunk is valid.
+
+       For multi-page operations, upper layers communicate their 
+       Log2PageSize else argument is redundant (set to zero). 
+*/
+
+static IMG_VOID
+_PMRLogicalOffsetToPhysicalOffset(const PMR *psPMR,
+                                                                 IMG_UINT32 ui32Log2PageSize,
+                                                                 IMG_UINT32 ui32NumOfPages,
+                                                                 IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                                                                 IMG_DEVMEM_OFFSET_T *puiPhysicalOffset,
+                                                                 IMG_UINT32 *pui32BytesRemain,
+                                                                 IMG_BOOL *bValid)
+{
+       PMR_MAPPING_TABLE *psMappingTable = psPMR->psMappingTable;
+       IMG_DEVMEM_OFFSET_T uiPageSize = 1ULL << ui32Log2PageSize;
+       IMG_DEVMEM_OFFSET_T uiOffset = uiLogicalOffset;
+       IMG_UINT64 ui64ChunkIndex;
+       IMG_UINT32 ui32Remain;
+       IMG_UINT32 idx;
+
+       /* Must be translating at least a page */
+       PVR_ASSERT(ui32NumOfPages);
+
+       if (psMappingTable->ui32NumPhysChunks == psMappingTable->ui32NumVirtChunks)
+       {
+               /* Fast path the common case, as logical and physical offsets are
+                       equal we _assume_ the ui32NumOfPages span is also valid */
+               *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiOffset);
+               puiPhysicalOffset[0] = uiOffset;
+               bValid[0] = IMG_TRUE;
+               
+               if (ui32NumOfPages > 1)
+               {
+                       /* initial offset may not be page aligned, round down */
+                       uiOffset &= ~(uiPageSize-1);
+                       for (idx=1; idx < ui32NumOfPages; idx++)
+                       {
+                               uiOffset += uiPageSize;
+                               puiPhysicalOffset[idx] = uiOffset;
+                               bValid[idx] = IMG_TRUE;
+                       }
+               }
+       }
+       else
+       {
+               for (idx=0; idx < ui32NumOfPages; idx++)
+               {
+                       ui64ChunkIndex = OSDivide64r64(
+                                       uiOffset,
+                                       TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize),
+                                       &ui32Remain);
+
+                       if (psMappingTable->aui32Translation[ui64ChunkIndex] == TRANSLATION_INVALID)
+                       {
+                               bValid[idx] = IMG_FALSE;
+                       }
+                       else
+                       {
+                               bValid[idx] = IMG_TRUE;
+                       }
+
+                       if (idx == 0)
+                       {
+                               if (ui32Remain == 0)
+                               {
+                                       /* Start of chunk so return the chunk size */
+                                       *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize);
+                               }
+                               else
+                               {
+                                       *pui32BytesRemain = TRUNCATE_64BITS_TO_32BITS(psMappingTable->uiChunkSize - ui32Remain);
+                               }
+
+                               puiPhysicalOffset[idx] = (psMappingTable->aui32Translation[ui64ChunkIndex] * psMappingTable->uiChunkSize) +      ui32Remain;
+                               
+                               /* initial offset may not be page aligned, round down */
+                               uiOffset &= ~(uiPageSize-1);
+                       }
+                       else
+                       {
+                               puiPhysicalOffset[idx] = psMappingTable->aui32Translation[ui64ChunkIndex] * psMappingTable->uiChunkSize;
+                       }
+                       uiOffset += uiPageSize;
+               }
+       }
+}
+
+static PVRSRV_ERROR
+_PMR_ReadBytesPhysical(PMR *psPMR,
+                       IMG_DEVMEM_OFFSET_T uiPhysicalOffset,
+                       IMG_UINT8 *pcBuffer,
+                       IMG_SIZE_T uiBufSz,
+                       IMG_SIZE_T *puiNumBytes)
+{
+       PVRSRV_ERROR eError;
+
+    if (psPMR->psFuncTab->pfnReadBytes != IMG_NULL)
+    {
+        /* defer to callback if present */
+
+        eError = PMRLockSysPhysAddresses(psPMR,
+                                         psPMR->uiLog2ContiguityGuarantee);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+
+        eError = psPMR->psFuncTab->pfnReadBytes(psPMR->pvFlavourData,
+                                                uiPhysicalOffset,
+                                                pcBuffer,
+                                                uiBufSz,
+                                                puiNumBytes);
+        PMRUnlockSysPhysAddresses(psPMR);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+    }
+    else if (psPMR->psFuncTab->pfnAcquireKernelMappingData)
+    {
+        /* "default" handler for reading bytes */
+
+        IMG_HANDLE hKernelMappingHandle;
+        IMG_UINT8 *pcKernelAddress;
+        PMR_FLAGS_T ulFlags;
+
+        PMR_Flags(psPMR, &ulFlags);
+
+        eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData,
+                                                               (IMG_SIZE_T) uiPhysicalOffset,
+                                                               uiBufSz,
+                                                               (IMG_VOID **)&pcKernelAddress,
+                                                               &hKernelMappingHandle,
+                                                               ulFlags);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+
+        OSMemCopy(&pcBuffer[0], pcKernelAddress, uiBufSz);
+        *puiNumBytes = uiBufSz;
+
+        psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData,
+                                                      hKernelMappingHandle);
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR, "PMR_ReadBytes: can't read from this PMR"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        OSPanic();
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMR_ReadBytes(PMR *psPMR,
+              IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+              IMG_UINT8 *pcBuffer,
+              IMG_SIZE_T uiBufSz,
+              IMG_SIZE_T *puiNumBytes)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    IMG_DEVMEM_OFFSET_T uiPhysicalOffset;
+    IMG_SIZE_T uiBytesCopied = 0;
+
+    if (uiLogicalOffset + uiBufSz > psPMR->uiLogicalSize)
+    {
+               uiBufSz = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiLogicalOffset);
+    }
+    PVR_ASSERT(uiBufSz > 0);
+    PVR_ASSERT(uiBufSz <= psPMR->uiLogicalSize);
+
+    /*
+      PMR implementations can override this.  If they don't, a
+      "default" handler uses kernel virtual mappings.  If the kernel
+      can't provide a kernel virtual mapping, this function fails
+    */
+    PVR_ASSERT(psPMR->psFuncTab->pfnAcquireKernelMappingData != IMG_NULL ||
+               psPMR->psFuncTab->pfnReadBytes != IMG_NULL);
+
+       while (uiBytesCopied != uiBufSz)
+       {
+               IMG_UINT32 ui32Remain;
+               IMG_SIZE_T uiBytesToCopy;
+               IMG_SIZE_T uiRead;
+               IMG_BOOL bValid;
+
+               _PMRLogicalOffsetToPhysicalOffset(psPMR,
+                                                                                 0,
+                                                                                 1,
+                                                                                 uiLogicalOffset,
+                                                                                 &uiPhysicalOffset,
+                                                                                 &ui32Remain,
+                                                                                 &bValid);
+               /* 
+                       Copy till either then end of the
+                       chunk or end end of the buffer
+               */
+               uiBytesToCopy = MIN(uiBufSz - uiBytesCopied, ui32Remain);
+
+               if (bValid)
+               {
+                       /* Read the data from the PMR */
+                       eError = _PMR_ReadBytesPhysical(psPMR,
+                                                                                       uiPhysicalOffset,
+                                                                                       &pcBuffer[uiBytesCopied],
+                                                                                       uiBytesToCopy,
+                                                                                       &uiRead);
+                       if ((eError != PVRSRV_OK) || (uiRead != uiBytesToCopy))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                                "%s: Failed to read chunk (eError = %s, uiRead = "IMG_SIZE_FMTSPEC" uiBytesToCopy = "IMG_SIZE_FMTSPEC")",
+                                                __FUNCTION__,
+                                                PVRSRVGetErrorStringKM(eError),
+                                                uiRead,
+                                                uiBytesToCopy));
+                               /* Bail out as soon as we hit an error */
+                               break;
+                       }
+               }
+               else
+               {
+                       /* Fill invalid chunks with 0 */
+                       OSMemSet(&pcBuffer[uiBytesCopied], 0, uiBytesToCopy);
+                       uiRead = uiBytesToCopy;
+               }
+               uiLogicalOffset += uiRead;
+               uiBytesCopied += uiRead;
+       }
+
+       *puiNumBytes = uiBytesCopied;
+    return eError;
+}
+
+static PVRSRV_ERROR
+_PMR_WriteBytesPhysical(PMR *psPMR,
+                                               IMG_DEVMEM_OFFSET_T uiPhysicalOffset,
+                                               IMG_UINT8 *pcBuffer,
+                                               IMG_SIZE_T uiBufSz,
+                                               IMG_SIZE_T *puiNumBytes)
+{
+       PVRSRV_ERROR eError;
+
+    if (psPMR->psFuncTab->pfnWriteBytes != IMG_NULL)
+    {
+        /* defer to callback if present */
+
+        eError = PMRLockSysPhysAddresses(psPMR,
+                                         psPMR->uiLog2ContiguityGuarantee);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+
+        eError = psPMR->psFuncTab->pfnWriteBytes(psPMR->pvFlavourData,
+                                                                                                uiPhysicalOffset,
+                                                 pcBuffer,
+                                                 uiBufSz,
+                                                 puiNumBytes);
+        PMRUnlockSysPhysAddresses(psPMR);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+    }
+    else if (psPMR->psFuncTab->pfnAcquireKernelMappingData)
+    {
+        /* "default" handler for reading bytes */
+
+        IMG_HANDLE hKernelMappingHandle;
+        IMG_UINT8 *pcKernelAddress;
+        PMR_FLAGS_T ulFlags;
+
+        PMR_Flags(psPMR, &ulFlags);
+
+        eError = psPMR->psFuncTab->pfnAcquireKernelMappingData(psPMR->pvFlavourData,
+                                                               (IMG_SIZE_T) uiPhysicalOffset,
+                                                               uiBufSz,
+                                                               (IMG_VOID **)&pcKernelAddress,
+                                                               &hKernelMappingHandle,
+                                                               ulFlags);
+        if (eError != PVRSRV_OK)
+        {
+            goto e0;
+        }
+
+               OSMemCopy(pcKernelAddress, &pcBuffer[0], uiBufSz);
+        *puiNumBytes = uiBufSz;
+
+        psPMR->psFuncTab->pfnReleaseKernelMappingData(psPMR->pvFlavourData,
+                                                      hKernelMappingHandle);
+    }
+    else
+    {
+               /*
+                       The write callback is optional as it's only required by the debug
+                       tools
+               */
+        PVR_DPF((PVR_DBG_ERROR, "_PMR_WriteBytesPhysical: can't write to this PMR"));
+        eError = PVRSRV_ERROR_PMR_NOT_PERMITTED;
+        OSPanic();
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMR_WriteBytes(PMR *psPMR,
+                          IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+               IMG_UINT8 *pcBuffer,
+               IMG_SIZE_T uiBufSz,
+               IMG_SIZE_T *puiNumBytes)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+       #if 0
+    PMR_FLAGS_T uiFlags;
+       #endif
+    IMG_DEVMEM_OFFSET_T uiPhysicalOffset;
+    IMG_SIZE_T uiBytesCopied = 0;
+
+       /* FIXME: When we honour CPU mapping flags remove the #if 0*/
+       #if 0
+       /* Check that writes are allowed */
+       PMR_Flags(psPMR, &uiFlags);
+       if (!(uiFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE))
+       {
+               return PVRSRV_ERROR_PMR_NOT_PERMITTED;
+       }
+       #endif
+
+    if (uiLogicalOffset + uiBufSz > psPMR->uiLogicalSize)
+    {
+        uiBufSz = TRUNCATE_64BITS_TO_32BITS(psPMR->uiLogicalSize - uiLogicalOffset);
+    }
+    PVR_ASSERT(uiBufSz > 0);
+    PVR_ASSERT(uiBufSz <= psPMR->uiLogicalSize);
+
+    /*
+      PMR implementations can override this.  If they don't, a
+      "default" handler uses kernel virtual mappings.  If the kernel
+      can't provide a kernel virtual mapping, this function fails
+    */
+    PVR_ASSERT(psPMR->psFuncTab->pfnAcquireKernelMappingData != IMG_NULL ||
+               psPMR->psFuncTab->pfnWriteBytes != IMG_NULL);
+
+       while (uiBytesCopied != uiBufSz)
+       {
+               IMG_UINT32 ui32Remain;
+               IMG_SIZE_T uiBytesToCopy;
+               IMG_SIZE_T uiWrite;
+               IMG_BOOL bValid;
+
+               _PMRLogicalOffsetToPhysicalOffset(psPMR,
+                                                                                 0,
+                                                                                 1,
+                                                                                 uiLogicalOffset,
+                                                                                 &uiPhysicalOffset,
+                                                                                 &ui32Remain,
+                                                                                 &bValid);
+
+               /* 
+                       Copy till either then end of the
+                       chunk or end end of the buffer
+               */
+               uiBytesToCopy = MIN(uiBufSz - uiBytesCopied, ui32Remain);
+
+               if (bValid)
+               {
+                       /* Write the data to the PMR */
+                       eError = _PMR_WriteBytesPhysical(psPMR,
+                                                                                        uiPhysicalOffset,
+                                                                                        &pcBuffer[uiBytesCopied],
+                                                                                        uiBytesToCopy,
+                                                                                        &uiWrite);
+                       if ((eError != PVRSRV_OK) || (uiWrite != uiBytesToCopy))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                                "%s: Failed to read chunk (eError = %s, uiWrite = "IMG_SIZE_FMTSPEC" uiBytesToCopy = "IMG_SIZE_FMTSPEC")",
+                                                __FUNCTION__,
+                                                PVRSRVGetErrorStringKM(eError),
+                                                uiWrite,
+                                                uiBytesToCopy));
+                               /* Bail out as soon as we hit an error */
+                               break;
+                       }
+               }
+               else
+               {
+                       /* Ignore writes to invalid pages */
+                       uiWrite = uiBytesToCopy;
+               }
+               uiLogicalOffset += uiWrite;
+               uiBytesCopied += uiWrite;
+       }
+
+       *puiNumBytes = uiBytesCopied;
+    return eError;
+}
+
+IMG_VOID
+PMRRefPMR(PMR *psPMR)
+{
+       PVR_ASSERT(psPMR != IMG_NULL);
+       _Ref(psPMR);
+}
+
+PVRSRV_ERROR
+PMRUnrefPMR(PMR *psPMR)
+{
+    _UnrefAndMaybeDestroy(psPMR);
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMR_Flags(const PMR *psPMR,
+          PMR_FLAGS_T *puiPMRFlags)
+{
+    PVR_ASSERT(psPMR != IMG_NULL);
+
+    *puiPMRFlags = psPMR->uiFlags;
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMR_LogicalSize(const PMR *psPMR,
+                               IMG_DEVMEM_SIZE_T *puiLogicalSize)
+{
+       PVR_ASSERT(psPMR != IMG_NULL);
+
+    *puiLogicalSize = psPMR->uiLogicalSize;
+    return PVRSRV_OK;
+}
+
+/* must have called PMRLockSysPhysAddresses() before calling this! */
+PVRSRV_ERROR
+PMR_DevPhysAddr(const PMR *psPMR,
+                               IMG_UINT32 ui32Log2PageSize,
+                               IMG_UINT32 ui32NumOfPages,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_DEV_PHYADDR *psDevAddrPtr,
+                IMG_BOOL *pbValid)
+{
+       IMG_UINT32 ui32Remain;  
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    IMG_DEVMEM_OFFSET_T auiPhysicalOffset[PMR_MAX_TRANSLATION_STACK_ALLOC];
+    IMG_DEVMEM_OFFSET_T *puiPhysicalOffset = auiPhysicalOffset;
+
+    PVR_ASSERT(psPMR != IMG_NULL);
+    PVR_ASSERT(ui32NumOfPages > 0);
+    PVR_ASSERT(psPMR->psFuncTab->pfnDevPhysAddr != IMG_NULL);
+
+#ifdef PVRSRV_NEED_PVR_ASSERT
+    OSLockAcquire(psPMR->hLock);
+    PVR_ASSERT(psPMR->uiLockCount > 0);
+    OSLockRelease(psPMR->hLock);
+#endif
+
+    if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+    {
+       puiPhysicalOffset = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEVMEM_OFFSET_T));
+       if (puiPhysicalOffset == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+    }
+
+       _PMRLogicalOffsetToPhysicalOffset(psPMR,
+                                                                        ui32Log2PageSize,
+                                                                        ui32NumOfPages,
+                                                                        uiLogicalOffset,
+                                                                        puiPhysicalOffset,
+                                                                        &ui32Remain,
+                                                                        pbValid);
+       if (*pbValid || _PMRIsSparse(psPMR))
+       {
+               /* Sparse PMR may not always have the first page valid */
+               eError = psPMR->psFuncTab->pfnDevPhysAddr(psPMR->pvFlavourData,
+                                                                                                 ui32NumOfPages,
+                                                                                                 puiPhysicalOffset,
+                                                                                                 pbValid,
+                                                                                                 psDevAddrPtr);
+       }
+
+       if (puiPhysicalOffset != auiPhysicalOffset)
+       {
+               OSFreeMem(puiPhysicalOffset);
+       }
+
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMR_CpuPhysAddr(const PMR *psPMR,
+                IMG_UINT32 ui32Log2PageSize,
+                IMG_UINT32 ui32NumOfPages,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_CPU_PHYADDR *psCpuAddrPtr,
+                IMG_BOOL *pbValid)
+{
+    PVRSRV_ERROR eError;
+       IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+       IMG_DEV_PHYADDR *psDevPAddr = asDevPAddr;
+
+    if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+    {
+       psDevPAddr = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEV_PHYADDR));
+       if (psDevPAddr == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+    }
+
+    eError = PMR_DevPhysAddr(psPMR, ui32Log2PageSize, ui32NumOfPages, 
+                                                        uiLogicalOffset, psDevPAddr, pbValid);
+    if (eError != PVRSRV_OK)
+    {
+        goto e1;
+    }
+       PhysHeapDevPAddrToCpuPAddr(psPMR->psPhysHeap, ui32NumOfPages, psCpuAddrPtr, psDevPAddr);
+       
+       if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+       {
+               OSFreeMem(psDevPAddr);
+       }
+
+    return PVRSRV_OK;
+e1:
+       if (psDevPAddr != asDevPAddr)
+       {
+               OSFreeMem(psDevPAddr);
+       }
+e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+#if defined(PDUMP)
+
+static PVRSRV_ERROR
+_PMR_PDumpSymbolicAddrPhysical(const PMR *psPMR,
+                               IMG_DEVMEM_OFFSET_T uiPhysicalOffset,
+                               IMG_UINT32 ui32MemspaceNameLen,
+                               IMG_CHAR *pszMemspaceName,
+                               IMG_UINT32 ui32SymbolicAddrLen,
+                               IMG_CHAR *pszSymbolicAddr,
+                               IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                               IMG_DEVMEM_OFFSET_T *puiNextSymName)
+{
+       const IMG_CHAR *pszPrefix;
+
+    if (psPMR->psFuncTab->pfnPDumpSymbolicAddr != IMG_NULL)
+    {
+        /* defer to callback if present */
+        return psPMR->psFuncTab->pfnPDumpSymbolicAddr(psPMR->pvFlavourData,
+                                                      uiPhysicalOffset,
+                                                      pszMemspaceName,
+                                                      ui32MemspaceNameLen,
+                                                      pszSymbolicAddr,
+                                                      ui32SymbolicAddrLen,
+                                                      puiNewOffset,
+                                                      puiNextSymName);
+    }
+    else
+    {
+        OSSNPrintf(pszMemspaceName, ui32MemspaceNameLen, "%s",
+                   psPMR->pszPDumpDefaultMemspaceName);
+
+        if (psPMR->pszPDumpFlavour != IMG_NULL)
+        {
+            pszPrefix = psPMR->pszPDumpFlavour;
+        }
+        else
+        {
+            pszPrefix = PMR_DEFAULT_PREFIX;
+        }
+        OSSNPrintf(pszSymbolicAddr, ui32SymbolicAddrLen, PMR_SYMBOLICADDR_FMTSPEC,
+                   pszPrefix, psPMR->uiSerialNum);
+        *puiNewOffset = uiPhysicalOffset;
+        *puiNextSymName = (IMG_DEVMEM_OFFSET_T) psPMR->uiLogicalSize;
+
+        return PVRSRV_OK;
+    }
+}
+
+
+PVRSRV_ERROR
+PMR_PDumpSymbolicAddr(const PMR *psPMR,
+                      IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                      IMG_UINT32 ui32MemspaceNameLen,
+                      IMG_CHAR *pszMemspaceName,
+                      IMG_UINT32 ui32SymbolicAddrLen,
+                      IMG_CHAR *pszSymbolicAddr,
+                      IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                      IMG_DEVMEM_OFFSET_T *puiNextSymName
+                      )
+{
+    IMG_DEVMEM_OFFSET_T uiPhysicalOffset;
+    IMG_UINT32 ui32Remain;
+    IMG_BOOL bValid;
+
+    PVR_ASSERT(uiLogicalOffset < psPMR->uiLogicalSize);
+
+    _PMRLogicalOffsetToPhysicalOffset(psPMR,
+                                                                     0,
+                                                                     1,
+                                                                     uiLogicalOffset,
+                                                                     &uiPhysicalOffset,
+                                                                     &ui32Remain,
+                                                                     &bValid);
+
+       if (!bValid)
+       {
+               /* We should never be asked a symbolic address of an invalid chunk */
+               return PVRSRV_ERROR_PMR_INVALID_CHUNK;
+       }
+
+       return _PMR_PDumpSymbolicAddrPhysical(psPMR,
+                                                                                 uiPhysicalOffset,
+                                                                                 ui32MemspaceNameLen,
+                                                                                 pszMemspaceName,
+                                                                                 ui32SymbolicAddrLen,
+                                                                                 pszSymbolicAddr,
+                                                                                 puiNewOffset,
+                                                                                 puiNextSymName);
+}
+
+/*!
+ * @brief Writes a WRW command to the script2 buffer, representing a
+ *               dword write to a physical allocation. Size is always
+ *               sizeof(IMG_UINT32).
+ * @param psPMR - PMR object representing allocation
+ * @param uiLogicalOffset - offset
+ * @param ui32Value - value to write
+ * @param uiPDumpFlags - pdump flags
+ * @return PVRSRV_ERROR
+ */
+PVRSRV_ERROR
+PMRPDumpLoadMemValue32(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT32 ui32Value,
+                     PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
+    IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+    IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    PVR_ASSERT(uiLogicalOffset + sizeof(IMG_UINT32) <= psPMR->uiLogicalSize);
+
+    eError = PMRLockSysPhysAddresses(psPMR,
+                                     psPMR->uiLog2ContiguityGuarantee);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Get the symbolic address of the PMR */
+       eError = PMR_PDumpSymbolicAddr(psPMR,
+                                                                  uiLogicalOffset,
+                                                                  sizeof(aszMemspaceName),
+                                                                  &aszMemspaceName[0],
+                                                                  sizeof(aszSymbolicName),
+                                                                  &aszSymbolicName[0],
+                                                                  &uiPDumpSymbolicOffset,
+                                                  &uiNextSymName);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Write the WRW script command */
+       eError = PDumpPMRWRW32(aszMemspaceName,
+                                                aszSymbolicName,
+                                                uiPDumpSymbolicOffset,
+                                                ui32Value,
+                                                uiPDumpFlags);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+    eError = PMRUnlockSysPhysAddresses(psPMR);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    return PVRSRV_OK;
+}
+
+/*!
+ * @brief Writes a WRW64 command to the script2 buffer, representing a
+ *               dword write to a physical allocation. Size is always
+ *               sizeof(IMG_UINT64).
+ * @param psPMR - PMR object representing allocation
+ * @param uiLogicalOffset - offset
+ * @param ui64Value - value to write
+ * @param uiPDumpFlags - pdump flags
+ * @return PVRSRV_ERROR
+ */
+PVRSRV_ERROR
+PMRPDumpLoadMemValue64(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT64 ui64Value,
+                     PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
+    IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+    IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    PVR_ASSERT(uiLogicalOffset + sizeof(IMG_UINT64) <= psPMR->uiLogicalSize);
+
+    eError = PMRLockSysPhysAddresses(psPMR,
+                                     psPMR->uiLog2ContiguityGuarantee);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Get the symbolic address of the PMR */
+       eError = PMR_PDumpSymbolicAddr(psPMR,
+                                                                  uiLogicalOffset,
+                                                                  sizeof(aszMemspaceName),
+                                                                  &aszMemspaceName[0],
+                                                                  sizeof(aszSymbolicName),
+                                                                  &aszSymbolicName[0],
+                                                                  &uiPDumpSymbolicOffset,
+                                                  &uiNextSymName);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Write the WRW script command */
+       eError = PDumpPMRWRW64(aszMemspaceName,
+                                                aszSymbolicName,
+                                                uiPDumpSymbolicOffset,
+                                                ui64Value,
+                                                uiPDumpFlags);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+    eError = PMRUnlockSysPhysAddresses(psPMR);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    return PVRSRV_OK;
+}
+
+/*!
+ * @brief PDumps the contents of the given allocation.
+ * If bZero is IMG_TRUE then the zero page in the parameter stream is used
+ * as the source of data, rather than the allocation's actual backing.
+ * @param psPMR - PMR object representing allocation
+ * @param uiLogicalOffset - Offset to write at
+ * @param uiSize - Number of bytes to write
+ * @param uiPDumpFlags - PDump flags
+ * @param bZero - Use the PDump zero page as the source
+ * @return PVRSRV_ERROR
+ */
+PVRSRV_ERROR
+PMRPDumpLoadMem(PMR *psPMR,
+                                       IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                                       IMG_DEVMEM_SIZE_T uiSize,
+                                       PDUMP_FLAGS_T uiPDumpFlags,
+                                       IMG_BOOL bZero)
+{
+       /* common variables */
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
+       IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+       IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
+       PDUMP_FILEOFFSET_T uiParamStreamFileOffset;
+       IMG_SIZE_T uiBufSz;
+       IMG_SIZE_T uiNumBytes;
+       IMG_DEVMEM_OFFSET_T uiNextSymName;
+       const IMG_CHAR *pszParamStreamFileName;
+
+       /* required when !bZero */
+       #define PMR_MAX_PDUMP_BUFSZ 16384
+       IMG_CHAR aszParamStreamFilename[PMR_MAX_PARAMSTREAM_FILENAME_LENGTH_DEFAULT];
+       IMG_UINT8 *pcBuffer = IMG_NULL;
+
+       PVR_ASSERT(uiLogicalOffset + uiSize <= psPMR->uiLogicalSize);
+
+       if(bZero)
+       {
+               /* Check if this PMR needs to be persistent:
+                * If the allocation is persistent then it will be present in every
+                * pdump stream after its allocation. We must ensure the zeroing is also
+                * persistent so that every PDump MALLOC is accompanied by the initialisation
+                * to zero.
+                */
+               if(psPMR->bForcePersistent)
+               {
+                       uiPDumpFlags = PDUMP_FLAGS_PERSISTENT;
+               }
+
+               PDumpCommentWithFlags(uiPDumpFlags, "Zeroing allocation (%llu bytes)",
+                                                                               (unsigned long long) uiSize);
+
+               /* get the zero page information. it is constant for this function */
+               PDumpGetParameterZeroPageInfo(&uiParamStreamFileOffset, &uiBufSz, &pszParamStreamFileName);
+       }
+       else
+       {
+               uiBufSz = PMR_MAX_PDUMP_BUFSZ;
+               if (uiBufSz > uiSize)
+               {
+                       uiBufSz = TRUNCATE_64BITS_TO_SIZE_T(uiSize);
+               }
+
+               pcBuffer = OSAllocMem(uiBufSz);
+               PVR_ASSERT(pcBuffer != IMG_NULL);
+
+               eError = PMRLockSysPhysAddresses(psPMR,
+                                                               psPMR->uiLog2ContiguityGuarantee);
+               PVR_ASSERT(eError == PVRSRV_OK);
+
+               pszParamStreamFileName = aszParamStreamFilename;
+       }
+
+       while (uiSize > 0)
+       {
+               IMG_DEVMEM_OFFSET_T uiPhysicalOffset;
+               IMG_UINT32 ui32Remain;
+               IMG_BOOL bValid;
+
+               _PMRLogicalOffsetToPhysicalOffset(psPMR,
+                                                                                 0,
+                                                                                 1,
+                                                                                 uiLogicalOffset,
+                                                                                 &uiPhysicalOffset,
+                                                                                 &ui32Remain,
+                                                                                 &bValid);
+
+               if (bValid)
+               {
+                       eError = _PMR_PDumpSymbolicAddrPhysical(psPMR,
+                                                                                                       uiPhysicalOffset,
+                                                                                                       sizeof(aszMemspaceName),
+                                                                                                       &aszMemspaceName[0],
+                                                                                                       sizeof(aszSymbolicName),
+                                                                                                       &aszSymbolicName[0],
+                                                                                                       &uiPDumpSymbolicOffset,
+                                                                                                       &uiNextSymName);
+                       if(eError != PVRSRV_OK)
+                       {
+                               goto err_unlock_phys;
+                       }
+
+                       if(bZero)
+                       {
+                               uiNumBytes = TRUNCATE_64BITS_TO_SIZE_T(MIN(uiSize, uiBufSz));
+                       }
+                       else
+                       {
+
+                               /* Reads enough to fill buffer, or until next chunk,
+                               or until end of PMR, whichever comes first */
+                               eError = _PMR_ReadBytesPhysical(psPMR,
+                                                                                               uiPhysicalOffset,
+                                                                                               pcBuffer,
+                                                                                               TRUNCATE_64BITS_TO_SIZE_T(MIN3(uiBufSz, uiSize, ui32Remain)),
+                                                                                               &uiNumBytes);
+                               if(eError != PVRSRV_OK)
+                               {
+                                   goto err_unlock_phys;
+                               }
+                               PVR_ASSERT(uiNumBytes > 0);
+
+                               eError = PDumpWriteBuffer(pcBuffer,
+                                                         uiNumBytes,
+                                                         uiPDumpFlags,
+                                                         &aszParamStreamFilename[0],
+                                                         sizeof(aszParamStreamFilename),
+                                                         &uiParamStreamFileOffset);
+                               if(eError != PVRSRV_OK)
+                               {
+                                   goto err_unlock_phys;
+                               }
+                       }
+
+                       eError = PDumpPMRLDB(aszMemspaceName,
+                                                                       aszSymbolicName,
+                                                                       uiPDumpSymbolicOffset,
+                                                                       uiNumBytes,
+                                                                       pszParamStreamFileName,
+                                                                       uiParamStreamFileOffset,
+                                                                       uiPDumpFlags);
+
+                       if(eError != PVRSRV_OK)
+                       {
+                               goto err_unlock_phys;
+                       }
+               }
+               else
+               {
+                       /* Skip over invalid chunks */
+                       uiNumBytes = TRUNCATE_64BITS_TO_SIZE_T(MIN(ui32Remain, uiSize));
+               }
+
+                uiLogicalOffset += uiNumBytes;
+                PVR_ASSERT(uiNumBytes <= uiSize);
+                uiSize -= uiNumBytes;
+       }
+
+err_unlock_phys:
+
+       if(!bZero)
+       {
+           eError = PMRUnlockSysPhysAddresses(psPMR);
+           PVR_ASSERT(eError == PVRSRV_OK);
+
+           OSFreeMem(pcBuffer);
+       }
+    return eError;
+}
+
+
+
+PVRSRV_ERROR
+PMRPDumpSaveToFile(const PMR *psPMR,
+                   IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   IMG_UINT32 uiArraySize,
+                   const IMG_CHAR *pszFilename)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
+    IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+    IMG_DEVMEM_OFFSET_T uiOutOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    PVR_UNREFERENCED_PARAMETER(uiArraySize);
+
+    PVR_ASSERT(uiLogicalOffset + uiSize <= psPMR->uiLogicalSize);
+
+    eError = PMR_PDumpSymbolicAddr(psPMR,
+                                   uiLogicalOffset,
+                                   sizeof(aszMemspaceName),
+                                   &aszMemspaceName[0],
+                                   sizeof(aszSymbolicName),
+                                   &aszSymbolicName[0],
+                                   &uiOutOffset,
+                                  &uiNextSymName);
+    PVR_ASSERT(eError == PVRSRV_OK);
+    PVR_ASSERT(uiLogicalOffset + uiSize <= uiNextSymName);
+
+    eError = PDumpPMRSAB(aszMemspaceName,
+                         aszSymbolicName,
+                         uiOutOffset,
+                         uiSize,
+                         pszFilename,
+                         0);
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+    return PVRSRV_OK;
+}
+#endif /* PDUMP */
+
+/*
+   FIXME: Find a better way to do this
+ */
+
+IMG_VOID *PMRGetPrivateDataHack(const PMR *psPMR,
+                                const PMR_IMPL_FUNCTAB *psFuncTab)
+{
+    PVR_ASSERT(psFuncTab == psPMR->psFuncTab);
+
+    return psPMR->pvFlavourData;
+}
+
+PVRSRV_ERROR
+PMRWritePMPageList(/* Target PMR, offset, and length */
+                   PMR *psPageListPMR,
+                   IMG_DEVMEM_OFFSET_T uiTableOffset,
+                   IMG_DEVMEM_SIZE_T  uiTableLength,
+                   /* Referenced PMR, and "page" granularity */
+                   PMR *psReferencePMR,
+                   IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
+                   PMR_PAGELIST **ppsPageList,
+                   IMG_UINT64 *pui64CheckSum)
+{
+    PVRSRV_ERROR eError;
+    IMG_DEVMEM_SIZE_T uiWordSize;
+    IMG_UINT32 uiNumPages;
+    IMG_UINT32 uiPageIndex;
+    IMG_UINT32 ui32CheckSumXor = 0;
+    IMG_UINT32 ui32CheckSumAdd = 0;
+    PMR_FLAGS_T uiFlags;
+    PMR_PAGELIST *psPageList;
+#if defined(PDUMP)
+    IMG_CHAR aszTableEntryMemspaceName[100];
+    IMG_CHAR aszTableEntrySymbolicName[100];
+    IMG_DEVMEM_OFFSET_T uiTableEntryPDumpOffset;
+    IMG_CHAR aszPageMemspaceName[100];
+    IMG_CHAR aszPageSymbolicName[100];
+    IMG_DEVMEM_OFFSET_T uiPagePDumpOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+#endif
+#if !defined(NO_HARDWARE)
+    IMG_UINT32 uiPageListPageSize = 1 << psPageListPMR->uiLog2ContiguityGuarantee;
+    IMG_BOOL bPageIsMapped = IMG_FALSE;
+    IMG_UINT64 uiPageListPMRPage = 0;
+    IMG_UINT64 uiPrevPageListPMRPage = 0;
+    IMG_HANDLE hPrivData = IMG_NULL;
+    IMG_VOID *pvKernAddr = IMG_NULL;
+       IMG_DEV_PHYADDR asDevPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+       IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
+    IMG_DEV_PHYADDR *pasDevAddrPtr;
+    IMG_UINT32 *pui32DataPtr;
+    IMG_BOOL *pbPageIsValid;
+#endif
+    /* FIXME: should this be configurable? */
+    uiWordSize = 4;
+
+    /* check we're being asked to write the same number of 4-byte units as there are pages */
+    uiNumPages = (IMG_UINT32)(psReferencePMR->uiLogicalSize >> uiLog2PageSize);
+
+    if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psReferencePMR->uiLogicalSize)
+    {
+               /* Strictly speaking, it's possible to provoke this error in two ways:
+                       (i) if it's not a whole multiple of the page size; or
+                       (ii) if there are more than 4 billion pages.
+           The latter is unlikely. :)  but the check is required in order to justify the cast.
+               */
+        eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+        goto e0;
+    }
+    uiWordSize = (IMG_UINT32)uiTableLength / uiNumPages;
+    if (uiNumPages * uiWordSize != uiTableLength)
+    {
+        eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+        goto e0;
+    }
+
+    /* Check we're not being asked to write off the end of the PMR */
+    if (uiTableOffset + uiTableLength > psPageListPMR->uiLogicalSize)
+    {
+        /* table memory insufficient to store all the entries */
+        /* table insufficient to store addresses of whole block */
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e0;
+    }
+
+    /* the PMR into which we are writing must not be user CPU mappable: */
+    eError = PMR_Flags(psPageListPMR, &uiFlags);
+    if ((eError != PVRSRV_OK) ||
+               ((uiFlags & (PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE)) != 0))
+    {
+               PVR_DPF((PVR_DBG_ERROR, "eError = %d", eError));
+               PVR_DPF((PVR_DBG_ERROR, "masked flags = 0x%08x", (uiFlags & (PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE))));
+               PVR_DPF((PVR_DBG_ERROR, "Page list PMR allows CPU mapping (0x%08x)", uiFlags));
+               eError = PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS;
+        goto e0;
+    }
+
+       if (_PMRIsSparse(psPageListPMR))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PageList PMR is sparse"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       if (_PMRIsSparse(psReferencePMR))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Reference PMR is sparse"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       psPageList = OSAllocMem(sizeof(PMR_PAGELIST));
+       if (psPageList == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR page list"));
+               goto e0;
+       }
+       psPageList->psReferencePMR = psReferencePMR;
+
+    /* Need to lock down the physical addresses of the reference PMR */
+    /* N.B.  This also checks that the requested "contiguity" is achievable */
+    eError = PMRLockSysPhysAddresses(psReferencePMR,
+                                     uiLog2PageSize);
+    if(eError != PVRSRV_OK)
+    {
+        goto e1;
+    }
+
+#if !defined(NO_HARDWARE)
+    if (uiNumPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+       {
+           pasDevAddrPtr = OSAllocMem(uiNumPages * sizeof(IMG_DEV_PHYADDR));
+               if (pasDevAddrPtr == IMG_NULL)
+               {
+                        PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR page list"));
+                        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                        goto e2;
+               }
+
+               pbPageIsValid = OSAllocMem(uiNumPages * sizeof(IMG_BOOL));
+               if (pbPageIsValid == IMG_NULL)
+               {
+                       /* Clean-up before exit */
+                        OSFreeMem(pasDevAddrPtr);
+
+                        PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR page state"));
+                        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                        goto e2;
+               }
+       }
+       else
+       {
+               pasDevAddrPtr = asDevPAddr;
+               pbPageIsValid = abValid;
+       }
+       
+       
+       eError = PMR_DevPhysAddr(psReferencePMR, uiLog2PageSize, uiNumPages, 0,
+                                                        pasDevAddrPtr, pbPageIsValid);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to map PMR pages into device physical addresses"));
+               goto e3;
+       }       
+#endif
+
+    for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++)
+    {
+#if !defined(NO_HARDWARE)
+        IMG_DEV_PHYADDR sOldDevAddrPtr = {1}; //Set to non-aligned non-valid page
+#endif
+        IMG_DEVMEM_OFFSET_T uiPMROffset = uiTableOffset + (uiWordSize * uiPageIndex);
+#if defined(PDUMP)
+        eError = PMR_PDumpSymbolicAddr(psPageListPMR,
+                                       uiPMROffset,
+                                       sizeof(aszTableEntryMemspaceName),
+                                       &aszTableEntryMemspaceName[0],
+                                       sizeof(aszTableEntrySymbolicName),
+                                       &aszTableEntrySymbolicName[0],
+                                       &uiTableEntryPDumpOffset,
+                                       &uiNextSymName);
+        PVR_ASSERT(eError == PVRSRV_OK);
+
+        eError = PMR_PDumpSymbolicAddr(psReferencePMR,
+                                       (IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize,
+                                       sizeof(aszPageMemspaceName),
+                                       &aszPageMemspaceName[0],
+                                       sizeof(aszPageSymbolicName),
+                                       &aszPageSymbolicName[0],
+                                       &uiPagePDumpOffset,
+                                       &uiNextSymName);
+        PVR_ASSERT(eError == PVRSRV_OK);
+
+        eError = PDumpWriteShiftedMaskedValue(/* destination */
+                                              aszTableEntryMemspaceName,
+                                              aszTableEntrySymbolicName,
+                                              uiTableEntryPDumpOffset,
+                                              /* source */
+                                              aszPageMemspaceName,
+                                              aszPageSymbolicName,
+                                              uiPagePDumpOffset,
+                                              /* shift right */
+                                              uiLog2PageSize,
+                                              /* shift left */
+                                              0,
+                                              /* mask */
+                                              0xffffffff,
+                                              /* word size */
+                                              uiWordSize,
+                                              /* flags */
+                                              PDUMP_FLAGS_CONTINUOUS);
+        PVR_ASSERT(eError == PVRSRV_OK);
+#else
+               PVR_UNREFERENCED_PARAMETER(uiPMROffset);
+#endif
+#if !defined(NO_HARDWARE)
+
+               /*
+                       We check for sparse PMR's at function entry, but as we can,
+                       check that every page is valid
+               */
+               PVR_ASSERT(pbPageIsValid[uiPageIndex]);
+
+        uiPageListPMRPage = uiPMROffset >> psReferencePMR->uiLog2ContiguityGuarantee;
+
+        if ((bPageIsMapped == IMG_FALSE) || (uiPageListPMRPage != uiPrevPageListPMRPage))
+        {
+            IMG_SIZE_T uiMappingOffset = uiPMROffset & (~(uiPageListPageSize - 1));
+            IMG_SIZE_T uiMappedSize;
+
+            if (bPageIsMapped == IMG_TRUE)
+            {
+                PMRReleaseKernelMappingData(psPageListPMR, hPrivData);
+            }
+
+            eError = PMRAcquireKernelMappingData(psPageListPMR,
+                                                 uiMappingOffset,
+                                                 uiPageListPageSize,
+                                                 &pvKernAddr,
+                                                 &uiMappedSize,
+                                                 &hPrivData);
+            if (eError != PVRSRV_OK)
+            {
+                PVR_DPF((PVR_DBG_ERROR, "Error mapping page list PMR page (%llu) into kernel (%d)",
+                         uiPageListPMRPage, eError));
+                goto e3;
+            }
+
+            bPageIsMapped = IMG_TRUE;
+            uiPrevPageListPMRPage = uiPageListPMRPage;
+            PVR_ASSERT(uiMappedSize >= uiPageListPageSize);
+            PVR_ASSERT(pvKernAddr != IMG_NULL);
+        }
+
+        PVR_ASSERT(((pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize) & 0xFFFFFFFF00000000ll) == 0);
+
+        /* Write the physcial page index into the page list PMR */
+        pui32DataPtr = (IMG_UINT32 *) (((IMG_CHAR *) pvKernAddr) + (uiPMROffset & (uiPageListPageSize - 1)));
+        *pui32DataPtr = TRUNCATE_64BITS_TO_32BITS(pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize);
+        ui32CheckSumXor ^= TRUNCATE_64BITS_TO_32BITS(pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize);
+        ui32CheckSumAdd += TRUNCATE_64BITS_TO_32BITS(pasDevAddrPtr[uiPageIndex].uiAddr >> uiLog2PageSize);
+        PVR_ASSERT(pasDevAddrPtr[uiPageIndex].uiAddr != 0);
+        PVR_ASSERT(pasDevAddrPtr[uiPageIndex].uiAddr != sOldDevAddrPtr.uiAddr);
+        sOldDevAddrPtr.uiAddr = pasDevAddrPtr[uiPageIndex].uiAddr;
+        /* Last page so unmap */
+        if (uiPageIndex == (uiNumPages - 1))
+        {
+            PMRReleaseKernelMappingData(psPageListPMR, hPrivData);
+        }
+#endif
+    }
+
+#if !defined(NO_HARDWARE)
+    if (pasDevAddrPtr != asDevPAddr)
+       {
+               OSFreeMem(pbPageIsValid);
+               OSFreeMem(pasDevAddrPtr);
+       }
+#endif
+    *pui64CheckSum = ((IMG_UINT64)ui32CheckSumXor << 32) | ui32CheckSumAdd;
+    *ppsPageList = psPageList;
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+#if !defined(NO_HARDWARE)
+e3: 
+    if (pasDevAddrPtr != asDevPAddr)
+       {
+               OSFreeMem(pbPageIsValid);  
+               OSFreeMem(pasDevAddrPtr);
+       }
+ e2:
+   PMRUnlockSysPhysAddresses(psReferencePMR);
+#endif
+ e1:
+       OSFreeMem(psPageList);
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+
+PVRSRV_ERROR /* FIXME: should be IMG_VOID */
+PMRUnwritePMPageList(PMR_PAGELIST *psPageList)
+{
+    PVRSRV_ERROR eError2;
+
+    eError2 = PMRUnlockSysPhysAddresses(psPageList->psReferencePMR);
+    PVR_ASSERT(eError2 == PVRSRV_OK);
+       OSFreeMem(psPageList);
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRZeroingPMR(PMR *psPMR,
+                               IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize)
+{
+    IMG_UINT32 uiNumPages;
+    IMG_UINT32 uiPageIndex;
+    IMG_UINT32 ui32PageSize = 1 << uiLog2PageSize;
+    IMG_HANDLE hPrivData = IMG_NULL;
+    IMG_VOID *pvKernAddr = IMG_NULL;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    IMG_SIZE_T uiMapedSize;
+
+    PVR_ASSERT(psPMR);
+
+    /* Calculate number of pages in this PMR */
+       uiNumPages = (IMG_UINT32)(psPMR->uiLogicalSize >> uiLog2PageSize);
+
+       /* Verify the logical Size is a multiple or the physical page size */
+    if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psPMR->uiLogicalSize)
+    {
+               PVR_DPF((PVR_DBG_ERROR, "PMRZeroingPMR: PMR is not a multiple of %u",ui32PageSize));
+        eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+        goto MultiPage_Error;
+    }
+
+       if (_PMRIsSparse(psPMR))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PMRZeroingPMR: PMR is sparse"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto Sparse_Error;
+       }
+
+       /* Scan through all pages of the PMR */
+    for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++)
+    {
+        /* map the physical page (for a given PMR offset) into kernel space */
+        eError = PMRAcquireKernelMappingData(psPMR,
+                                             (IMG_SIZE_T)uiPageIndex << uiLog2PageSize,
+                                             ui32PageSize,
+                                             &pvKernAddr,
+                                             &uiMapedSize,
+                                             &hPrivData);
+        if (eError != PVRSRV_OK)
+        {
+               PVR_DPF((PVR_DBG_ERROR, "PMRZeroingPMR: AcquireKernelMapping failed with error %u", eError));
+               goto AcquireKernelMapping_Error;
+        }
+
+        /* ensure the mapped page size is the same as the physical page size */
+        if (uiMapedSize != ui32PageSize)
+        {
+               PVR_DPF((PVR_DBG_ERROR, "PMRZeroingPMR: Physical Page size = 0x%08x, Size of Mapping = 0x%016llx",
+                                                               ui32PageSize,
+                                                               (IMG_UINT64)uiMapedSize));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto MappingSize_Error;
+        }
+
+        /* zeroing page content */
+        OSMemSet(pvKernAddr, 0, ui32PageSize);
+
+        /* release mapping */
+        PMRReleaseKernelMappingData(psPMR, hPrivData);
+
+    }
+
+    PVR_DPF((PVR_DBG_WARNING,"PMRZeroingPMR: Zeroing PMR %p done (num pages %u, page size %u)",
+                                               psPMR,
+                                               uiNumPages,
+                                               ui32PageSize));
+
+    return PVRSRV_OK;
+
+
+    /* Error handling */
+
+MappingSize_Error:
+       PMRReleaseKernelMappingData(psPMR, hPrivData);
+
+AcquireKernelMapping_Error:
+Sparse_Error:
+MultiPage_Error:
+
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMRDumpPageList(PMR *psPMR,
+                                       IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize)
+{
+    IMG_DEV_PHYADDR sDevAddrPtr;
+    IMG_UINT32 uiNumPages;
+    IMG_UINT32 uiPageIndex;
+    IMG_BOOL bPageIsValid;
+    IMG_UINT32 ui32Col = 16;
+    IMG_UINT32 ui32SizePerCol = 11;
+    IMG_UINT32 ui32ByteCount = 0;
+    IMG_CHAR pszBuffer[16 /* ui32Col */ * 11 /* ui32SizePerCol */ + 1];
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    /* Get number of pages */
+       uiNumPages = (IMG_UINT32)(psPMR->uiLogicalSize >> uiLog2PageSize);
+
+       /* Verify the logical Size is a multiple or the physical page size */
+    if ((PMR_SIZE_T)uiNumPages << uiLog2PageSize != psPMR->uiLogicalSize)
+    {
+               PVR_DPF((PVR_DBG_ERROR, "PMRPrintPageList: PMR is not a multiple of %u", 1 << uiLog2PageSize));
+        eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+        goto MultiPage_Error;
+    }
+
+       if (_PMRIsSparse(psPMR))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PMRPrintPageList: PMR is sparse"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto Sparse_Error;
+       }
+
+       PVR_LOG(("    PMR %p, Number of pages %u, Log2PageSize %d", psPMR, uiNumPages, uiLog2PageSize));
+
+       /* Print the address of the physical pages */
+    for (uiPageIndex = 0; uiPageIndex < uiNumPages; uiPageIndex++)
+    {
+       /* Get Device physical Address */
+        eError = PMR_DevPhysAddr(psPMR,
+                        uiLog2PageSize,
+                        1,
+                        (IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize,
+                        &sDevAddrPtr,
+                        &bPageIsValid);
+        if (eError != PVRSRV_OK)
+        {
+               PVR_DPF((PVR_DBG_ERROR, "PMRPrintPageList: PMR %p failed to get DevPhysAddr with error %u",
+                                                               psPMR,
+                                                               eError));
+               goto DevPhysAddr_Error;
+        }
+
+        ui32ByteCount += OSSNPrintf(pszBuffer + ui32ByteCount, ui32SizePerCol + 1, "%08x ", (IMG_UINT32)(sDevAddrPtr.uiAddr >> uiLog2PageSize));
+        PVR_ASSERT(ui32ByteCount < ui32Col * ui32SizePerCol);
+
+               if (uiPageIndex % ui32Col == ui32Col -1)
+               {
+                       PVR_LOG(("      Phys Page: %s", pszBuffer));
+                       ui32ByteCount = 0;
+               }
+    }
+    if (ui32ByteCount > 0)
+    {
+               PVR_LOG(("      Phys Page: %s", pszBuffer));
+    }
+
+    return PVRSRV_OK;
+
+    /* Error handling */
+DevPhysAddr_Error:
+Sparse_Error:
+MultiPage_Error:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+#if defined(PDUMP)
+extern PVRSRV_ERROR
+PMRPDumpPol32(const PMR *psPMR,
+              IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+              IMG_UINT32 ui32Value,
+              IMG_UINT32 ui32Mask,
+              PDUMP_POLL_OPERATOR eOperator,
+              PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszMemspaceName[100];
+    IMG_CHAR aszSymbolicName[100];
+    IMG_DEVMEM_OFFSET_T uiPDumpOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    eError = PMR_PDumpSymbolicAddr(psPMR,
+                                   uiLogicalOffset,
+                                   sizeof(aszMemspaceName),
+                                   &aszMemspaceName[0],
+                                   sizeof(aszSymbolicName),
+                                   &aszSymbolicName[0],
+                                   &uiPDumpOffset,
+                                  &uiNextSymName);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+#define _MEMPOLL_DELAY         (1000)
+#define _MEMPOLL_COUNT         (2000000000 / _MEMPOLL_DELAY)
+
+    eError = PDumpPMRPOL(aszMemspaceName,
+                         aszSymbolicName,
+                         uiPDumpOffset,
+                         ui32Value,
+                         ui32Mask,
+                         eOperator,
+                         _MEMPOLL_COUNT,
+                         _MEMPOLL_DELAY,
+                         uiPDumpFlags);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PMRPDumpCBP(const PMR *psPMR,
+            IMG_DEVMEM_OFFSET_T uiReadOffset,
+            IMG_DEVMEM_OFFSET_T uiWriteOffset,
+            IMG_DEVMEM_SIZE_T uiPacketSize,
+            IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+    PVRSRV_ERROR eError;
+    IMG_CHAR aszMemspaceName[100];
+    IMG_CHAR aszSymbolicName[100];
+    IMG_DEVMEM_OFFSET_T uiPDumpOffset;
+    IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+    eError = PMR_PDumpSymbolicAddr(psPMR,
+                                   uiReadOffset,
+                                   sizeof(aszMemspaceName),
+                                   &aszMemspaceName[0],
+                                   sizeof(aszSymbolicName),
+                                   &aszSymbolicName[0],
+                                   &uiPDumpOffset,
+                                   &uiNextSymName);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    eError = PDumpPMRCBP(aszMemspaceName,
+                         aszSymbolicName,
+                         uiPDumpOffset,
+                         uiWriteOffset,
+                         uiPacketSize,
+                         uiBufferSize);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+#endif
+
+PVRSRV_ERROR
+PMRInit()
+{
+       PVRSRV_ERROR eError;
+
+    if (_gsSingletonPMRContext.bModuleInitialised)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "pmr.c:  oops, already initialized"));
+        return PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR;
+    }
+
+       eError = OSLockCreate(&_gsSingletonPMRContext.hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = OSLockCreate(&gGlobalLookupPMRLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+    _gsSingletonPMRContext.uiNextSerialNum = 1;
+
+    _gsSingletonPMRContext.uiNextKey = 0x8300f001 * (IMG_UINTPTR_T)&_gsSingletonPMRContext;
+
+    _gsSingletonPMRContext.bModuleInitialised = IMG_TRUE;
+
+    _gsSingletonPMRContext.uiNumLivePMRs = 0;
+
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PMRDeInit()
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+       {
+               return PVRSRV_OK;
+       }
+
+    PVR_ASSERT(_gsSingletonPMRContext.bModuleInitialised);
+    if (!_gsSingletonPMRContext.bModuleInitialised)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "pmr.c:  oops, not initialized"));
+        return PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR;
+    }
+
+    PVR_ASSERT(_gsSingletonPMRContext.uiNumLivePMRs == 0);
+    if (_gsSingletonPMRContext.uiNumLivePMRs != 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "pmr.c:  %d live PMR(s) remain(s)", _gsSingletonPMRContext.uiNumLivePMRs));
+        PVR_DPF((PVR_DBG_ERROR, "pmr.c:  This is an unrecoverable error; a subsequent crash is inevitable"));
+        return PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR;
+    }
+
+       OSLockDestroy(_gsSingletonPMRContext.hLock);
+       OSLockDestroy(gGlobalLookupPMRLock);
+
+    _gsSingletonPMRContext.bModuleInitialised = IMG_FALSE;
+
+    /*
+      FIXME:
+
+      should deinitialise the mutex here
+    */
+
+    return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/power.c b/drivers/gpu/rogue_m/services/server/common/power.c
new file mode 100644 (file)
index 0000000..94d8706
--- /dev/null
@@ -0,0 +1,1300 @@
+/*************************************************************************/ /*!
+@File           power.c
+@Title          Power management functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main APIs for power management functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pdump_km.h"
+#include "allocmem.h"
+#include "osfunc.h"
+
+#include "lists.h"
+#include "pvrsrv.h"
+#include "pvr_debug.h"
+#include "process_stats.h"
+#include "rk_init.h"
+
+static IMG_BOOL gbInitServerRunning = IMG_FALSE;
+static IMG_BOOL gbInitServerRan = IMG_FALSE;
+static IMG_BOOL gbInitSuccessful = IMG_FALSE;
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVSetInitServerState
+
+ @Description  Sets given services init state.
+
+ @Input                eInitServerState : a services init state
+ @Input                bState : a state to set
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVGetInitServerState
+
+ @Description  Tests whether a given services init state was run.
+
+ @Input                eInitServerState : a services init state
+
+ @Return       IMG_BOOL
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function     _IsSystemStatePowered
+
+ @Description  Tests whether a given system state represents powered-up.
+
+ @Input                eSystemPowerState : a system power state
+
+ @Return       IMG_BOOL
+
+******************************************************************************/
+static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
+{
+       return (eSystemPowerState == PVRSRV_SYS_POWER_STATE_ON);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVPowerLock
+
+ @Description  Obtain the mutex for power transitions. Only allowed when
+                system power is on.
+
+ @Return       PVRSRV_ERROR_RETRY or PVRSRV_OK
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPowerLock()
+{
+       PVRSRV_ERROR    eError;
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* Only allow to take powerlock when the system power is on */
+       if (_IsSystemStatePowered(psPVRSRVData->eCurrentPowerState))
+       {
+               OSLockAcquire(psPVRSRVData->hPowerLock);
+               eError = PVRSRV_OK;
+       }
+       else
+       {
+               eError = PVRSRV_ERROR_RETRY;
+       }
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVForcedPowerLock
+
+ @Description  Obtain the mutex for power transitions regardless of
+                system power state
+
+ @Return       PVRSRV_ERROR_RETRY or PVRSRV_OK
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID PVRSRVForcedPowerLock()
+{
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       OSLockAcquire(psPVRSRVData->hPowerLock);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVPowerUnlock
+
+ @Description  Release the mutex for power transitions
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID PVRSRVPowerUnlock()
+{
+       PVRSRV_DATA     *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       OSLockRelease(psPVRSRVData->hPowerLock);
+}
+IMG_EXPORT
+IMG_BOOL PVRSRVDeviceIsDefaultStateOFF(PVRSRV_POWER_DEV *psPowerDevice)
+{
+       return (psPowerDevice->eDefaultPowerState == PVRSRV_DEV_POWER_STATE_OFF);
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePrePowerStateKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required before a power transition
+
+ @Input                psPowerDevice : the device
+ @Input                va : variable argument list with:
+                               bAllDevices : IMG_TRUE - All devices
+                                                         IMG_FALSE - Use ui32DeviceIndex
+                               ui32DeviceIndex : device index
+                               eNewPowerState : New power state
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
+       PVRSRV_ERROR                    eError;
+
+       /*Variable Argument variables*/
+       IMG_BOOL                                bAllDevices;
+       IMG_UINT32                              ui32DeviceIndex;
+       PVRSRV_DEV_POWER_STATE  eNewPowerState;
+       IMG_BOOL                                bForced;
+       IMG_UINT64                              ui32SysTimer1=0, ui32SysTimer2=0, ui32DevTimer1=0, ui32DevTimer2=0;
+
+       /*WARNING! if types were not aligned to 4 bytes, this could be dangerous!!!*/
+       bAllDevices = va_arg(va, IMG_BOOL);
+       ui32DeviceIndex = va_arg(va, IMG_UINT32);
+       eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+       bForced = va_arg(va, IMG_BOOL);
+
+       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+       {
+               eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+                                                       psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+               if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+               {
+                       if (psPowerDevice->pfnDevicePrePower != IMG_NULL)
+                       {
+                               /* Call the device's power callback. */
+
+                               ui32DevTimer1=OSClockns64();
+
+                               eError = psPowerDevice->pfnDevicePrePower(psPowerDevice->hDevCookie,
+                                                                                                                       eNewDevicePowerState,
+                                                                                                                       psPowerDevice->eCurrentPowerState,
+                                                                                                                       bForced);
+
+                               ui32DevTimer2=OSClockns64();
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       return eError;
+                               }
+                       }
+
+                       /* Do any required system-layer processing. */
+                       if (psPowerDevice->pfnSystemPrePower != IMG_NULL)
+                       {
+
+                               ui32SysTimer1=OSClockus();
+
+                               eError = psPowerDevice->pfnSystemPrePower(eNewDevicePowerState,
+                                                                                                                 psPowerDevice->eCurrentPowerState,
+                                                                                                                 bForced);
+
+                               ui32SysTimer2=OSClockus();
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       return eError;
+                               }
+                       }
+               }
+       }
+
+
+    InsertPowerTimeStatistic(PVRSRV_POWER_ENTRY_TYPE_PRE,
+                       psPowerDevice->eCurrentPowerState, eNewPowerState,
+            ui32SysTimer1,ui32SysTimer2,
+                       ui32DevTimer1,ui32DevTimer2,
+                       bForced);
+
+
+       return  PVRSRV_OK;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeviceIdleKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required to force the device idle.
+
+ @Input                psPowerDevice : the device
+ @Input                va : variable argument list with:
+                               bAllDevices :   IMG_TRUE - All devices
+                                               IMG_FALSE - Use ui32DeviceIndex
+                               ui32DeviceIndex : device index
+                               pfnCheckIdleReq : Filter function used to determine whether a forced idle is required for the device
+                               bDeviceOffPermitted :   IMG_TRUE if the transition should not fail if device off
+                                                       IMG_FALSE if the transition should fail if device off
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDeviceIdleKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+       PVRSRV_ERROR                    eError = PVRSRV_OK;
+
+       /*Variable Argument variables*/
+       IMG_BOOL                                bAllDevices;
+       IMG_UINT32                              ui32DeviceIndex;
+       PFN_SYS_DEV_IS_DEFAULT_STATE_OFF        pfnIsDefaultStateOff;
+       IMG_BOOL                                bDeviceOffPermitted;
+
+       /*WARNING! if types were not aligned to 4 bytes, this could be dangerous!!!*/
+       bAllDevices = va_arg(va, IMG_BOOL);
+       ui32DeviceIndex = va_arg(va, IMG_UINT32);
+       pfnIsDefaultStateOff = va_arg(va, PFN_SYS_DEV_IS_DEFAULT_STATE_OFF);
+       bDeviceOffPermitted = va_arg(va, IMG_BOOL);
+
+       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+       {
+               if (psPowerDevice->pfnForcedIdleRequest != IMG_NULL)
+               {
+                       if ((pfnIsDefaultStateOff == IMG_NULL) || pfnIsDefaultStateOff(psPowerDevice))
+                       {
+                               eError = psPowerDevice->pfnForcedIdleRequest(psPowerDevice->hDevCookie, bDeviceOffPermitted);
+                       }
+               }
+       }
+
+       return eError;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeviceIdleRequestKM
+
+ @Description
+
+ Perform device-specific processing required to force the device idle.
+
+ @Input                bAllDevices :   IMG_TRUE - All devices
+                               IMG_FALSE - Use ui32DeviceIndex
+ @Input                ui32DeviceIndex : device index
+ @Input                pfnCheckIdleReq : Filter function used to determine whether a forced idle is required for the device
+ @Input                bDeviceOffPermitted :   IMG_TRUE if the transition should not fail if device off
+                                       IMG_FALSE if the transition should fail if device off
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVDeviceIdleRequestKM(IMG_BOOL                                        bAllDevices,
+                                       IMG_UINT32                              ui32DeviceIndex,
+                                       PFN_SYS_DEV_IS_DEFAULT_STATE_OFF        pfnIsDefaultStateOff,
+                                       IMG_BOOL                                bDeviceOffPermitted)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* Loop through the power devices. */
+       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                               &PVRSRVDeviceIdleKM_AnyVaCb,
+                                                               bAllDevices,
+                                                               ui32DeviceIndex,
+                                                               pfnIsDefaultStateOff,
+                                                               bDeviceOffPermitted);
+
+       return eError;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeviceIdleCancelKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required before a power transition
+
+ @Input                psPowerDevice : the device
+ @Input                va : variable argument list with:
+                               bAllDevices :   IMG_TRUE - All devices
+                                               IMG_FALSE - Use ui32DeviceIndex
+                               ui32DeviceIndex : device index
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDeviceIdleCancelKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+       /*Variable Argument variables*/
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       IMG_BOOL                bAllDevices;
+       IMG_UINT32              ui32DeviceIndex;
+
+       /*WARNING! if types were not aligned to 4 bytes, this could be dangerous!!!*/
+       bAllDevices = va_arg(va, IMG_BOOL);
+       ui32DeviceIndex = va_arg(va, IMG_UINT32);
+
+       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+       {
+               if (psPowerDevice->pfnForcedIdleCancelRequest != IMG_NULL)
+               {
+                       eError = psPowerDevice->pfnForcedIdleCancelRequest(psPowerDevice->hDevCookie);
+               }
+       }
+
+       return eError;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeviceIdleCancelRequestKM
+
+ @Description
+
+ Perform device-specific processing required to cancel the forced idle state on the device, returning to normal operation.
+
+ @Input                bAllDevices :   IMG_TRUE - All devices
+                               IMG_FALSE - Use ui32DeviceIndex
+ @Input                ui32DeviceIndex : device index
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVDeviceIdleCancelRequestKM(IMG_BOOL                  bAllDevices,
+                                               IMG_UINT32              ui32DeviceIndex)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* Loop through the power devices. */
+       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psPVRSRVData->psPowerDeviceList,
+                                       &PVRSRVDeviceIdleCancelKM_AnyVaCb,
+                                       bAllDevices,
+                                       ui32DeviceIndex);
+
+       return eError;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePrePowerStateKM
+
+ @Description
+
+ Perform device-specific processing required before a power transition
+
+ @Input                bAllDevices : IMG_TRUE - All devices
+                                                 IMG_FALSE - Use ui32DeviceIndex
+ @Input                ui32DeviceIndex : device index
+ @Input                eNewPowerState : New power state
+ @Input                bForced : TRUE if the transition should not fail (e.g. OS request)
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL                              bAllDevices,
+                                                                                IMG_UINT32                             ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState,
+                                                                                IMG_BOOL                               bForced)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* Loop through the power devices. */
+       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                               &PVRSRVDevicePrePowerStateKM_AnyVaCb,
+                                                                                                               bAllDevices,
+                                                                                                               ui32DeviceIndex,
+                                                                                                               eNewPowerState,
+                                                                                                               bForced);
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePostPowerStateKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required after a power transition
+
+ @Input                psPowerDevice : the device
+ @Input                va : variable argument list with:
+                               bAllDevices : IMG_TRUE - All devices
+                                                         IMG_FALSE - Use ui32DeviceIndex
+                               ui32DeviceIndex : device index
+                               eNewPowerState : New power state
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
+       PVRSRV_ERROR                    eError;
+
+       /*Variable Argument variables*/
+       IMG_BOOL                                bAllDevices;
+       IMG_UINT32                              ui32DeviceIndex;
+       PVRSRV_DEV_POWER_STATE  eNewPowerState;
+       IMG_BOOL                                bForced;
+       IMG_UINT64                              ui32SysTimer1=0, ui32SysTimer2=0, ui32DevTimer1=0, ui32DevTimer2=0;
+
+       /*WARNING! if types were not aligned to 4 bytes, this could be dangerous!!!*/
+       bAllDevices = va_arg(va, IMG_BOOL);
+       ui32DeviceIndex = va_arg(va, IMG_UINT32);
+       eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+       bForced = va_arg(va, IMG_BOOL);
+
+       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+       {
+               eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+                                                               psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+               if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+               {
+                       /* Do any required system-layer processing. */
+                       if (psPowerDevice->pfnSystemPostPower != IMG_NULL)
+                       {
+
+                               ui32SysTimer1=OSClockns64();
+
+                               eError = psPowerDevice->pfnSystemPostPower(eNewDevicePowerState,
+                                                                                                                  psPowerDevice->eCurrentPowerState,
+                                                                                                                  bForced);
+
+                               ui32SysTimer2=OSClockns64();
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       return eError;
+                               }
+                       }
+
+                       if (psPowerDevice->pfnDevicePostPower != IMG_NULL)
+                       {
+                               /* Call the device's power callback. */
+
+                               ui32DevTimer1=OSClockus();
+
+                               eError = psPowerDevice->pfnDevicePostPower(psPowerDevice->hDevCookie,
+                                                                                                                  eNewDevicePowerState,
+                                                                                                                  psPowerDevice->eCurrentPowerState,
+                                                                                                                  bForced);
+
+                               ui32DevTimer2=OSClockus();
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       return eError;
+                               }
+                       }
+
+                       psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
+               }
+       }
+
+
+    InsertPowerTimeStatistic(PVRSRV_POWER_ENTRY_TYPE_POST,
+                                                       psPowerDevice->eCurrentPowerState, eNewPowerState,
+                            ui32SysTimer1,ui32SysTimer2,
+                                                       ui32DevTimer1,ui32DevTimer2,
+                                                       bForced);
+
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePostPowerStateKM
+
+ @Description
+
+ Perform device-specific processing required after a power transition
+
+ @Input                bAllDevices : IMG_TRUE - All devices
+                                                 IMG_FALSE - Use ui32DeviceIndex
+ @Input                ui32DeviceIndex : device index
+ @Input                eNewPowerState : New power state
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL                                     bAllDevices,
+                                                                                 IMG_UINT32                            ui32DeviceIndex,
+                                                                                 PVRSRV_DEV_POWER_STATE        eNewPowerState,
+                                                                                 IMG_BOOL                                      bForced)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* Loop through the power devices. */
+       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                               &PVRSRVDevicePostPowerStateKM_AnyVaCb,
+                                                                                                               bAllDevices,
+                                                                                                               ui32DeviceIndex,
+                                                                                                               eNewPowerState,
+                                                                                                               bForced);
+
+       return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVSetDevicePowerStateKM
+
+ @Description  Set the Device into a new state
+
+ @Input                ui32DeviceIndex : device index
+ @Input                eNewPowerState : New power state
+ @Input                bForced : TRUE if the transition should not fail (e.g. OS request)
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32                            ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState,
+                                                                                IMG_BOOL                               bForced)
+{
+       PVRSRV_ERROR    eError;
+       PVRSRV_DATA*    psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEV_POWER_STATE eOldPowerState;
+
+       eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &eOldPowerState);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "PVRSRVSetDevicePowerStateKM: Couldn't read power state."));
+               eOldPowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+       }
+
+       eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);
+       if(eError != PVRSRV_OK)
+       {
+               goto Exit;
+       }
+
+       eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);
+
+       /* Signal Device Watchdog Thread about power mode change. */
+       if (eOldPowerState != eNewPowerState && eNewPowerState == PVRSRV_DEV_POWER_STATE_ON)
+       {
+               psPVRSRVData->ui32DevicesWatchdogPwrTrans++;
+
+               if (psPVRSRVData->ui32DevicesWatchdogTimeout == DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT)
+               {
+                       if (psPVRSRVData->hDevicesWatchdogEvObj)
+                       {
+                               eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj);
+                               PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+                       }
+               }
+       }
+
+Exit:
+
+       if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE,
+                               "PVRSRVSetDevicePowerStateKM : Transition to %d was denied, Forced=%d", eNewPowerState, bForced));
+       }
+       else if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING,
+                               "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED (%s)", eNewPowerState, PVRSRVGetErrorStringKM(eError)));
+       }
+       
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVSetPowerStateKM
+
+ @Description  Set the system into a new state
+
+ @Input                eNewPowerState :
+ @Input                bForced : TRUE if the transition should not fail (e.g. OS request)
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState, IMG_BOOL bForced)
+{
+       PVRSRV_ERROR    eError;
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       IMG_UINT        uiStage = 0;
+
+       PVRSRV_DEV_POWER_STATE eNewDevicePowerState = 
+         _IsSystemStatePowered(eNewSysPowerState)? PVRSRV_DEV_POWER_STATE_DEFAULT : PVRSRV_DEV_POWER_STATE_OFF;
+
+       /* require a proper power state */
+       if (eNewSysPowerState == PVRSRV_SYS_POWER_STATE_Unspecified)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Prevent simultaneous SetPowerStateKM calls */
+       PVRSRVForcedPowerLock();
+
+       /* no power transition requested, so do nothing */
+       if (eNewSysPowerState == psPVRSRVData->eCurrentPowerState)
+       {
+               PVRSRVPowerUnlock();
+               return PVRSRV_OK;
+       }
+
+       /* For a forced power down, all devices must be forced idle before being powered off */
+       if (bForced && ((eNewDevicePowerState == PVRSRV_DEV_POWER_STATE_OFF) || (eNewDevicePowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)))
+       {
+               /* If setting devices to default state, selectively force idle all devices whose default state is off */
+                PFN_SYS_DEV_IS_DEFAULT_STATE_OFF pfnIsDefaultStateOff =
+                       (eNewDevicePowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? PVRSRVDeviceIsDefaultStateOFF : IMG_NULL;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError = PVRSRVDeviceIdleRequestKM(IMG_TRUE, 0, pfnIsDefaultStateOff, IMG_TRUE);
+
+                       if (eError == PVRSRV_OK)
+                       {
+                               break;
+                       }
+                       else if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+                       {
+                               PVRSRVPowerUnlock();
+                               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+                               PVRSRVForcedPowerLock();
+                       }
+                       else
+                       {
+                               uiStage++;
+                               goto ErrorExit;
+                       }
+               } END_LOOP_UNTIL_TIMEOUT();
+       }
+
+       /* Perform pre transitions: first device and then sys layer */
+       eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced);
+       if (eError != PVRSRV_OK)
+       {
+               uiStage++;
+               goto ErrorExit;
+       }
+       eError = PVRSRVSysPrePowerState(eNewSysPowerState, bForced);
+       if (eError != PVRSRV_OK)
+       {
+               uiStage++;
+               goto ErrorExit;
+       }
+
+       /* Perform system-specific post power transitions: first sys layer and then device */
+       eError = PVRSRVSysPostPowerState(eNewSysPowerState, bForced);
+       if (eError != PVRSRV_OK)
+       {
+               uiStage++;
+               goto ErrorExit;
+       }
+       eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced);
+       if (eError != PVRSRV_OK)
+       {
+               uiStage++;
+               goto ErrorExit;
+       }
+
+       psPVRSRVData->eCurrentPowerState = eNewSysPowerState;
+       psPVRSRVData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+       PVRSRVPowerUnlock();
+
+       /*
+               Reprocess the devices' queues in case commands were blocked during
+               the power transition.
+       */
+       if (_IsSystemStatePowered(eNewSysPowerState) &&
+                       PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+       {
+               PVRSRVCheckStatus(IMG_NULL);
+       }
+
+       return PVRSRV_OK;
+
+ErrorExit:
+       /* save the power state for the re-attempt */
+       psPVRSRVData->eFailedPowerState = eNewSysPowerState;
+
+       PVRSRVPowerUnlock();
+
+       PVR_DPF((PVR_DBG_ERROR,
+                       "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED (%s) at stage %d, forced: %d. Dumping debug info.",
+                       psPVRSRVData->eCurrentPowerState, eNewSysPowerState, PVRSRVGetErrorStringKM(eError), uiStage, bForced));
+
+       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+
+       return eError;
+}
+
+
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32                                      ui32DeviceIndex,
+                                                                          PFN_PRE_POWER                                pfnDevicePrePower,
+                                                                          PFN_POST_POWER                               pfnDevicePostPower,
+                                                                          PFN_SYS_DEV_PRE_POWER                pfnSystemPrePower,
+                                                                          PFN_SYS_DEV_POST_POWER               pfnSystemPostPower,
+                                                                          PFN_PRE_CLOCKSPEED_CHANGE    pfnPreClockSpeedChange,
+                                                                          PFN_POST_CLOCKSPEED_CHANGE   pfnPostClockSpeedChange,
+                                                                          PFN_FORCED_IDLE_REQUEST      pfnForcedIdleRequest,
+                                                                          PFN_FORCED_IDLE_CANCEL_REQUEST       pfnForcedIdleCancelRequest,
+                                                                          PFN_DUST_COUNT_REQUEST       pfnDustCountRequest,
+                                                                          IMG_HANDLE                                   hDevCookie,
+                                                                          PVRSRV_DEV_POWER_STATE               eCurrentPowerState,
+                                                                          PVRSRV_DEV_POWER_STATE               eDefaultPowerState)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDevice;
+
+       if (pfnDevicePrePower == IMG_NULL &&
+               pfnDevicePostPower == IMG_NULL)
+       {
+               return PVRSRVRemovePowerDevice(ui32DeviceIndex);
+       }
+
+       psPowerDevice = OSAllocMem(sizeof(PVRSRV_POWER_DEV));
+       if (psPowerDevice == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* setup device for power manager */
+       psPowerDevice->pfnDevicePrePower = pfnDevicePrePower;
+       psPowerDevice->pfnDevicePostPower = pfnDevicePostPower;
+       psPowerDevice->pfnSystemPrePower = pfnSystemPrePower;
+       psPowerDevice->pfnSystemPostPower = pfnSystemPostPower;
+       psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
+       psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
+       psPowerDevice->pfnForcedIdleRequest = pfnForcedIdleRequest;
+       psPowerDevice->pfnForcedIdleCancelRequest = pfnForcedIdleCancelRequest;
+       psPowerDevice->pfnDustCountRequest = pfnDustCountRequest;
+       psPowerDevice->hDevCookie = hDevCookie;
+       psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
+       psPowerDevice->eCurrentPowerState = eCurrentPowerState;
+       psPowerDevice->eDefaultPowerState = eDefaultPowerState;
+
+       /* insert into power device list */
+       List_PVRSRV_POWER_DEV_Insert(&(psPVRSRVData->psPowerDeviceList), psPowerDevice);
+
+#if RK33_DVFS_SUPPORT && RK33_USE_RGX_GET_GPU_UTIL
+    //zxl:set device node to get pfnGetGpuUtilStats in rk_init.c
+    rk33_set_device_node(hDevCookie);
+#endif
+       return (PVRSRV_OK);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVRemovePowerDevice
+
+ @Description
+
+ Removes device from power management register. Device is located by Device Index
+
+ @Input                ui32DeviceIndex : device index
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDev;
+
+       /* find device in list and remove it */
+       psPowerDev = (PVRSRV_POWER_DEV*)
+                                       List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                &MatchPowerDeviceIndex_AnyVaCb,
+                                                                                                ui32DeviceIndex);
+
+       if (psPowerDev)
+       {
+               List_PVRSRV_POWER_DEV_Remove(psPowerDev);
+               OSFreeMem(psPowerDev);
+               /*not nulling pointer, copy on stack*/
+       }
+
+#if RK33_DVFS_SUPPORT && RK33_USE_RGX_GET_GPU_UTIL
+    //zxl:clear device node
+    rk33_clear_device_node();
+#endif
+
+       return (PVRSRV_OK);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVGetDevicePowerState
+
+ @Description
+
+       Return the device power state
+
+ @Input                ui32DeviceIndex : device index
+ @Output       psPowerState : Current power state 
+
+ @Return       PVRSRV_ERROR_UNKNOWN_POWER_STATE if device could not be found. PVRSRV_OK otherwise.
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDevicePowerState(IMG_UINT32 ui32DeviceIndex, PPVRSRV_DEV_POWER_STATE pePowerState)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDevice;
+
+       psPowerDevice = (PVRSRV_POWER_DEV*)
+                                       List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                &MatchPowerDeviceIndex_AnyVaCb,
+                                                                                                ui32DeviceIndex);
+       if (psPowerDevice == IMG_NULL)
+       {
+               return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+       }
+
+       *pePowerState = psPowerDevice->eCurrentPowerState;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVIsDevicePowered
+
+ @Description
+
+       Whether the device is powered, for the purposes of lockup detection.
+
+ @Input                ui32DeviceIndex : device index
+
+ @Return       IMG_BOOL
+
+******************************************************************************/
+IMG_EXPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
+{
+       PVRSRV_DATA            *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEV_POWER_STATE ePowerState;
+
+       if (OSLockIsLocked(psPVRSRVData->hPowerLock))
+       {
+               return IMG_FALSE;
+       }
+
+       if (PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState) != PVRSRV_OK)
+       {
+               return IMG_FALSE;
+       }
+
+       return (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePreClockSpeedChange
+
+ @Description
+
+       Notification from system layer that a device clock speed change is about to happen.
+
+ @Input                ui32DeviceIndex : device index
+ @Input                bIdleDevice : whether the device should be idled
+ @Input                pvInfo
+
+ @Return       IMG_VOID
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32        ui32DeviceIndex,
+                                                                                        IMG_BOOL       bIdleDevice,
+                                                                                        IMG_VOID       *pvInfo)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDevice;
+       IMG_UINT64                      ui64StartTimer, ui64StopTimer;
+
+       PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+       ui64StartTimer = OSClockus();
+
+       /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */
+       eError = PVRSRVPowerLock();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
+               return eError;
+       }
+
+       /*search the device and then do the pre clock speed change*/
+       psPowerDevice = (PVRSRV_POWER_DEV*)
+                                       List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                &MatchPowerDeviceIndex_AnyVaCb,
+                                                                                                ui32DeviceIndex);
+
+
+       if (psPowerDevice)
+       {
+               if ((psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) && bIdleDevice)
+               {
+                       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+                       {       /* We can change the clock speed if the device is either IDLE or OFF */
+                               eError = PVRSRVDeviceIdleRequestKM(IMG_FALSE, ui32DeviceIndex, IMG_NULL, IMG_TRUE);
+
+                               if (eError == PVRSRV_OK)
+                               {
+                                       break;
+                               }
+                               else if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+                               {
+                                       PVRSRV_ERROR    eError2;
+
+                                       PVRSRVPowerUnlock();
+                                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+                                       eError2 = PVRSRVPowerLock();
+
+                                       if (eError2 != PVRSRV_OK)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
+                                               return eError2;
+                                       }
+                               }
+                               else
+                               {
+                                       PVRSRVPowerUnlock();
+                                       return eError;
+                               }
+                       } END_LOOP_UNTIL_TIMEOUT();
+               }
+
+               eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
+                                                                                                          psPowerDevice->eCurrentPowerState);
+
+               if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED))
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                       "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
+                                       ui32DeviceIndex, eError));
+               }
+       }
+
+       if (eError != PVRSRV_OK)
+       {
+               PVRSRVPowerUnlock();
+               return eError;
+       }
+
+       ui64StopTimer = OSClockus();
+
+       InsertPowerTimeStatisticExtraPre(ui64StartTimer, ui64StopTimer);
+
+       return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDevicePostClockSpeedChange
+
+ @Description
+
+       Notification from system layer that a device clock speed change has just happened.
+
+ @Input                ui32DeviceIndex : device index
+ @Input                bIdleDevice : whether the device had been idled
+ @Input                pvInfo
+
+ @Return       IMG_VOID
+
+******************************************************************************/
+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32   ui32DeviceIndex,
+                                                                                 IMG_BOOL              bIdleDevice,
+                                                                                 IMG_VOID              *pvInfo)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDevice;
+       IMG_UINT64                      ui64StartTimer, ui64StopTimer;
+
+    PVR_UNREFERENCED_PARAMETER(pvInfo);
+
+       ui64StartTimer = OSClockus();
+
+       /*search the device and then do the post clock speed change*/
+       psPowerDevice = (PVRSRV_POWER_DEV*)
+                                       List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                &MatchPowerDeviceIndex_AnyVaCb,
+                                                                                                ui32DeviceIndex);
+
+       if (psPowerDevice)
+       {
+               eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
+                                                                                                               psPowerDevice->eCurrentPowerState);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                       "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
+                                       ui32DeviceIndex, eError));
+               }
+
+               if((psPowerDevice->eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF) && bIdleDevice)
+               {
+                       eError = PVRSRVDeviceIdleCancelRequestKM(IMG_FALSE, ui32DeviceIndex);
+
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePostClockSpeedChange : Failed to cancel forced IDLE."));
+                       }
+               }
+       }
+
+       /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */
+       PVRSRVPowerUnlock();
+
+       ui64StopTimer = OSClockus();
+
+       InsertPowerTimeStatisticExtraPost(ui64StartTimer, ui64StopTimer);
+
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeviceDustCountChange
+
+ @Description
+
+       Request from system layer that a dust count change is requested.
+
+ @Input                ui32DeviceIndex : device index
+ @Input                ui32DustCount : dust count to be set
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVDeviceDustCountChange(IMG_UINT32    ui32DeviceIndex,
+                                               IMG_UINT32      ui32DustCount)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_POWER_DEV        *psPowerDevice;
+
+       /*search the device and then do the pre clock speed change*/
+       psPowerDevice = (PVRSRV_POWER_DEV*)
+                                       List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
+                                                                                                &MatchPowerDeviceIndex_AnyVaCb,
+                                                                                                ui32DeviceIndex);
+
+       if (psPowerDevice)
+       {
+               eError = PVRSRVPowerLock();
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceDustCountChange : failed to acquire lock, error:0x%x", eError));
+                       return eError;
+               }
+
+               /* Device must be idle to change dust count  */
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       PDUMPPOWCMDSTART();
+                       eError = PVRSRVSetDevicePowerStateKM(ui32DeviceIndex,
+                                                               PVRSRV_DEV_POWER_STATE_ON,
+                                                               IMG_FALSE);
+                       PDUMPPOWCMDEND();
+
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceDustCountChange: failed to transition Rogue to ON (%s)",
+                                                       PVRSRVGetErrorStringKM(eError)));
+                               goto ErrorExit;
+                       }
+
+                       eError = PVRSRVDeviceIdleRequestKM(IMG_FALSE, ui32DeviceIndex, IMG_NULL, IMG_FALSE);
+
+                       if (eError == PVRSRV_OK)
+                       {
+                               break;
+                       }
+                       else if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+                       {
+                               PVRSRV_ERROR    eError2;
+
+                               PVRSRVPowerUnlock();
+                               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+                               eError2 = PVRSRVPowerLock();
+
+                               if (eError2 != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceDustCountChange : failed to acquire lock, error:0x%x", eError));
+                                       return eError2;
+                               }
+                       }
+                       else
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceDustCountChange : error occurred whilst forcing idle, error:0x%x", eError));
+                               goto ErrorExit;
+                       }
+               } END_LOOP_UNTIL_TIMEOUT();
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceDustCountChange : timeout occurred attempting to force idle, error:0x%x", eError));
+                       goto ErrorExit;
+               }
+
+               if (psPowerDevice->pfnDustCountRequest != IMG_NULL)
+               {
+                       PVRSRV_ERROR    eError2 = psPowerDevice->pfnDustCountRequest(psPowerDevice->hDevCookie, ui32DustCount);
+
+                       if (eError2 != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                               "PVRSRVDeviceDustCountChange : Device %u failed, error:0x%x",
+                                               ui32DeviceIndex, eError));
+                       }
+               }
+
+               eError = PVRSRVDeviceIdleCancelRequestKM(IMG_FALSE, ui32DeviceIndex);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePostClockSpeedChange : Failed to cancel forced IDLE."));
+                       goto ErrorExit;
+               }
+
+               PVRSRVPowerUnlock();
+       }
+
+       return eError;
+
+ErrorExit:
+       PVRSRVPowerUnlock();
+       return eError;
+}
+
+
+/******************************************************************************
+ End of file (power.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/common/process_stats.c b/drivers/gpu/rogue_m/services/server/common/process_stats.c
new file mode 100644 (file)
index 0000000..80f5ad9
--- /dev/null
@@ -0,0 +1,2515 @@
+/*************************************************************************/ /*!
+@File
+@Title          Process based statistics
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Manages a collection of statistics based around a process
+                and referenced via OS agnostic methods.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "lock.h"
+#include "allocmem.h"
+#include "osfunc.h"
+#include "lists.h"
+#include "process_stats.h"
+#include "ri_server.h"
+#include "hash.h"
+#include "connection_server.h"
+#include "pvrsrv.h"
+
+#define DBGTIMEDIFF(T0, T1)  ((IMG_UINT64) ( (T0) <= (T1) ? (T1) - (T0): IMG_UINT64_MAX - (T0) + (T1) ))
+#define MEAN_TIME(A, B)     ( ((3*(A))/4) + ((1 * (B))/4) )
+
+
+/*
+ *  Maximum history of process statistics that will be kept.
+ */
+#define MAX_DEAD_LIST_PROCESSES  (10)
+
+void *pvOSPowerStatsEntryData=NULL;
+
+
+/*
+ * Definition of all process based statistics and the strings used to
+ * format them.
+ */
+typedef enum
+{
+    /* Stats that are per process... */
+    PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS,
+    PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS,
+
+    PVRSRV_PROCESS_STAT_TYPE_RC_OOMS,
+    PVRSRV_PROCESS_STAT_TYPE_RC_PRS,
+    PVRSRV_PROCESS_STAT_TYPE_RC_GROWS,
+    PVRSRV_PROCESS_STAT_TYPE_RC_PUSH_GROWS,
+    PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES,
+    PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES,
+    PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES,
+    PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES,
+    PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP,
+    PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW,
+    PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP,
+    PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW,
+    PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT,
+    PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES,
+    PVRSRV_PROCESS_STAT_TYPE_KMALLOC,
+    PVRSRV_PROCESS_STAT_TYPE_KMALLOC_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_VMALLOC,
+    PVRSRV_PROCESS_STAT_TYPE_VMALLOC_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA,
+    PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA,
+    PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES,
+    PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES_MAX,
+    PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES,
+    PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES_MAX,
+
+    //zxl: count total data
+       PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC,
+       PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC,
+       PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP,
+       PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP,
+
+       /* Must be the last enum...*/
+       PVRSRV_PROCESS_STAT_TYPE_COUNT
+} PVRSRV_PROCESS_STAT_TYPE;
+
+
+typedef enum
+{
+    PVRSRV_POWER_TIMING_STAT_FORCED_POWER_TRANSITION=0,
+    PVRSRV_POWER_TIMING_STAT_PRE_DEVICE,
+    PVRSRV_POWER_TIMING_STAT_PRE_SYSTEM,
+    PVRSRV_POWER_TIMING_STAT_POST_DEVICE,
+    PVRSRV_POWER_TIMING_STAT_POST_SYSTEM,
+    PVRSRV_POWER_TIMING_STAT_NEWLINE1,
+    PVRSRV_POWER_TIMING_STAT_NOT_FORCED_POWER_TRANSITION,
+    PVRSRV_POWER_TIMING_STAT_NON_PRE_DEVICE,
+    PVRSRV_POWER_TIMING_STAT_NON_PRE_SYSTEM,
+    PVRSRV_POWER_TIMING_STAT_NON_POST_DEVICE,
+    PVRSRV_POWER_TIMING_STAT_NON_POST_SYSTEM,
+    PVRSRV_POWER_TIMING_STAT_NEWLINE2,
+    PVRSRV_POWER_TIMING_STAT_FW_BOOTUP_TIME,
+    PVRSRV_POWER_TIMING_STAT_HOST_ACK
+} PVR_SRV_OTHER_STAT_TYPE;
+
+
+static IMG_CHAR*  pszProcessStatFmt[PVRSRV_PROCESS_STAT_TYPE_COUNT] = {
+       "Connections                       %10d\n", /* PVRSRV_STAT_TYPE_CONNECTIONS */
+       "ConnectionsMax                    %10d\n", /* PVRSRV_STAT_TYPE_MAXCONNECTIONS */
+
+    "RenderContextOutOfMemoryEvents    %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_OOMS */
+    "RenderContextPartialRenders       %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_PRS */
+    "RenderContextGrows                %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_GROWS */
+    "RenderContextPushGrows            %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_PUSH_GROWS */
+    "RenderContextTAStores             %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES */
+    "RenderContext3DStores             %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES */
+    "RenderContextSHStores             %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES */
+    "RenderContextCDMStores            %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES */
+    "ZSBufferRequestsByApp             %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP */
+    "ZSBufferRequestsByFirmware        %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW */
+    "FreeListGrowRequestsByApp         %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP */
+    "FreeListGrowRequestsByFirmware    %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW */
+    "FreeListInitialPages              %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT */
+    "FreeListMaxPages                  %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES */
+    "MemoryUsageKMalloc                %10d\n", /* PVRSRV_STAT_TYPE_KMALLOC */
+    "MemoryUsageKMallocMax             %10d\n", /* PVRSRV_STAT_TYPE_MAX_KMALLOC */
+    "MemoryUsageVMalloc                %10d\n", /* PVRSRV_STAT_TYPE_VMALLOC */
+    "MemoryUsageVMallocMax             %10d\n", /* PVRSRV_STAT_TYPE_MAX_VMALLOC */
+    "MemoryUsageAllocPTMemoryUMA       %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_PAGES_PT_UMA */
+    "MemoryUsageAllocPTMemoryUMAMax    %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_PAGES_PT_UMA */
+    "MemoryUsageVMapPTUMA              %10d\n", /* PVRSRV_STAT_TYPE_VMAP_PT_UMA */
+    "MemoryUsageVMapPTUMAMax           %10d\n", /* PVRSRV_STAT_TYPE_MAX_VMAP_PT_UMA */
+    "MemoryUsageAllocPTMemoryLMA       %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_PAGES_PT_LMA */
+    "MemoryUsageAllocPTMemoryLMAMax    %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_PAGES_PT_LMA */
+    "MemoryUsageIORemapPTLMA           %10d\n", /* PVRSRV_STAT_TYPE_IOREMAP_PT_LMA */
+    "MemoryUsageIORemapPTLMAMax        %10d\n", /* PVRSRV_STAT_TYPE_MAX_IOREMAP_PT_LMA */
+    "MemoryUsageAllocGPUMemLMA         %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_LMA_PAGES */
+    "MemoryUsageAllocGPUMemLMAMax      %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_LMA_PAGES */
+    "MemoryUsageAllocGPUMemUMA         %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_UMA_PAGES */
+    "MemoryUsageAllocGPUMemUMAMax      %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_UMA_PAGES */
+    "MemoryUsageMappedGPUMemUMA/LMA    %10d\n", /* PVRSRV_STAT_TYPE_MAP_UMA_LMA_PAGES */
+    "MemoryUsageMappedGPUMemUMA/LMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_MAP_UMA_LMA_PAGES */
+
+    //zxl: count total data
+    "MemoryUsageTotalAlloc             %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC */
+    "MemoryUsageTotalAllocMax          %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC */
+    "MemoryUsageTotalMap               %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP */
+    "MemoryUsageTotalMapMax            %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP */
+};
+
+
+/*
+ *  Functions for printing the information stored...
+ */
+IMG_VOID  ProcessStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
+                                    OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+IMG_VOID  MemStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
+                                OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+IMG_VOID  RIMemStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
+                                  OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+IMG_VOID  PowerStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
+                                  OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+IMG_VOID  GlobalStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
+                                                                  OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+
+
+/*
+ *  Macros for updating stat values.
+ */
+#define UPDATE_MAX_VALUE(a,b)                  do { if ((b) > (a)) {(a) = (b);} } while(0)
+#define INCREASE_STAT_VALUE(ptr,var,val)       do { (ptr)->i32StatValue[(var)] += (val); if ((ptr)->i32StatValue[(var)] > (ptr)->i32StatValue[(var##_MAX)]) {(ptr)->i32StatValue[(var##_MAX)] = (ptr)->i32StatValue[(var)];} } while(0)
+#define DECREASE_STAT_VALUE(ptr,var,val)       do { if ((IMG_SIZE_T)(ptr)->i32StatValue[(var)] >= (val)) { (ptr)->i32StatValue[(var)] -= (val); } else { (ptr)->i32StatValue[(var)] = 0; } } while(0)
+#define INCREASE_GLOBAL_STAT_VALUE(var,val)    do { (var) += (val); if ((var) > (var##Max)) {(var##Max) = (var);} } while(0)
+#define DECREASE_GLOBAL_STAT_VALUE(var,val)    do { if ((var) >= (val)) { (var) -= (val); } else { (var) = 0; } } while(0)
+
+
+/*
+ * Structures for holding statistics...
+ */
+typedef enum
+{
+       PVRSRV_STAT_STRUCTURE_PROCESS = 1,
+       PVRSRV_STAT_STRUCTURE_RENDER_CONTEXT = 2,
+       PVRSRV_STAT_STRUCTURE_MEMORY = 3,
+       PVRSRV_STAT_STRUCTURE_RIMEMORY = 4
+} PVRSRV_STAT_STRUCTURE_TYPE;
+
+#define MAX_PROC_NAME_LENGTH   (32)
+
+typedef struct _PVRSRV_PROCESS_STATS_ {
+       /* Structure type (must be first!) */
+       PVRSRV_STAT_STRUCTURE_TYPE        eStructureType;
+
+       /* Linked list pointers */
+       struct _PVRSRV_PROCESS_STATS_*    psNext;
+       struct _PVRSRV_PROCESS_STATS_*    psPrev;
+
+       /* OS level process ID */
+       IMG_PID                           pid;
+       IMG_UINT32                        ui32RefCount;
+       IMG_UINT32                        ui32MemRefCount;
+
+       /* Folder name used to store the statistic */
+       IMG_CHAR                                          szFolderName[MAX_PROC_NAME_LENGTH];
+
+       /* OS specific data */
+       IMG_PVOID                         pvOSPidFolderData;
+       IMG_PVOID                         pvOSPidEntryData;
+
+       /* Stats... */
+       IMG_INT32                         i32StatValue[PVRSRV_PROCESS_STAT_TYPE_COUNT];
+
+       /* Other statistics structures */
+       struct _PVRSRV_RENDER_STATS_*     psRenderLiveList;
+       struct _PVRSRV_RENDER_STATS_*     psRenderDeadList;
+
+       struct _PVRSRV_MEMORY_STATS_*     psMemoryStats;
+       struct _PVRSRV_RI_MEMORY_STATS_*  psRIMemoryStats;
+} PVRSRV_PROCESS_STATS;
+
+typedef struct _PVRSRV_RENDER_STATS_ {
+       /* Structure type (must be first!) */
+       PVRSRV_STAT_STRUCTURE_TYPE     eStructureType;
+
+       /* Linked list pointers */
+       struct _PVRSRV_RENDER_STATS_*  psNext;
+       struct _PVRSRV_RENDER_STATS_*  psPrev;
+
+       /* OS specific data */
+       IMG_PVOID                      pvOSData;
+
+       /* Stats... */
+       IMG_INT32                      i32StatValue[4];
+} PVRSRV_RENDER_STATS;
+
+typedef struct _PVRSRV_MEM_ALLOC_REC_
+{
+    PVRSRV_MEM_ALLOC_TYPE  eAllocType;
+    IMG_UINT64                 ui64Key;
+    IMG_VOID               *pvCpuVAddr;
+    IMG_CPU_PHYADDR        sCpuPAddr;
+       IMG_SIZE_T                         uiBytes;
+    IMG_PVOID              pvPrivateData;
+
+    struct _PVRSRV_MEM_ALLOC_REC_  *psNext;
+       struct _PVRSRV_MEM_ALLOC_REC_  **ppsThis;
+} PVRSRV_MEM_ALLOC_REC;
+
+typedef struct _PVRSRV_MEMORY_STATS_ {
+       /* Structure type (must be first!) */
+       PVRSRV_STAT_STRUCTURE_TYPE  eStructureType;
+
+       /* OS specific data */
+       IMG_PVOID                   pvOSMemEntryData;
+
+       /* Stats... */
+       PVRSRV_MEM_ALLOC_REC        *psMemoryRecords;
+} PVRSRV_MEMORY_STATS;
+
+typedef struct _PVRSRV_RI_MEMORY_STATS_ {
+       /* Structure type (must be first!) */
+       PVRSRV_STAT_STRUCTURE_TYPE  eStructureType;
+
+       /* OS level process ID */
+       IMG_PID                         pid;
+
+       /* OS specific data */
+       IMG_PVOID                   pvOSRIMemEntryData;
+} PVRSRV_RI_MEMORY_STATS;
+
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+static IMPLEMENT_LIST_INSERT(PVRSRV_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_REMOVE(PVRSRV_MEM_ALLOC_REC)
+#endif
+
+
+/*
+ *  Global Boolean to flag when the statistics are ready to monitor
+ *  memory allocations.
+ */
+static  IMG_BOOL  bProcessStatsInitialised = IMG_FALSE;
+
+/*
+ * Linked lists for process stats. Live stats are for processes which are still running
+ * and the dead list holds those that have exited.
+ */
+static PVRSRV_PROCESS_STATS*  psLiveList = IMG_NULL;
+static PVRSRV_PROCESS_STATS*  psDeadList = IMG_NULL;
+
+POS_LOCK  psLinkedListLock = IMG_NULL;
+
+
+/*
+ * Pointer to OS folder to hold PID folders.
+ */
+IMG_CHAR*  pszOSLivePidFolderName = "pid";
+IMG_CHAR*  pszOSDeadPidFolderName = "pids_retired";
+IMG_PVOID  pvOSLivePidFolder      = IMG_NULL;
+IMG_PVOID  pvOSDeadPidFolder      = IMG_NULL;
+
+/* global driver-data folders */
+typedef struct _GLOBAL_STATS_
+{
+       IMG_UINT32 ui32MemoryUsageKMalloc;
+       IMG_UINT32 ui32MemoryUsageKMallocMax;
+       IMG_UINT32 ui32MemoryUsageVMalloc;
+       IMG_UINT32 ui32MemoryUsageVMallocMax;
+       IMG_UINT32 ui32MemoryUsageAllocPTMemoryUMA;
+       IMG_UINT32 ui32MemoryUsageAllocPTMemoryUMAMax;
+       IMG_UINT32 ui32MemoryUsageVMapPTUMA;
+       IMG_UINT32 ui32MemoryUsageVMapPTUMAMax;
+       IMG_UINT32 ui32MemoryUsageAllocPTMemoryLMA;
+       IMG_UINT32 ui32MemoryUsageAllocPTMemoryLMAMax;
+       IMG_UINT32 ui32MemoryUsageIORemapPTLMA;
+       IMG_UINT32 ui32MemoryUsageIORemapPTLMAMax;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemLMA;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemLMAMax;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemUMA;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAMax;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAPool;
+       IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAPoolMax;
+       IMG_UINT32 ui32MemoryUsageMappedGPUMemUMA_LMA;
+       IMG_UINT32 ui32MemoryUsageMappedGPUMemUMA_LMAMax;
+
+       //zxl: count total data
+       IMG_UINT32 ui32MemoryUsageTotalAlloc;
+       IMG_UINT32 ui32MemoryUsageTotalAllocMax;
+       IMG_UINT32 ui32MemoryUsageTotalMap;
+    IMG_UINT32 ui32MemoryUsageTotalMapMax;
+} GLOBAL_STATS;
+
+static IMG_PVOID  pvOSGlobalMemEntryRef = IMG_NULL;
+static IMG_CHAR* const pszDriverStatFilename = "driver_stats";
+static GLOBAL_STATS gsGlobalStats;
+
+#define HASH_INITIAL_SIZE 5
+/* A hash table used to store the size of any vmalloc'd allocation
+ * against its address (not needed for kmallocs as we can use ksize()) */
+static HASH_TABLE* gpsVmallocSizeHashTable;
+static POS_LOCK         gpsVmallocSizeHashTableLock;
+
+/*Power Statistics List */
+
+static IMG_UINT64 ui64TotalForcedEntries=0,ui64TotalNotForcedEntries=0;
+
+static IMG_UINT64 ui64ForcedPreDevice=0, ui64ForcedPreSystem=0, ui64ForcedPostDevice=0, ui64ForcedPostSystem=0;
+static IMG_UINT64 ui64NotForcedPreDevice=0, ui64NotForcedPreSystem=0, ui64NotForcedPostDevice=0, ui64NotForcedPostSystem=0;
+
+static IMG_UINT32 _PVRSRVIncrMemStatRefCount(IMG_PVOID pvStatPtr);
+static IMG_UINT32 _PVRSRVDecrMemStatRefCount(IMG_PVOID pvStatPtr);
+
+IMG_VOID InsertPowerTimeStatistic(PVRSRV_POWER_ENTRY_TYPE bType,
+               IMG_INT32 i32CurrentState, IMG_INT32 i32NextState,
+        IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime,
+               IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime,
+               IMG_BOOL bForced)
+{
+    IMG_UINT64 ui64Device;
+    IMG_UINT64 ui64System;
+
+       if (i32CurrentState==i32NextState) return ;
+
+    ui64Device=ui64DevEndTime-ui64DevStartTime;
+    ui64System=ui64SysEndTime-ui64SysStartTime;
+
+    if (bForced)
+    {
+        ui64TotalForcedEntries++;
+        if (bType==PVRSRV_POWER_ENTRY_TYPE_POST)
+        {
+            ui64ForcedPostDevice+=ui64Device;
+            ui64ForcedPostSystem+=ui64System;
+        }
+        else
+        {
+            ui64ForcedPreDevice+=ui64Device;
+            ui64ForcedPreSystem+=ui64System;
+        }
+    }
+    else
+    {
+        ui64TotalNotForcedEntries++;
+        if (bType==PVRSRV_POWER_ENTRY_TYPE_POST)
+        {
+            ui64NotForcedPostDevice+=ui64Device;
+            ui64NotForcedPostSystem+=ui64System;
+        }
+        else
+        {
+            ui64NotForcedPreDevice+=ui64Device;
+            ui64NotForcedPreSystem+=ui64System;
+        }
+    }
+
+       return;
+}
+
+typedef struct _EXTRA_POWER_STATS_
+{
+       IMG_UINT64      ui64PreClockSpeedChangeDuration;
+       IMG_UINT64      ui64BetweenPreEndingAndPostStartingDuration;
+       IMG_UINT64      ui64PostClockSpeedChangeDuration;
+} EXTRA_POWER_STATS;
+
+#define NUM_EXTRA_POWER_STATS  10
+
+static EXTRA_POWER_STATS asClockSpeedChanges[NUM_EXTRA_POWER_STATS];
+static IMG_UINT32      ui32ClockSpeedIndexStart = 0, ui32ClockSpeedIndexEnd = 0;
+
+static IMG_UINT64 ui64PreClockSpeedChangeMark = 0;
+
+IMG_VOID InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer)
+{
+       asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PreClockSpeedChangeDuration = ui64Stoptimer - ui64StartTimer;
+
+       ui64PreClockSpeedChangeMark = OSClockus();
+
+       return ;
+}
+
+IMG_VOID InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer)
+{
+       IMG_UINT64 ui64Duration = ui64StartTimer - ui64PreClockSpeedChangeMark;
+
+       PVR_ASSERT(ui64PreClockSpeedChangeMark > 0);
+
+       asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64BetweenPreEndingAndPostStartingDuration = ui64Duration;
+       asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PostClockSpeedChangeDuration = ui64StopTimer - ui64StartTimer;
+
+       ui32ClockSpeedIndexEnd = (ui32ClockSpeedIndexEnd + 1) % NUM_EXTRA_POWER_STATS;
+
+       if (ui32ClockSpeedIndexEnd == ui32ClockSpeedIndexStart)
+       {
+               ui32ClockSpeedIndexStart = (ui32ClockSpeedIndexStart + 1) % NUM_EXTRA_POWER_STATS;
+       }
+
+       ui64PreClockSpeedChangeMark = 0;
+
+       return;
+}
+
+/*************************************************************************/ /*!
+@Function       _RemoveRenderStatsFromList
+@Description    Detaches a process from either the live or dead list.
+@Input          psProcessStats  Process to remove the stats from.
+@Input          psRenderStats   Render stats to remove.
+*/ /**************************************************************************/
+static IMG_VOID
+_RemoveRenderStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats,
+                           PVRSRV_RENDER_STATS* psRenderStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+       PVR_ASSERT(psRenderStats != IMG_NULL);
+
+       /* Remove the item from the linked lists... */
+       if (psProcessStats->psRenderLiveList == psRenderStats)
+       {
+               psProcessStats->psRenderLiveList = psRenderStats->psNext;
+
+               if (psProcessStats->psRenderLiveList != IMG_NULL)
+               {
+                       psProcessStats->psRenderLiveList->psPrev = IMG_NULL;
+               }
+       }
+       else if (psProcessStats->psRenderDeadList == psRenderStats)
+       {
+               psProcessStats->psRenderDeadList = psRenderStats->psNext;
+
+               if (psProcessStats->psRenderDeadList != IMG_NULL)
+               {
+                       psProcessStats->psRenderDeadList->psPrev = IMG_NULL;
+               }
+       }
+       else
+       {
+               PVRSRV_RENDER_STATS*  psNext = psRenderStats->psNext;
+               PVRSRV_RENDER_STATS*  psPrev = psRenderStats->psPrev;
+
+               if (psRenderStats->psNext != IMG_NULL)
+               {
+                       psRenderStats->psNext->psPrev = psPrev;
+               }
+               if (psRenderStats->psPrev != IMG_NULL)
+               {
+                       psRenderStats->psPrev->psNext = psNext;
+               }
+       }
+
+       /* Reset the pointers in this cell, as it is not attached to anything */
+       psRenderStats->psNext = IMG_NULL;
+       psRenderStats->psPrev = IMG_NULL;
+} /* _RemoveRenderStatsFromList */
+
+
+/*************************************************************************/ /*!
+@Function       _DestoryRenderStat
+@Description    Frees memory and resources held by a render statistic.
+@Input          psRenderStats  Render stats to destroy.
+*/ /**************************************************************************/
+static IMG_VOID
+_DestoryRenderStat(PVRSRV_RENDER_STATS* psRenderStats)
+{
+       PVR_ASSERT(psRenderStats != IMG_NULL);
+
+       /* Remove the statistic from the OS... */
+//     OSRemoveStatisticEntry(psRenderStats->pvOSData);
+
+       /* Free the memory... */
+       OSFreeMem(psRenderStats);
+} /* _DestoryRenderStat */
+
+
+/*************************************************************************/ /*!
+@Function       _FindProcessStatsInLiveList
+@Description    Searches the Live Process List for a statistics structure that
+                matches the PID given.
+@Input          pid  Process to search for.
+@Return         Pointer to stats structure for the process.
+*/ /**************************************************************************/
+static PVRSRV_PROCESS_STATS*
+_FindProcessStatsInLiveList(IMG_PID pid)
+{
+       PVRSRV_PROCESS_STATS*  psProcessStats = psLiveList;
+
+       while (psProcessStats != IMG_NULL)
+       {
+               if (psProcessStats->pid == pid)
+               {
+                       return psProcessStats;
+               }
+
+               psProcessStats = psProcessStats->psNext;
+       }
+
+       return IMG_NULL;
+} /* _FindProcessStatsInLiveList */
+
+
+/*************************************************************************/ /*!
+@Function       _FindProcessStatsInDeadList
+@Description    Searches the Dead Process List for a statistics structure that
+                matches the PID given.
+@Input          pid  Process to search for.
+@Return         Pointer to stats structure for the process.
+*/ /**************************************************************************/
+static PVRSRV_PROCESS_STATS*
+_FindProcessStatsInDeadList(IMG_PID pid)
+{
+       PVRSRV_PROCESS_STATS*  psProcessStats = psDeadList;
+
+       while (psProcessStats != IMG_NULL)
+       {
+               if (psProcessStats->pid == pid)
+               {
+                       return psProcessStats;
+               }
+
+               psProcessStats = psProcessStats->psNext;
+       }
+
+       return IMG_NULL;
+} /* _FindProcessStatsInDeadList */
+
+
+/*************************************************************************/ /*!
+@Function       _FindProcessStats
+@Description    Searches the Live and Dead Process Lists for a statistics
+                structure that matches the PID given.
+@Input          pid  Process to search for.
+@Return         Pointer to stats structure for the process.
+*/ /**************************************************************************/
+static PVRSRV_PROCESS_STATS*
+_FindProcessStats(IMG_PID pid)
+{
+       PVRSRV_PROCESS_STATS*  psProcessStats = _FindProcessStatsInLiveList(pid);
+
+       if (psProcessStats == IMG_NULL)
+       {
+               psProcessStats = _FindProcessStatsInDeadList(pid);
+       }
+
+       return psProcessStats;
+} /* _FindProcessStats */
+
+
+/*************************************************************************/ /*!
+@Function       _AddProcessStatsToFrontOfLiveList
+@Description    Add a statistic to the live list head.
+@Input          psProcessStats  Process stats to add.
+*/ /**************************************************************************/
+static IMG_VOID
+_AddProcessStatsToFrontOfLiveList(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+       if (psLiveList != IMG_NULL)
+       {
+               psLiveList->psPrev     = psProcessStats;
+               psProcessStats->psNext = psLiveList;
+       }
+
+       psLiveList = psProcessStats;
+} /* _AddProcessStatsToFrontOfLiveList */
+
+
+/*************************************************************************/ /*!
+@Function       _AddProcessStatsToFrontOfDeadList
+@Description    Add a statistic to the dead list head.
+@Input          psProcessStats  Process stats to add.
+*/ /**************************************************************************/
+static IMG_VOID
+_AddProcessStatsToFrontOfDeadList(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+       if (psDeadList != IMG_NULL)
+       {
+               psDeadList->psPrev     = psProcessStats;
+               psProcessStats->psNext = psDeadList;
+       }
+
+       psDeadList = psProcessStats;
+} /* _AddProcessStatsToFrontOfDeadList */
+
+
+/*************************************************************************/ /*!
+@Function       _RemoveProcessStatsFromList
+@Description    Detaches a process from either the live or dead list.
+@Input          psProcessStats  Process stats to remove.
+*/ /**************************************************************************/
+static IMG_VOID
+_RemoveProcessStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+       /* Remove the item from the linked lists... */
+       if (psLiveList == psProcessStats)
+       {
+               psLiveList = psProcessStats->psNext;
+
+               if (psLiveList != IMG_NULL)
+               {
+                       psLiveList->psPrev = IMG_NULL;
+               }
+       }
+       else if (psDeadList == psProcessStats)
+       {
+               psDeadList = psProcessStats->psNext;
+
+               if (psDeadList != IMG_NULL)
+               {
+                       psDeadList->psPrev = IMG_NULL;
+               }
+       }
+       else
+       {
+               PVRSRV_PROCESS_STATS*  psNext = psProcessStats->psNext;
+               PVRSRV_PROCESS_STATS*  psPrev = psProcessStats->psPrev;
+
+               if (psProcessStats->psNext != IMG_NULL)
+               {
+                       psProcessStats->psNext->psPrev = psPrev;
+               }
+               if (psProcessStats->psPrev != IMG_NULL)
+               {
+                       psProcessStats->psPrev->psNext = psNext;
+               }
+       }
+
+       /* Reset the pointers in this cell, as it is not attached to anything */
+       psProcessStats->psNext = IMG_NULL;
+       psProcessStats->psPrev = IMG_NULL;
+} /* _RemoveProcessStatsFromList */
+
+
+/*************************************************************************/ /*!
+@Function       _CreateOSStatisticEntries
+@Description    Create all OS entries for this statistic.
+@Input          psProcessStats  Process stats to destroy.
+@Input          pvOSPidFolder   Pointer to OS folder to place the entrys in.
+*/ /**************************************************************************/
+static IMG_VOID
+_CreateOSStatisticEntries(PVRSRV_PROCESS_STATS* psProcessStats,
+                          IMG_PVOID pvOSPidFolder)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+       psProcessStats->pvOSPidFolderData = OSCreateStatisticFolder(psProcessStats->szFolderName, pvOSPidFolder);
+       psProcessStats->pvOSPidEntryData  = OSCreateStatisticEntry("process_stats",
+                                                                  psProcessStats->pvOSPidFolderData,
+                                                                  ProcessStatsPrintElements,
+                                                                                                                          _PVRSRVIncrMemStatRefCount,
+                                                                                                                          _PVRSRVDecrMemStatRefCount,
+                                                                  (IMG_PVOID) psProcessStats);
+
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       psProcessStats->psMemoryStats->pvOSMemEntryData = OSCreateStatisticEntry("mem_area",
+                                                                  psProcessStats->pvOSPidFolderData,
+                                                                  MemStatsPrintElements,
+                                                                                                                          IMG_NULL,
+                                                                                                                          IMG_NULL,
+                                                                  (IMG_PVOID) psProcessStats->psMemoryStats);
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       psProcessStats->psRIMemoryStats->pvOSRIMemEntryData = OSCreateStatisticEntry("ri_mem_area",
+                                                                  psProcessStats->pvOSPidFolderData,
+                                                                  RIMemStatsPrintElements,
+                                                                                                                          IMG_NULL,
+                                                                                                                          IMG_NULL,
+                                                                  (IMG_PVOID) psProcessStats->psRIMemoryStats);
+#endif
+} /* _CreateOSStatisticEntries */
+
+
+/*************************************************************************/ /*!
+@Function       _RemoveOSStatisticEntries
+@Description    Removed all OS entries used by this statistic.
+@Input          psProcessStats  Process stats to destroy.
+*/ /**************************************************************************/
+static IMG_VOID
+_RemoveOSStatisticEntries(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+#if defined(PVR_RI_DEBUG)
+       OSRemoveStatisticEntry(psProcessStats->psRIMemoryStats->pvOSRIMemEntryData);
+#endif
+
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       OSRemoveStatisticEntry(psProcessStats->psMemoryStats->pvOSMemEntryData);
+#endif
+
+       if( psProcessStats->pvOSPidEntryData != IMG_NULL)
+       {
+               OSRemoveStatisticEntry(psProcessStats->pvOSPidEntryData);
+       }
+       if( psProcessStats->pvOSPidFolderData != IMG_NULL)
+       {
+               OSRemoveStatisticFolder(psProcessStats->pvOSPidFolderData);
+       }
+} /* _RemoveOSStatisticEntries */
+
+
+/*************************************************************************/ /*!
+@Function       _DestoryProcessStat
+@Description    Frees memory and resources held by a process statistic.
+@Input          psProcessStats  Process stats to destroy.
+*/ /**************************************************************************/
+static IMG_VOID
+_DestoryProcessStat(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       PVR_ASSERT(psProcessStats != IMG_NULL);
+
+       /* Remove this statistic from the OS... */
+       //_RemoveOSStatisticEntries(psProcessStats);
+
+       /* Free the live and dead render statistic lists... */
+       while (psProcessStats->psRenderLiveList != IMG_NULL)
+       {
+               PVRSRV_RENDER_STATS*  psRenderStats = psProcessStats->psRenderLiveList;
+
+               _RemoveRenderStatsFromList(psProcessStats, psRenderStats);
+               _DestoryRenderStat(psRenderStats);
+       }
+
+       while (psProcessStats->psRenderDeadList != IMG_NULL)
+       {
+               PVRSRV_RENDER_STATS*  psRenderStats = psProcessStats->psRenderDeadList;
+
+               _RemoveRenderStatsFromList(psProcessStats, psRenderStats);
+               _DestoryRenderStat(psRenderStats);
+       }
+
+       /* Free the memory statistics... */
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       while (psProcessStats->psMemoryStats->psMemoryRecords)
+       {
+               List_PVRSRV_MEM_ALLOC_REC_Remove(psProcessStats->psMemoryStats->psMemoryRecords);
+       }
+       OSFreeMem(psProcessStats->psMemoryStats);
+#endif
+
+       /* Free the memory... */
+       OSFreeMem(psProcessStats);
+} /* _DestoryProcessStat */
+
+static IMG_UINT32 _PVRSRVIncrMemStatRefCount(IMG_PVOID pvStatPtr)
+{
+       PVRSRV_STAT_STRUCTURE_TYPE*  peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
+       PVRSRV_PROCESS_STATS*  psProcessStats = (PVRSRV_PROCESS_STATS*) pvStatPtr;
+       IMG_UINT32 ui32Res = 7777;
+
+    switch (*peStructureType)
+       {
+               case PVRSRV_STAT_STRUCTURE_PROCESS:
+               {
+                       /* Increment stat memory refCount */
+                       ui32Res = ++psProcessStats->ui32MemRefCount;
+                       break;
+               }
+               default:
+               {
+                       break;
+               }
+       }
+       return ui32Res;
+}
+
+static IMG_UINT32 _PVRSRVDecrMemStatRefCount(IMG_PVOID pvStatPtr)
+{
+       PVRSRV_STAT_STRUCTURE_TYPE*  peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
+       PVRSRV_PROCESS_STATS*  psProcessStats = (PVRSRV_PROCESS_STATS*) pvStatPtr;
+       IMG_UINT32 ui32Res = 7777;
+
+    switch (*peStructureType)
+       {
+               case PVRSRV_STAT_STRUCTURE_PROCESS:
+               {
+                       /* Decrement stat memory refCount and free if now zero */
+                       ui32Res = --psProcessStats->ui32MemRefCount;
+                       if (ui32Res == 0)
+                       {
+                               _DestoryProcessStat(psProcessStats);
+                       }
+                       break;
+               }
+               default:
+               {
+                       break;
+               }
+       }
+       return ui32Res;
+}
+
+/*************************************************************************/ /*!
+@Function       _CompressMemoryUsage
+@Description    Reduces memory usage by deleting old statistics data.
+                This function requires that the list lock is not held!
+*/ /**************************************************************************/
+static IMG_VOID
+_CompressMemoryUsage(IMG_VOID)
+{
+       PVRSRV_PROCESS_STATS*  psProcessStats;
+       PVRSRV_PROCESS_STATS*  psProcessStatsToBeFreed;
+       IMG_UINT32  ui32ItemsRemaining;
+
+       /*
+        *  We hold the lock whilst checking the list, but we'll release it
+        *  before freeing memory (as that will require the lock too)!
+        */
+    OSLockAcquire(psLinkedListLock);
+
+       /* Check that the dead list is not bigger than the max size... */
+       psProcessStats          = psDeadList;
+       psProcessStatsToBeFreed = IMG_NULL;
+       ui32ItemsRemaining      = MAX_DEAD_LIST_PROCESSES;
+
+       while (psProcessStats != IMG_NULL  &&  ui32ItemsRemaining > 0)
+    {
+               ui32ItemsRemaining--;
+               if (ui32ItemsRemaining == 0)
+               {
+                       /* This is the last allowed process, cut the linked list here! */
+                       psProcessStatsToBeFreed = psProcessStats->psNext;
+                       psProcessStats->psNext  = IMG_NULL;
+               }
+               else
+               {
+                       psProcessStats = psProcessStats->psNext;
+               }
+       }
+
+       OSLockRelease(psLinkedListLock);
+
+       /* Any processes stats remaining will need to be destroyed... */
+       while (psProcessStatsToBeFreed != IMG_NULL)
+    {
+               PVRSRV_PROCESS_STATS*  psNextProcessStats = psProcessStatsToBeFreed->psNext;
+
+               psProcessStatsToBeFreed->psNext = IMG_NULL;
+               _RemoveOSStatisticEntries(psProcessStatsToBeFreed);
+               _PVRSRVDecrMemStatRefCount((void*)psProcessStatsToBeFreed);
+               //_DestoryProcessStat(psProcessStatsToBeFreed);
+
+               psProcessStatsToBeFreed = psNextProcessStats;
+       }
+} /* _CompressMemoryUsage */
+
+/* These functions move the process stats from the living to the dead list.
+ * _MoveProcessToDeadList moves the entry in the global lists and
+ * it needs to be protected by psLinkedListLock.
+ * _MoveProcessToDeadListDebugFS performs the OS calls and it
+ * shouldn't be used under psLinkedListLock because this could generate a
+ * lockdep warning. */
+static IMG_VOID
+_MoveProcessToDeadList(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       /* Take the element out of the live list and append to the dead list... */
+       _RemoveProcessStatsFromList(psProcessStats);
+       _AddProcessStatsToFrontOfDeadList(psProcessStats);
+} /* _MoveProcessToDeadList */
+
+static IMG_VOID
+_MoveProcessToDeadListDebugFS(PVRSRV_PROCESS_STATS* psProcessStats)
+{
+       /* Transfer the OS entries to the folder for dead processes... */
+       _RemoveOSStatisticEntries(psProcessStats);
+       _CreateOSStatisticEntries(psProcessStats, pvOSDeadPidFolder);
+} /* _MoveProcessToDeadListDebugFS */
+
+
+/*************************************************************************/ /*!
+@Function       PVRSRVStatsInitialise
+@Description    Entry point for initialising the statistics module.
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+PVRSRVStatsInitialise(IMG_VOID)
+{
+    PVRSRV_ERROR error;
+
+    PVR_ASSERT(psLiveList == IMG_NULL);
+    PVR_ASSERT(psDeadList == IMG_NULL);
+    PVR_ASSERT(psLinkedListLock == IMG_NULL);
+       PVR_ASSERT(gpsVmallocSizeHashTable == NULL);
+       PVR_ASSERT(bProcessStatsInitialised == IMG_FALSE);
+
+       /* We need a lock to protect the linked lists... */
+       error = OSLockCreate(&psLinkedListLock, LOCK_TYPE_NONE);
+       if (error == PVRSRV_OK)
+       {
+               /* We also need a lock to protect the hash table used for vmalloc size tracking.. */
+               error = OSLockCreate(&gpsVmallocSizeHashTableLock, LOCK_TYPE_NONE);
+
+               if (error != PVRSRV_OK)
+               {
+                       goto e0;
+               }
+               /* Create a pid folders for putting the PID files in... */
+               pvOSLivePidFolder = OSCreateStatisticFolder(pszOSLivePidFolderName, IMG_NULL);
+               pvOSDeadPidFolder = OSCreateStatisticFolder(pszOSDeadPidFolderName, IMG_NULL);
+
+               /* Create power stats entry... */
+               pvOSPowerStatsEntryData = OSCreateStatisticEntry("power_timing_stats",
+                                                                                                                IMG_NULL,
+                                                                                                                PowerStatsPrintElements,
+                                                                                                            IMG_NULL,
+                                                                                                            IMG_NULL,
+                                                                                                            IMG_NULL);
+
+               pvOSGlobalMemEntryRef = OSCreateStatisticEntry(pszDriverStatFilename,
+                                                                                                          IMG_NULL,
+                                                                                                          GlobalStatsPrintElements,
+                                                                                                      IMG_NULL,
+                                                                                                          IMG_NULL,
+                                                                                                          IMG_NULL);
+
+               /* Flag that we are ready to start monitoring memory allocations. */
+
+               gpsVmallocSizeHashTable = HASH_Create(HASH_INITIAL_SIZE);
+
+               OSMemSet(&gsGlobalStats, 0, sizeof(gsGlobalStats));
+
+               OSMemSet(asClockSpeedChanges, 0, sizeof(asClockSpeedChanges));
+       
+               bProcessStatsInitialised = IMG_TRUE;
+       }
+       return error;
+e0:
+       OSLockDestroy(psLinkedListLock);
+       psLinkedListLock = NULL;
+       return error;
+
+} /* PVRSRVStatsInitialise */
+
+
+/*************************************************************************/ /*!
+@Function       PVRSRVStatsDestroy
+@Description    Method for destroying the statistics module data.
+*/ /**************************************************************************/
+IMG_VOID
+PVRSRVStatsDestroy(IMG_VOID)
+{
+       PVR_ASSERT(bProcessStatsInitialised == IMG_TRUE);
+
+       /* Stop monitoring memory allocations... */
+       bProcessStatsInitialised = IMG_FALSE;
+
+       /* Destroy the power stats entry... */
+       if (pvOSPowerStatsEntryData!=NULL)
+       {
+               OSRemoveStatisticEntry(pvOSPowerStatsEntryData);
+               pvOSPowerStatsEntryData=NULL;
+       }
+
+       /* Destroy the global data entry */
+       if (pvOSGlobalMemEntryRef!=NULL)
+       {
+               OSRemoveStatisticEntry(pvOSGlobalMemEntryRef);
+               pvOSGlobalMemEntryRef=NULL;
+       }
+       
+       /* Destroy the lock... */
+       if (psLinkedListLock != IMG_NULL)
+       {
+               OSLockDestroy(psLinkedListLock);
+               psLinkedListLock = IMG_NULL;
+       }
+
+       /* Free the live and dead lists... */
+    while (psLiveList != IMG_NULL)
+    {
+               PVRSRV_PROCESS_STATS*  psProcessStats = psLiveList;
+
+               _RemoveProcessStatsFromList(psProcessStats);
+               _RemoveOSStatisticEntries(psProcessStats);
+       }
+
+    while (psDeadList != IMG_NULL)
+    {
+               PVRSRV_PROCESS_STATS*  psProcessStats = psDeadList;
+
+               _RemoveProcessStatsFromList(psProcessStats);
+               _RemoveOSStatisticEntries(psProcessStats);
+       }
+
+       /* Remove the OS folders used by the PID folders... */
+    OSRemoveStatisticFolder(pvOSLivePidFolder);
+    pvOSLivePidFolder = IMG_NULL;
+    OSRemoveStatisticFolder(pvOSDeadPidFolder);
+    pvOSDeadPidFolder = IMG_NULL;
+
+       if (gpsVmallocSizeHashTable != IMG_NULL)
+       {
+               HASH_Delete(gpsVmallocSizeHashTable);
+       }
+       if (gpsVmallocSizeHashTableLock != IMG_NULL)
+       {
+               OSLockDestroy(gpsVmallocSizeHashTableLock);
+               gpsVmallocSizeHashTableLock = IMG_NULL;
+       }
+
+} /* PVRSRVStatsDestroy */
+
+
+
+static void _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                                 IMG_SIZE_T uiBytes)
+{
+       switch (eAllocType)
+       {
+               case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageKMalloc, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMalloc, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMapPTUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageIORemapPTLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:     
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES:
+                       DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool, uiBytes);
+                       break;
+
+               default:
+                       PVR_ASSERT(0);
+                       break;
+       }
+}
+
+static void _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                                 IMG_SIZE_T uiBytes)
+{
+       switch (eAllocType)
+       {
+               case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageKMalloc, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMalloc, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMapPTUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageIORemapPTLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:     
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA, uiBytes);
+                       break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES:
+                       INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool, uiBytes);
+                       break;
+
+               default:
+                       PVR_ASSERT(0);
+                       break;
+       }
+       //Count total data
+    gsGlobalStats.ui32MemoryUsageTotalAlloc = gsGlobalStats.ui32MemoryUsageKMalloc + gsGlobalStats.ui32MemoryUsageVMalloc +\
+        gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA + gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA +\
+        gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA + gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA;
+
+    gsGlobalStats.ui32MemoryUsageTotalMap = gsGlobalStats.ui32MemoryUsageVMapPTUMA + gsGlobalStats.ui32MemoryUsageIORemapPTLMA +\
+        gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA;
+       //Count total data
+       gsGlobalStats.ui32MemoryUsageTotalAlloc = gsGlobalStats.ui32MemoryUsageKMalloc + gsGlobalStats.ui32MemoryUsageVMalloc +\
+        gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA + gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA +\
+        gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA + gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA;
+    UPDATE_MAX_VALUE(gsGlobalStats.ui32MemoryUsageTotalAllocMax,gsGlobalStats.ui32MemoryUsageTotalAlloc);
+
+    gsGlobalStats.ui32MemoryUsageTotalMap = gsGlobalStats.ui32MemoryUsageVMapPTUMA + gsGlobalStats.ui32MemoryUsageIORemapPTLMA +\
+        gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA;
+    UPDATE_MAX_VALUE(gsGlobalStats.ui32MemoryUsageTotalMapMax,gsGlobalStats.ui32MemoryUsageTotalMap);
+}
+
+
+/*************************************************************************/ /*!
+@Function       PVRSRVStatsRegisterProcess
+@Description    Register a process into the list statistics list.
+@Output         phProcessStats  Handle to the process to be used to deregister.
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+PVRSRVStatsRegisterProcess(IMG_HANDLE* phProcessStats)
+{
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+    IMG_PID                currentPid = OSGetCurrentProcessID();
+       IMG_BOOL               bMoveProcess = IMG_FALSE;
+
+    PVR_ASSERT(phProcessStats != IMG_NULL);
+
+    /* Check the PID has not already moved to the dead list... */
+       OSLockAcquire(psLinkedListLock);
+       psProcessStats = _FindProcessStatsInDeadList(currentPid);
+    if (psProcessStats != IMG_NULL)
+    {
+               /* Move it back onto the live list! */
+               _RemoveProcessStatsFromList(psProcessStats);
+               _AddProcessStatsToFrontOfLiveList(psProcessStats);
+
+               /* we can perform the OS operation out of lock */
+               bMoveProcess = IMG_TRUE;
+       }
+       else
+       {
+               /* Check the PID is not already registered in the live list... */
+               psProcessStats = _FindProcessStatsInLiveList(currentPid);
+       }
+
+       /* If the PID is on the live list then just increment the ref count and return... */
+    if (psProcessStats != IMG_NULL)
+    {
+               psProcessStats->ui32RefCount++;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount;
+               UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS],
+                                psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS]);
+               OSLockRelease(psLinkedListLock);
+
+               *phProcessStats = psProcessStats;
+
+               /* Check if we need to perform any OS operation */
+               if (bMoveProcess)
+               {
+                       /* Transfer the OS entries back to the folder for live processes... */
+                       _RemoveOSStatisticEntries(psProcessStats);
+                       _CreateOSStatisticEntries(psProcessStats, pvOSLivePidFolder);
+               }
+
+               return PVRSRV_OK;
+       }
+       OSLockRelease(psLinkedListLock);
+
+       /* Allocate a new node structure and initialise it... */
+       psProcessStats = OSAllocMem(sizeof(PVRSRV_PROCESS_STATS));
+       if (psProcessStats == IMG_NULL)
+       {
+               *phProcessStats = 0;
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psProcessStats, 0, sizeof(PVRSRV_PROCESS_STATS));
+
+       psProcessStats->eStructureType  = PVRSRV_STAT_STRUCTURE_PROCESS;
+       psProcessStats->pid             = currentPid;
+       psProcessStats->ui32RefCount    = 1;
+       psProcessStats->ui32MemRefCount = 1;
+
+       psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS]     = 1;
+       psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS] = 1;
+
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       psProcessStats->psMemoryStats = OSAllocMem(sizeof(PVRSRV_MEMORY_STATS));
+       if (psProcessStats->psMemoryStats == IMG_NULL)
+       {
+               OSFreeMem(psProcessStats);
+               *phProcessStats = 0;
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psProcessStats->psMemoryStats, 0, sizeof(PVRSRV_MEMORY_STATS));
+       psProcessStats->psMemoryStats->eStructureType = PVRSRV_STAT_STRUCTURE_MEMORY;
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       psProcessStats->psRIMemoryStats = OSAllocMem(sizeof(PVRSRV_RI_MEMORY_STATS));
+       if (psProcessStats->psRIMemoryStats == IMG_NULL)
+       {
+               OSFreeMem(psProcessStats->psMemoryStats);
+               OSFreeMem(psProcessStats);
+               *phProcessStats = 0;
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psProcessStats->psRIMemoryStats, 0, sizeof(PVRSRV_RI_MEMORY_STATS));
+       psProcessStats->psRIMemoryStats->eStructureType = PVRSRV_STAT_STRUCTURE_RIMEMORY;
+       psProcessStats->psRIMemoryStats->pid            = currentPid;
+#endif
+
+       /* Add it to the live list... */
+    OSLockAcquire(psLinkedListLock);
+       _AddProcessStatsToFrontOfLiveList(psProcessStats);
+       OSLockRelease(psLinkedListLock);
+
+       /* Create the process stat in the OS... */
+       OSSNPrintf(psProcessStats->szFolderName, sizeof(psProcessStats->szFolderName),
+                  "%d", currentPid);
+       _CreateOSStatisticEntries(psProcessStats, pvOSLivePidFolder);
+
+       /* Done */
+       *phProcessStats = (IMG_HANDLE) psProcessStats;
+
+       return PVRSRV_OK;
+} /* PVRSRVStatsRegisterProcess */
+
+
+/*************************************************************************/ /*!
+@Function       PVRSRVStatsDeregisterProcess
+@Input          hProcessStats  Handle to the process returned when registered.
+@Description    Method for destroying the statistics module data.
+*/ /**************************************************************************/
+IMG_VOID
+PVRSRVStatsDeregisterProcess(IMG_HANDLE hProcessStats)
+{
+       IMG_BOOL    bMoveProcess = IMG_FALSE;
+
+       if (hProcessStats != 0)
+       {
+               PVRSRV_PROCESS_STATS*  psProcessStats = (PVRSRV_PROCESS_STATS*) hProcessStats;
+
+               /* Lower the reference count, if zero then move it to the dead list */
+               OSLockAcquire(psLinkedListLock);
+               if (psProcessStats->ui32RefCount > 0)
+               {
+                       psProcessStats->ui32RefCount--;
+                       psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount;
+
+                       if (psProcessStats->ui32RefCount == 0)
+                       {
+                               _MoveProcessToDeadList(psProcessStats);
+                               bMoveProcess = IMG_TRUE;
+                       }
+               }
+               OSLockRelease(psLinkedListLock);
+
+               /* The OS calls need to be performed without psLinkedListLock */
+               if (bMoveProcess == IMG_TRUE)
+               {
+                       _MoveProcessToDeadListDebugFS(psProcessStats);
+               }
+
+               /* Check if the dead list needs to be reduced */
+               _CompressMemoryUsage();
+       }
+} /* PVRSRVStatsDeregisterProcess */
+
+
+IMG_VOID
+PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                             IMG_VOID *pvCpuVAddr,
+                             IMG_CPU_PHYADDR sCpuPAddr,
+                             IMG_SIZE_T uiBytes,
+                             IMG_PVOID pvPrivateData)
+{
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       IMG_PID                currentPid = OSGetCurrentProcessID();
+       IMG_PID                            currentCleanupPid = PVRSRVGetPurgeConnectionPid();
+    PVRSRV_DATA*                  psPVRSRVData = PVRSRVGetPVRSRVData();
+    PVRSRV_MEM_ALLOC_REC*  psRecord   = IMG_NULL;
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+    PVRSRV_MEMORY_STATS*   psMemoryStats;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       /*
+        *  To prevent a recursive loop, we make the memory allocations
+        *  for our memstat records via OSAllocMemstatMem(), which does not try to
+        *  create a memstat record entry..
+        */
+
+    /* Allocate the memory record... */
+       psRecord = OSAllocMemstatMem(sizeof(PVRSRV_MEM_ALLOC_REC));
+       if (psRecord == IMG_NULL)
+       {
+               return;
+       }
+
+       OSMemSet(psRecord, 0, sizeof(PVRSRV_MEM_ALLOC_REC));
+       psRecord->eAllocType       = eAllocType;
+       psRecord->pvCpuVAddr       = pvCpuVAddr;
+       psRecord->sCpuPAddr.uiAddr = sCpuPAddr.uiAddr;
+       psRecord->uiBytes          = uiBytes;
+       psRecord->pvPrivateData    = pvPrivateData;
+
+       /* Lock while we find the correct process... */
+       OSLockAcquire(psLinkedListLock);
+
+       _increase_global_stat(eAllocType, uiBytes);
+       
+       if (psPVRSRVData)
+       {
+               if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
+                          (currentCleanupPid != 0))
+               {
+                       psProcessStats = _FindProcessStats(currentCleanupPid);
+               }
+           else
+           {
+               psProcessStats = _FindProcessStats(currentPid);
+           }
+       }
+    else
+    {
+       psProcessStats = _FindProcessStats(currentPid);
+    }
+    if (psProcessStats == IMG_NULL)
+    {
+               OSLockRelease(psLinkedListLock);
+               if (psRecord != IMG_NULL)
+               {
+                       OSFreeMemstatMem(psRecord);
+               }
+               return;
+       }
+       psMemoryStats = psProcessStats->psMemoryStats;
+
+       /* Insert the memory record... */
+       if (psRecord != IMG_NULL)
+       {
+               List_PVRSRV_MEM_ALLOC_REC_Insert(&psMemoryStats->psMemoryRecords, psRecord);
+       }
+
+       /* Update the memory watermarks... */
+       switch (eAllocType)
+       {
+               case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               psRecord->ui64Key = sCpuPAddr.uiAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               psRecord->ui64Key = sCpuPAddr.uiAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               psRecord->ui64Key = sCpuPAddr.uiAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
+               }
+               break;
+
+               case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+               {
+                       if (psRecord != IMG_NULL)
+                       {
+                               if (pvCpuVAddr == IMG_NULL)
+                               {
+                                       return;
+                               }
+                               psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
+                       }
+                       INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
+               }
+               break;
+
+               default:
+               {
+                       PVR_ASSERT(0);
+               }
+               break;
+       }
+
+//Count total data
+psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] += psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
+UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC],
+                                psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC]);
+
+psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] += psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
+UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP],
+                                psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP]);
+
+       OSLockRelease(psLinkedListLock);
+#else
+PVR_UNREFERENCED_PARAMETER(eAllocType);
+PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
+PVR_UNREFERENCED_PARAMETER(sCpuPAddr);
+PVR_UNREFERENCED_PARAMETER(uiBytes);
+PVR_UNREFERENCED_PARAMETER(pvPrivateData);
+#endif
+} /* PVRSRVStatsAddMemAllocRecord */
+
+
+IMG_VOID
+PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_UINT64 ui64Key)
+{
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       IMG_PID                currentPid     = OSGetCurrentProcessID();
+       IMG_PID                            currentCleanupPid = PVRSRVGetPurgeConnectionPid();
+    PVRSRV_DATA*                  psPVRSRVData = PVRSRVGetPVRSRVData();
+    PVRSRV_PROCESS_STATS*  psProcessStats = IMG_NULL;
+       PVRSRV_MEMORY_STATS*   psMemoryStats  = IMG_NULL;
+       PVRSRV_MEM_ALLOC_REC*  psRecord       = IMG_NULL;
+    IMG_BOOL               bFound         = IMG_FALSE;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       /* Lock while we find the correct process and remove this record... */
+       OSLockAcquire(psLinkedListLock);
+
+       if (psPVRSRVData)
+       {
+               if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
+                        (currentCleanupPid != 0))
+               {
+                       psProcessStats = _FindProcessStats(currentCleanupPid);
+               }
+           else
+           {
+               psProcessStats = _FindProcessStats(currentPid);
+           }
+       }
+    else
+    {
+       psProcessStats = _FindProcessStats(currentPid);
+    }
+    if (psProcessStats != IMG_NULL)
+    {
+               psMemoryStats = psProcessStats->psMemoryStats;
+               psRecord      = psMemoryStats->psMemoryRecords;
+               while (psRecord != IMG_NULL)
+               {
+                       if (psRecord->ui64Key == ui64Key  &&  psRecord->eAllocType == eAllocType)
+                       {
+                               bFound = IMG_TRUE;
+                               break;
+                       }
+
+                       psRecord = psRecord->psNext;
+               }
+       }
+
+       /* If not found, we need to do a full search in case it was allocated to a different PID... */
+       if (!bFound)
+       {
+               PVRSRV_PROCESS_STATS*  psProcessStatsAlreadyChecked = psProcessStats;
+
+               /* Search all live lists first... */
+               psProcessStats = psLiveList;
+               while (psProcessStats != IMG_NULL)
+               {
+                       if (psProcessStats != psProcessStatsAlreadyChecked)
+                       {
+                               psMemoryStats = psProcessStats->psMemoryStats;
+                               psRecord      = psMemoryStats->psMemoryRecords;
+                               while (psRecord != IMG_NULL)
+                               {
+                                       if (psRecord->ui64Key == ui64Key  &&  psRecord->eAllocType == eAllocType)
+                                       {
+                                               bFound = IMG_TRUE;
+                                               break;
+                                       }
+
+                                       psRecord = psRecord->psNext;
+                               }
+                       }
+
+                       if (bFound)
+                       {
+                               break;
+                       }
+
+                       psProcessStats = psProcessStats->psNext;
+               }
+
+               /* If not found, then search all dead lists next... */
+               if (!bFound)
+               {
+                       psProcessStats = psDeadList;
+                       while (psProcessStats != IMG_NULL)
+                       {
+                               if (psProcessStats != psProcessStatsAlreadyChecked)
+                               {
+                                       psMemoryStats = psProcessStats->psMemoryStats;
+                                       psRecord      = psMemoryStats->psMemoryRecords;
+                                       while (psRecord != IMG_NULL)
+                                       {
+                                               if (psRecord->ui64Key == ui64Key  &&  psRecord->eAllocType == eAllocType)
+                                               {
+                                                       bFound = IMG_TRUE;
+                                                       break;
+                                               }
+
+                                               psRecord = psRecord->psNext;
+                                       }
+                               }
+
+                               if (bFound)
+                               {
+                                       break;
+                               }
+
+                               psProcessStats = psProcessStats->psNext;
+                       }
+               }
+       }
+
+       /* Update the watermark and remove this record...*/
+       if (bFound)
+       {
+               _decrease_global_stat(eAllocType, psRecord->uiBytes);
+       
+               switch (eAllocType)
+               {
+                       case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, psRecord->uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, psRecord->uiBytes);
+                       }
+                       break;
+
+                       default:
+                       {
+                               PVR_ASSERT(0);
+                       }
+                       break;
+               }
+
+               List_PVRSRV_MEM_ALLOC_REC_Remove(psRecord);
+       }
+//Count total data
+psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
+
+psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
+    psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
+
+       OSLockRelease(psLinkedListLock);
+
+       /*
+        * Free the record outside the lock so we don't deadlock and so we
+        * reduce the time the lock is held.
+        */
+       if (psRecord != IMG_NULL)
+       {
+               OSFreeMemstatMem(psRecord);
+       }
+#else
+PVR_UNREFERENCED_PARAMETER(eAllocType);
+PVR_UNREFERENCED_PARAMETER(ui64Key);
+#endif
+} /* PVRSRVStatsRemoveMemAllocRecord */
+
+IMG_VOID
+PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_SIZE_T uiBytes,
+                                                               IMG_UINT64 uiCpuVAddr)
+{
+       IMG_BOOL bRes;
+
+       if (!bProcessStatsInitialised || (gpsVmallocSizeHashTable == NULL) )
+       {
+               return;
+       }
+
+       OSLockAcquire(gpsVmallocSizeHashTableLock);
+       bRes = HASH_Insert(gpsVmallocSizeHashTable, uiCpuVAddr, uiBytes);
+       OSLockRelease(gpsVmallocSizeHashTableLock);
+       if (bRes)
+       {
+               PVRSRVStatsIncrMemAllocStat(eAllocType, uiBytes);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "*** %s : @ line %d HASH_Insert() failed!!", __FUNCTION__, __LINE__));
+       }
+}
+
+IMG_VOID
+PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_SIZE_T uiBytes)
+{
+       IMG_PID                currentPid = OSGetCurrentProcessID();
+       IMG_PID                            currentCleanupPid = PVRSRVGetPurgeConnectionPid();
+    PVRSRV_DATA*                  psPVRSRVData = PVRSRVGetPVRSRVData();
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       _increase_global_stat(eAllocType, uiBytes);
+
+       OSLockAcquire(psLinkedListLock);
+
+       if (psPVRSRVData)
+       {
+               if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
+                        (currentCleanupPid != 0))
+               {
+                       psProcessStats = _FindProcessStats(currentCleanupPid);
+               }
+           else
+           {
+               psProcessStats = _FindProcessStats(currentPid);
+           }
+       }
+    else
+    {
+       psProcessStats = _FindProcessStats(currentPid);
+    }
+
+    if (psProcessStats != IMG_NULL)
+    {
+               /* Update the memory watermarks... */
+               switch (eAllocType)
+               {
+                       case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+                       {
+                               INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       default:
+                       {
+                               PVR_ASSERT(0);
+                       }
+                       break;
+               }
+        //Count total data
+        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
+        UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC],
+                        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC]);
+
+        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
+        UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP],
+                        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP]);
+    }
+
+       OSLockRelease(psLinkedListLock);
+}
+
+IMG_VOID
+PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                      IMG_UINT64 uiCpuVAddr)
+{
+       IMG_SIZE_T uiBytes;
+
+       if (!bProcessStatsInitialised || (gpsVmallocSizeHashTable == NULL) )
+       {
+               return;
+       }
+
+       OSLockAcquire(gpsVmallocSizeHashTableLock);
+       uiBytes = HASH_Remove(gpsVmallocSizeHashTable, uiCpuVAddr);
+       OSLockRelease(gpsVmallocSizeHashTableLock);
+
+       PVRSRVStatsDecrMemAllocStat(eAllocType, uiBytes);
+}
+
+IMG_VOID
+PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                            IMG_SIZE_T uiBytes)
+{
+       IMG_PID                currentPid = OSGetCurrentProcessID();
+       IMG_PID                            currentCleanupPid = PVRSRVGetPurgeConnectionPid();
+    PVRSRV_DATA*                  psPVRSRVData = PVRSRVGetPVRSRVData();
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       _decrease_global_stat(eAllocType, uiBytes);
+
+       OSLockAcquire(psLinkedListLock);
+
+       if (psPVRSRVData)
+       {
+               if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
+                        (currentCleanupPid != 0))
+               {
+                       psProcessStats = _FindProcessStats(currentCleanupPid);
+               }
+           else
+           {
+               psProcessStats = _FindProcessStats(currentPid);
+               }
+       }
+    else
+    {
+       psProcessStats = _FindProcessStats(currentPid);
+       }
+    if (psProcessStats != IMG_NULL)
+    {
+               /* Update the memory watermarks... */
+               switch (eAllocType)
+               {
+                       case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
+                       {
+                               DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
+                       }
+                       break;
+
+                       default:
+                       {
+                               PVR_ASSERT(0);
+                       }
+                       break;
+               }
+               //Count total data
+        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
+
+        psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
+            psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
+       }
+
+       OSLockRelease(psLinkedListLock);
+}
+
+/* For now we do not want to expose the global stats API
+ * so we wrap it into this specific function for pooled pages.
+ * As soon as we need to modify the global stats directly somewhere else
+ * we want to replace these functions with more general ones.
+ */
+IMG_VOID
+PVRSRVStatsIncrMemAllocPoolStat(IMG_SIZE_T uiBytes)
+{
+       _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes);
+}
+
+IMG_VOID
+PVRSRVStatsDecrMemAllocPoolStat(IMG_SIZE_T uiBytes)
+{
+       _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes);
+}
+
+IMG_VOID
+PVRSRVStatsUpdateRenderContextStats(IMG_UINT32 ui32TotalNumPartialRenders,
+                                    IMG_UINT32 ui32TotalNumOutOfMemory,
+                                    IMG_UINT32 ui32NumTAStores,
+                                    IMG_UINT32 ui32Num3DStores,
+                                    IMG_UINT32 ui32NumSHStores,
+                                    IMG_UINT32 ui32NumCDMStores,
+                                    IMG_PID pidOwner)
+{
+       //IMG_PID                currentPid = OSGetCurrentProcessID();
+       IMG_PID pidCurrent=pidOwner;
+
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       /* Lock while we find the correct process and update the record... */
+       OSLockAcquire(psLinkedListLock);
+
+    psProcessStats = _FindProcessStats(pidCurrent);
+    if (psProcessStats != IMG_NULL)
+    {
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_PRS]       += ui32TotalNumPartialRenders;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_OOMS]      += ui32TotalNumOutOfMemory;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES] += ui32NumTAStores;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES] += ui32Num3DStores;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES] += ui32NumSHStores;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES]+= ui32NumCDMStores;
+       }
+    else
+    {
+       PVR_DPF((PVR_DBG_WARNING, "PVRSRVStatsUpdateRenderContextStats: Null process. Pid=%d", pidCurrent));
+    }
+
+       OSLockRelease(psLinkedListLock);
+} /* PVRSRVStatsUpdateRenderContextStats */
+
+
+IMG_VOID
+PVRSRVStatsUpdateZSBufferStats(IMG_UINT32 ui32NumReqByApp,
+                               IMG_UINT32 ui32NumReqByFW,
+                               IMG_PID owner)
+{
+       IMG_PID                currentPid = (owner==0)?OSGetCurrentProcessID():owner;
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       /* Lock while we find the correct process and update the record... */
+       OSLockAcquire(psLinkedListLock);
+
+    psProcessStats = _FindProcessStats(currentPid);
+    if (psProcessStats != IMG_NULL)
+    {
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP] += ui32NumReqByApp;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW]  += ui32NumReqByFW;
+       }
+
+       OSLockRelease(psLinkedListLock);
+} /* PVRSRVStatsUpdateZSBufferStats */
+
+
+IMG_VOID
+PVRSRVStatsUpdateFreelistStats(IMG_UINT32 ui32NumGrowReqByApp,
+                               IMG_UINT32 ui32NumGrowReqByFW,
+                               IMG_UINT32 ui32InitFLPages,
+                               IMG_UINT32 ui32NumHighPages,
+                               IMG_PID ownerPid)
+{
+       IMG_PID                currentPid = (ownerPid!=0)?ownerPid:OSGetCurrentProcessID();
+    PVRSRV_PROCESS_STATS*  psProcessStats;
+
+    /* Don't do anything if we are not initialised or we are shutting down! */
+    if (!bProcessStatsInitialised)
+    {
+               return;
+       }
+
+       /* Lock while we find the correct process and update the record... */
+       OSLockAcquire(psLinkedListLock);
+
+       psProcessStats = _FindProcessStats(currentPid);
+
+    if (psProcessStats != IMG_NULL)
+    {
+               /* Avoid signed / unsigned mismatch which is flagged by some compilers */
+               IMG_INT32 a, b;
+
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP] += ui32NumGrowReqByApp;
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW]  += ui32NumGrowReqByFW;
+
+               a=psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT];
+               b=(IMG_INT32)(ui32InitFLPages);
+               UPDATE_MAX_VALUE(a, b);
+
+
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT]=a;
+               ui32InitFLPages=(IMG_UINT32)b;
+
+               a=psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES];
+               b=(IMG_INT32)ui32NumHighPages;
+
+               UPDATE_MAX_VALUE(a, b);
+               psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT]=a;
+               ui32InitFLPages=(IMG_UINT32)b;
+
+       }
+
+       OSLockRelease(psLinkedListLock);
+} /* PVRSRVStatsUpdateFreelistStats */
+
+
+/*************************************************************************/ /*!
+@Function       ProcessStatsPrintElements
+@Description    Prints all elements for this process statistic record.
+@Input          pvFilePtr         Pointer to seq_file.
+@Input          pvStatPtr         Pointer to statistics structure.
+@Input          pfnOSStatsPrintf  Printf function to use for output.
+*/ /**************************************************************************/
+IMG_VOID
+ProcessStatsPrintElements(IMG_PVOID pvFilePtr,
+                                                 IMG_PVOID pvStatPtr,
+                          OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+       PVRSRV_STAT_STRUCTURE_TYPE*  peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
+       PVRSRV_PROCESS_STATS*        psProcessStats  = (PVRSRV_PROCESS_STATS*) pvStatPtr;
+       IMG_UINT32                   ui32StatNumber = 0;
+
+       if (peStructureType == IMG_NULL  ||  *peStructureType != PVRSRV_STAT_STRUCTURE_PROCESS)
+       {
+               PVR_ASSERT(peStructureType != IMG_NULL  &&  *peStructureType == PVRSRV_STAT_STRUCTURE_PROCESS);
+               return;
+       }
+
+       if (pfnOSStatsPrintf == NULL)
+       {
+               return;
+       }
+
+       /* Loop through all the values and print them... */
+    while (ui32StatNumber < PVRSRV_PROCESS_STAT_TYPE_COUNT)
+    {
+        if (psProcessStats->ui32MemRefCount > 0)
+        {
+            pfnOSStatsPrintf(pvFilePtr, pszProcessStatFmt[ui32StatNumber], psProcessStats->i32StatValue[ui32StatNumber]);
+        }
+        else
+        {
+            PVR_DPF((PVR_DBG_ERROR, "%s: Called with psProcessStats->ui32MemRefCount=%d", __FUNCTION__, psProcessStats->ui32MemRefCount));
+        }
+        ui32StatNumber++;
+    }
+} /* ProcessStatsPrintElements */
+
+
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+/*************************************************************************/ /*!
+@Function       MemStatsPrintElements
+@Description    Prints all elements for the memory statistic record.
+@Input          pvFilePtr         Pointer to seq_file.
+@Input          pvStatPtr         Pointer to statistics structure.
+@Input          pfnOSStatsPrintf  Printf function to use for output.
+*/ /**************************************************************************/
+IMG_VOID
+MemStatsPrintElements(IMG_PVOID pvFilePtr,
+                                         IMG_PVOID pvStatPtr,
+                      OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+       PVRSRV_STAT_STRUCTURE_TYPE*  peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
+       PVRSRV_MEMORY_STATS*         psMemoryStats   = (PVRSRV_MEMORY_STATS*) pvStatPtr;
+       IMG_UINT32      ui32VAddrFields = sizeof(IMG_VOID*)/sizeof(IMG_UINT32);
+       IMG_UINT32      ui32PAddrFields = sizeof(IMG_CPU_PHYADDR)/sizeof(IMG_UINT32);
+       PVRSRV_MEM_ALLOC_REC  *psRecord;
+       IMG_UINT32  ui32ItemNumber;
+
+       if (peStructureType == IMG_NULL  ||  *peStructureType != PVRSRV_STAT_STRUCTURE_MEMORY)
+       {
+               PVR_ASSERT(peStructureType != IMG_NULL  &&  *peStructureType == PVRSRV_STAT_STRUCTURE_MEMORY);
+               return;
+       }
+
+       if (pfnOSStatsPrintf == NULL)
+       {
+               return;
+       }
+
+       /* Write the header... */
+    pfnOSStatsPrintf(pvFilePtr, "Type                VAddress");
+       for (ui32ItemNumber = 1;  ui32ItemNumber < ui32VAddrFields;  ui32ItemNumber++)
+       {
+        pfnOSStatsPrintf(pvFilePtr, "        ");
+       }
+
+    pfnOSStatsPrintf(pvFilePtr, "  PAddress");
+       for (ui32ItemNumber = 1;  ui32ItemNumber < ui32PAddrFields;  ui32ItemNumber++)
+       {
+        pfnOSStatsPrintf(pvFilePtr, "        ");
+       }
+
+    pfnOSStatsPrintf(pvFilePtr, "  Size(bytes)\n");
+
+       /* The lock has to be held whilst moving through the memory list... */
+       OSLockAcquire(psLinkedListLock);
+       psRecord = psMemoryStats->psMemoryRecords;
+
+       while (psRecord != IMG_NULL)
+       {
+               switch (psRecord->eAllocType)
+               {
+            case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:                pfnOSStatsPrintf(pvFilePtr, "KMALLOC             "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:                pfnOSStatsPrintf(pvFilePtr, "VMALLOC             "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:  pfnOSStatsPrintf(pvFilePtr, "ALLOC_PAGES_PT_LMA  "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:  pfnOSStatsPrintf(pvFilePtr, "ALLOC_PAGES_PT_UMA  "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:      pfnOSStatsPrintf(pvFilePtr, "IOREMAP_PT_LMA      "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:         pfnOSStatsPrintf(pvFilePtr, "VMAP_PT_UMA         "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:        pfnOSStatsPrintf(pvFilePtr, "ALLOC_LMA_PAGES     "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:        pfnOSStatsPrintf(pvFilePtr, "ALLOC_UMA_PAGES     "); break;
+            case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:      pfnOSStatsPrintf(pvFilePtr, "MAP_UMA_LMA_PAGES   "); break;
+            default:                                           pfnOSStatsPrintf(pvFilePtr, "INVALID             "); break;
+               }
+
+               for (ui32ItemNumber = 0;  ui32ItemNumber < ui32VAddrFields;  ui32ItemNumber++)
+               {
+            pfnOSStatsPrintf(pvFilePtr, "%08x", *(((IMG_UINT32*) &psRecord->pvCpuVAddr) + ui32VAddrFields - ui32ItemNumber - 1));
+               }
+        pfnOSStatsPrintf(pvFilePtr, "  ");
+
+               for (ui32ItemNumber = 0;  ui32ItemNumber < ui32PAddrFields;  ui32ItemNumber++)
+               {
+            pfnOSStatsPrintf(pvFilePtr, "%08x", *(((IMG_UINT32*) &psRecord->sCpuPAddr.uiAddr) + ui32PAddrFields - ui32ItemNumber - 1));
+               }
+
+        pfnOSStatsPrintf(pvFilePtr, "  %u\n", psRecord->uiBytes);
+
+               /* Move to next record... */
+               psRecord = psRecord->psNext;
+       }
+
+       OSLockRelease(psLinkedListLock);
+} /* MemStatsPrintElements */
+#endif
+
+
+#if defined(PVR_RI_DEBUG)
+/*************************************************************************/ /*!
+@Function       RIMemStatsPrintElements
+@Description    Prints all elements for the RI Memory record.
+@Input          pvFilePtr         Pointer to seq_file.
+@Input          pvStatPtr         Pointer to statistics structure.
+@Input          pfnOSStatsPrintf  Printf function to use for output.
+*/ /**************************************************************************/
+IMG_VOID
+RIMemStatsPrintElements(IMG_PVOID pvFilePtr,
+                                               IMG_PVOID pvStatPtr,
+                        OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+       PVRSRV_STAT_STRUCTURE_TYPE  *peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
+       PVRSRV_RI_MEMORY_STATS      *psRIMemoryStats = (PVRSRV_RI_MEMORY_STATS*) pvStatPtr;
+       IMG_CHAR                    *pszStatFmtText  = IMG_NULL;
+       IMG_HANDLE                  *pRIHandle       = IMG_NULL;
+
+       if (peStructureType == IMG_NULL  ||  *peStructureType != PVRSRV_STAT_STRUCTURE_RIMEMORY)
+       {
+               PVR_ASSERT(peStructureType != IMG_NULL  &&  *peStructureType == PVRSRV_STAT_STRUCTURE_RIMEMORY);
+               return;
+       }
+
+       if (pfnOSStatsPrintf == NULL)
+       {
+               return;
+       }
+
+       /*
+        *  Loop through the RI system to get each line of text.
+        */
+       while (RIGetListEntryKM(psRIMemoryStats->pid,
+                                                       &pRIHandle,
+                                                       &pszStatFmtText))
+       {
+        pfnOSStatsPrintf(pvFilePtr, "%s", pszStatFmtText);
+       }
+} /* RIMemStatsPrintElements */
+#endif
+
+
+static IMG_UINT32      ui32FirmwareStartTimestamp=0;
+static IMG_UINT64      ui64FirmwareIdleDuration=0;
+
+/* Averaging each new value with the previous accumulated knowledge. There are many coefficients for that
+ * (e.g.) 50 / 50 but i chose 75 / 25 meaning that previous knowledge affects the weighted average more
+ * than any new knowledge. As time goes by though eventually the number converges to the most commonly used
+ */
+
+IMG_VOID SetFirmwareStartTime(IMG_UINT32 ui32Time)
+{
+    if (ui32FirmwareStartTimestamp > 0)
+    {
+        ui32FirmwareStartTimestamp = MEAN_TIME(ui32FirmwareStartTimestamp, ui32Time);
+    }
+    else
+    {
+        ui32FirmwareStartTimestamp = ui32Time;
+    }
+}
+
+IMG_VOID SetFirmwareHandshakeIdleTime(IMG_UINT64 ui64Duration)
+{
+    if (ui64FirmwareIdleDuration > 0)
+       {
+        ui64FirmwareIdleDuration = MEAN_TIME(ui64FirmwareIdleDuration, ui64Duration);
+       }
+       else
+       {
+               ui64FirmwareIdleDuration = ui64Duration;
+       }
+}
+
+
+IMG_VOID PowerStatsPrintElements(IMG_PVOID pvFilePtr,
+                                 IMG_PVOID pvStatPtr,
+                                 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+       IMG_UINT32                      ui32Idx;
+
+       PVR_UNREFERENCED_PARAMETER(pvStatPtr);
+
+       if (pfnOSStatsPrintf == NULL)
+       {
+               return;
+       }
+
+       if (ui64TotalForcedEntries > 0)
+       {
+        pfnOSStatsPrintf(pvFilePtr, "Forced Power Transition (nanoseconds):\n");
+        pfnOSStatsPrintf(pvFilePtr, "Pre-Device:  %u\n", (IMG_UINT32)(ui64ForcedPreDevice)  / (IMG_UINT32)(ui64TotalForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Pre-System:  %u\n", (IMG_UINT32)(ui64ForcedPreSystem)  / (IMG_UINT32)(ui64TotalForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Post-Device: %u\n", (IMG_UINT32)(ui64ForcedPostDevice) / (IMG_UINT32)(ui64TotalForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Post-System: %u\n", (IMG_UINT32)(ui64ForcedPostSystem) / (IMG_UINT32)(ui64TotalForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "\n");
+       }
+
+       if (ui64TotalNotForcedEntries > 0)
+       {
+        pfnOSStatsPrintf(pvFilePtr, "Not Forced Power Transition (nanoseconds):\n");
+        pfnOSStatsPrintf(pvFilePtr, "Pre-Device:  %u\n", (IMG_UINT32)(ui64NotForcedPreDevice)  / (IMG_UINT32)(ui64TotalNotForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Pre-System:  %u\n", (IMG_UINT32)(ui64NotForcedPreSystem)  / (IMG_UINT32)(ui64TotalNotForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Post-Device: %u\n", (IMG_UINT32)(ui64NotForcedPostDevice) / (IMG_UINT32)(ui64TotalNotForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "Post-System: %u\n", (IMG_UINT32)(ui64NotForcedPostSystem) / (IMG_UINT32)(ui64TotalNotForcedEntries));
+        pfnOSStatsPrintf(pvFilePtr, "\n");
+       }
+
+    pfnOSStatsPrintf(pvFilePtr, "FW bootup time (timer ticks): %u\n", ui32FirmwareStartTimestamp);
+    pfnOSStatsPrintf(pvFilePtr, "Host Acknowledge Time for FW Idle Signal (timer ticks): %u\n", (IMG_UINT32)(ui64FirmwareIdleDuration));
+    pfnOSStatsPrintf(pvFilePtr, "\n");
+
+    pfnOSStatsPrintf(pvFilePtr, "Last %d Clock Speed Change Timers (nanoseconds):\n", NUM_EXTRA_POWER_STATS);
+    pfnOSStatsPrintf(pvFilePtr, "Prepare DVFS\tDVFS Change\tPost DVFS\n");
+
+       for (ui32Idx = ui32ClockSpeedIndexStart; ui32Idx !=ui32ClockSpeedIndexEnd; ui32Idx = (ui32Idx + 1) % NUM_EXTRA_POWER_STATS)
+       {
+        pfnOSStatsPrintf(pvFilePtr, "%12llu\t%11llu\t%9llu\n",asClockSpeedChanges[ui32Idx].ui64PreClockSpeedChangeDuration,
+                                                                                                asClockSpeedChanges[ui32Idx].ui64BetweenPreEndingAndPostStartingDuration,
+                                                                                                asClockSpeedChanges[ui32Idx].ui64PostClockSpeedChangeDuration);
+       }
+
+
+} /* PowerStatsPrintElements */
+
+
+IMG_VOID GlobalStatsPrintElements(IMG_PVOID pvFilePtr,
+                                  IMG_PVOID pvStatPtr,
+                                  OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf)
+{
+       PVR_UNREFERENCED_PARAMETER(pvStatPtr);
+
+       if (pfnOSGetStatsPrintf != IMG_NULL)
+       {
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageKMalloc                %10d\n", gsGlobalStats.ui32MemoryUsageKMalloc);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageKMallocMax             %10d\n", gsGlobalStats.ui32MemoryUsageKMallocMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMalloc                %10d\n", gsGlobalStats.ui32MemoryUsageVMalloc);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMallocMax             %10d\n", gsGlobalStats.ui32MemoryUsageVMallocMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryUMA       %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryUMAMax    %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMapPTUMA              %10d\n", gsGlobalStats.ui32MemoryUsageVMapPTUMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMapPTUMAMax           %10d\n", gsGlobalStats.ui32MemoryUsageVMapPTUMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryLMA       %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryLMAMax    %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageIORemapPTLMA           %10d\n", gsGlobalStats.ui32MemoryUsageIORemapPTLMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageIORemapPTLMAMax        %10d\n", gsGlobalStats.ui32MemoryUsageIORemapPTLMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemLMA         %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemLMAMax      %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemLMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMA         %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAMax      %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAPool     %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAPoolMax  %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPoolMax);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageMappedGPUMemUMA/LMA    %10d\n", gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA);
+        pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageMappedGPUMemUMA/LMAMax %10d\n", gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMAMax);
+
+               //zxl: count total data 
+               pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalAlloc             %10d\n",gsGlobalStats.ui32MemoryUsageTotalAlloc);
+               pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalAllocMax          %10d\n",gsGlobalStats.ui32MemoryUsageTotalAllocMax);
+               pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalMap               %10d\n",gsGlobalStats.ui32MemoryUsageTotalMap);
+               pfnOSGetStatsPrintf(pvFilePtr, "ui32MemoryUsageTotalMapMax        %10d\n",gsGlobalStats.ui32MemoryUsageTotalMapMax);
+       }
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/pvrsrv.c b/drivers/gpu/rogue_m/services/server/common/pvrsrv.c
new file mode 100644 (file)
index 0000000..83641db
--- /dev/null
@@ -0,0 +1,2850 @@
+/*************************************************************************/ /*!
+@File
+@Title          core services functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main APIs for core services functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "rgxdebug.h"
+#include "handle.h"
+#include "connection_server.h"
+#include "pdump_km.h"
+#include "ra.h"
+#include "allocmem.h"
+#include "pmr.h"
+#include "pvrsrv.h"
+#include "pvrsrv_device.h"
+#include "pvr_debug.h"
+#include "sync.h"
+#include "sync_server.h"
+#include "devicemem.h"
+
+#include "pvrversion.h"
+
+#include "lists.h"
+#include "dllist.h"
+#include "syscommon.h"
+
+#include "physmem_lma.h"
+#include "physmem_osmem.h"
+
+#include "tlintern.h"
+
+#if defined (SUPPORT_RGX)
+#include "rgxinit.h"
+#include "rgxfwutils.h"
+#endif
+
+#include "debug_request_ids.h"
+#include "pvrsrv.h"
+
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+       #if !defined(GPUVIRT_SIZEOF_ARENA0)
+               #define GPUVIRT_SIZEOF_ARENA0   64 * 1024 * 1024 //Giving 64 megs of LMA memory to arena 0 for firmware and other allocations
+       #endif
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#include "devicemem_history_server.h"
+#endif
+
+#if defined(PVR_DVFS)
+#include "pvr_dvfs_device.h"
+#endif
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+#include "dc_server.h"
+#endif
+
+/*! Wait 100ms before retrying deferred clean-up again */
+#define CLEANUP_THREAD_WAIT_RETRY_TIMEOUT 0x00000064
+
+/*! Wait 8hrs when no deferred clean-up required. Allows a poll several times
+ * a day to check for any missed clean-up. */
+#define CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT 0x01B77400
+
+
+typedef struct DEBUG_REQUEST_ENTRY_TAG
+{
+       IMG_UINT32              ui32RequesterID;
+       DLLIST_NODE             sListHead;
+} DEBUG_REQUEST_ENTRY;
+
+typedef struct DEBUG_REQUEST_TABLE_TAG
+{
+       IMG_UINT32                              ui32RequestCount;
+       DEBUG_REQUEST_ENTRY             asEntry[1];
+}DEBUG_REQUEST_TABLE;
+
+static PVRSRV_DATA     *gpsPVRSRVData = IMG_NULL;
+static IMG_HANDLE   g_hDbgSysNotify;
+
+static PVRSRV_SYSTEM_CONFIG *gpsSysConfig = IMG_NULL;
+
+typedef PVRSRV_ERROR (*PFN_REGISTER_DEVICE)(PVRSRV_DEVICE_NODE *psDeviceNode);
+typedef PVRSRV_ERROR (*PFN_UNREGISTER_DEVICE)(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+static PFN_REGISTER_DEVICE sRegisterDevice[PVRSRV_DEVICE_TYPE_LAST + 1];
+static PFN_UNREGISTER_DEVICE sUnregisterDevice[PVRSRV_DEVICE_TYPE_LAST + 1];
+
+static PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PVRSRV_DEVICE_CONFIG *psDevConfig);
+static PVRSRV_ERROR IMG_CALLCONV PVRSRVUnregisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+static PVRSRV_ERROR PVRSRVRegisterDbgTable(IMG_UINT32 *paui32Table, IMG_UINT32 ui32Length, IMG_PVOID *phTable);
+static IMG_VOID PVRSRVUnregisterDbgTable(IMG_PVOID hTable);
+
+static IMG_VOID _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel);
+
+IMG_UINT32     g_ui32InitFlags;
+
+/* mark which parts of Services were initialised */
+#define                INIT_DATA_ENABLE_PDUMPINIT      0x1U
+
+/* Head of the list of callbacks called when Cmd complete happens */
+static DLLIST_NODE sCmdCompNotifyHead;
+static POSWR_LOCK hNotifyLock = IMG_NULL;
+
+/* Debug request table and lock */
+static POSWR_LOCK g_hDbgNotifyLock = IMG_NULL;
+static DEBUG_REQUEST_TABLE *g_psDebugTable;
+
+static IMG_PVOID g_hDebugTable = IMG_NULL;
+
+static IMG_UINT32 g_aui32DebugOrderTable[] = {
+       DEBUG_REQUEST_SYS,
+       DEBUG_REQUEST_RGX,
+       DEBUG_REQUEST_DC,
+       DEBUG_REQUEST_SERVERSYNC,
+       DEBUG_REQUEST_ANDROIDSYNC
+};
+
+DUMPDEBUG_PRINTF_FUNC *g_pfnDumpDebugPrintf = IMG_NULL;
+
+/*!
+******************************************************************************
+
+ @Function     AllocateDeviceID
+
+ @Description
+
+ allocates a device id from the pool of valid ids
+
+ @input psPVRSRVData : Services private data
+
+ @input pui32DevID : device id to return
+
+ @Return device id
+
+******************************************************************************/
+static PVRSRV_ERROR AllocateDeviceID(PVRSRV_DATA *psPVRSRVData, IMG_UINT32 *pui32DevID)
+{
+       SYS_DEVICE_ID* psDeviceWalker;
+       SYS_DEVICE_ID* psDeviceEnd;
+
+       psDeviceWalker = &psPVRSRVData->sDeviceID[0];
+       psDeviceEnd = psDeviceWalker + SYS_DEVICE_COUNT;
+
+       /* find a free ID */
+       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!"));
+
+       /* Should never get here: sDeviceID[] may have been setup too small */
+       PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+       return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVAILABLE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     FreeDeviceID
+
+ @Description
+
+ frees a device id from the pool of valid ids
+
+ @input psPVRSRVData : Services private data
+
+ @input ui32DevID : device id to free
+
+ @Return device id
+
+******************************************************************************/
+static PVRSRV_ERROR FreeDeviceID(PVRSRV_DATA *psPVRSRVData, IMG_UINT32 ui32DevID)
+{
+       SYS_DEVICE_ID* psDeviceWalker;
+       SYS_DEVICE_ID* psDeviceEnd;
+
+       psDeviceWalker = &psPVRSRVData->sDeviceID[0];
+       psDeviceEnd = psDeviceWalker + SYS_DEVICE_COUNT;
+
+       /* find the ID to free */
+       while (psDeviceWalker < psDeviceEnd)
+       {
+               /* if matching id and in use, free */
+               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!"));
+
+       /* should never get here */
+       PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+       return PVRSRV_ERROR_INVALID_DEVICEID;
+}
+
+
+/*!
+******************************************************************************
+ @Function     PVRSRVEnumerateDevicesKM_ForEachVaCb
+
+ @Description
+
+ Enumerates the device node (if is of the same class as given).
+
+ @Input psDeviceNode   - The device node to be enumerated
+               va                              - variable arguments list, with:
+                                                       pui32DevCount   - The device count pointer (to be increased)
+                                                       ppeDeviceType     - The pointer to the device type pointer (to be updated and increased)
+                                                       ppeDeviceClass    - The pointer to the device classes pointer (to be updated and increased)
+                                                       ppui32DeviceIndex - The pointer to the device indexes pointer (to be updated and increased)
+******************************************************************************/
+static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+       IMG_UINT *pui32DevCount;
+       PVRSRV_DEVICE_TYPE **ppeDeviceType;
+       PVRSRV_DEVICE_CLASS **ppeDeviceClass;
+       IMG_UINT32 **ppui32DeviceIndex;
+
+       pui32DevCount = va_arg(va, IMG_UINT*);
+       ppeDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE**);
+       ppeDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS**);
+       ppui32DeviceIndex = va_arg(va, IMG_UINT32**);
+
+       if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
+       {
+               **ppeDeviceType = psDeviceNode->sDevId.eDeviceType;
+               **ppeDeviceClass = psDeviceNode->sDevId.eDeviceClass;
+               **ppui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
+
+               (*ppeDeviceType)++;
+               (*ppeDeviceClass)++;
+               (*ppui32DeviceIndex)++;
+
+               (*pui32DevCount)++;
+       }
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnumerateDevicesKM
+
+ @Description
+ This function will enumerate all the devices supported by the
+ PowerVR services within the target system.
+ The function returns a list of the device ID structures stored either in
+ the services or constructed in the user mode glue component in certain
+ environments. The number of devices in the list is also returned.
+
+ In a binary layered component which does not support dynamic runtime selection,
+ the glue code should compile to return the supported devices statically,
+ e.g. multiple instances of the same device if multiple devices are supported,
+ or the target combination of Rogue and display device.
+
+ In the case of an environment (for instance) where one Rogue may connect to two
+ display devices this code would enumerate all three devices and even
+ non-dynamic Rogue selection code should retain the facility to parse the list
+ to find the index of the Rogue device
+
+ @output pui32NumDevices :     On success, contains the number of devices present
+                                                       in the system
+
+ @output peDeviceType   :      Pointer to called supplied buffer to receive the
+                                                       list of PVRSRV_DEVICE_TYPE
+
+ @output peDeviceClass  :      Pointer to called supplied buffer to receive the
+                                                       list of PVRSRV_DEVICE_CLASS
+
+ @output pui32DeviceIndex:     Pointer to called supplied buffer to receive the
+                                                       list of device indexes
+
+ @return PVRSRV_ERROR  :       
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+                                                   PVRSRV_DEVICE_TYPE *peDeviceType,
+                                                   PVRSRV_DEVICE_CLASS *peDeviceClass,
+                                                   IMG_UINT32 *pui32DeviceIndex)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       IMG_UINT32                      i;
+
+       if (!pui32NumDevices || !peDeviceType || !peDeviceClass || !pui32DeviceIndex)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /*
+               setup input buffer to be `empty'
+       */
+       for (i=0; i<PVRSRV_MAX_DEVICES; i++)
+       {
+               peDeviceType[i] = PVRSRV_DEVICE_TYPE_UNKNOWN;
+       }
+
+       /* and zero device count */
+       *pui32NumDevices = 0;
+
+       /*
+               Search through the device list for services managed devices
+               return id info for each device and the number of devices
+               available
+       */
+       List_PVRSRV_DEVICE_NODE_ForEach_va(psPVRSRVData->psDeviceNodeList,
+                                                                          &PVRSRVEnumerateDevicesKM_ForEachVaCb,
+                                                                          pui32NumDevices,
+                                                                          &peDeviceType,
+                                                                          &peDeviceClass,
+                                                                          &pui32DeviceIndex);
+
+       return PVRSRV_OK;
+}
+
+/* Add work to the cleanup thread work list.
+ * The work item will be executed by the cleanup thread
+ */
+void PVRSRVCleanupThreadAddWork(PVRSRV_CLEANUP_THREAD_WORK *psData)
+{
+       PVRSRV_DATA *psPVRSRVData;
+       PVRSRV_ERROR eError;
+
+       psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       PVR_ASSERT(psData != NULL);
+
+       if(psPVRSRVData->bUnload)
+       {
+               CLEANUP_THREAD_FN pfnFree = psData->pfnFree;
+
+               PVR_DPF((PVR_DBG_MESSAGE, "Cleanup thread has already quit: doing work immediately"));
+
+               eError = pfnFree(psData->pvData);
+
+               if(eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to free resource "
+                                               "(callback " IMG_PFN_FMTSPEC "). "
+                                               "Immediate free will not be retried.",
+                                               pfnFree));
+               }
+       }
+       else
+       {
+               /* add this work item to the list */
+               OSLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock);
+               dllist_add_to_tail(&psPVRSRVData->sCleanupThreadWorkList, &psData->sNode);
+               OSLockRelease(psPVRSRVData->hCleanupThreadWorkListLock);
+
+               /* signal the cleanup thread to ensure this item gets processed */
+               eError = OSEventObjectSignal(psPVRSRVData->hCleanupEventObject);
+               PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+       }
+}
+
+/* Pop an item from the head of the cleanup thread work list */
+static INLINE DLLIST_NODE *_CleanupThreadWorkListPop(PVRSRV_DATA *psPVRSRVData)
+{
+       DLLIST_NODE *psNode;
+
+       OSLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock);
+       psNode = dllist_get_next_node(&psPVRSRVData->sCleanupThreadWorkList);
+       if(psNode != NULL)
+       {
+               dllist_remove_node(psNode);
+       }
+       OSLockRelease(psPVRSRVData->hCleanupThreadWorkListLock);
+
+       return psNode;
+}
+
+/* Process the cleanup thread work list */
+static IMG_BOOL _CleanupThreadProcessWorkList(PVRSRV_DATA *psPVRSRVData)
+{
+       DLLIST_NODE *psNodeIter, *psNodeLast;
+       PVRSRV_ERROR eError;
+       IMG_BOOL bNeedRetry = IMG_FALSE;
+
+       /* any callback functions which return error will be
+        * moved to the back of the list, and additional items can be added
+        * to the list at any time so we ensure we only iterate from the
+        * head of the list to the current tail (since the tail may always
+        * be changing)
+        */
+
+       OSLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock);
+       psNodeLast = psPVRSRVData->sCleanupThreadWorkList.psPrevNode;
+       OSLockRelease(psPVRSRVData->hCleanupThreadWorkListLock);
+
+       do
+       {
+               PVRSRV_CLEANUP_THREAD_WORK *psData;
+
+               psNodeIter = _CleanupThreadWorkListPop(psPVRSRVData);
+
+               if(psNodeIter != NULL)
+               {
+                       CLEANUP_THREAD_FN pfnFree;
+
+                       psData = IMG_CONTAINER_OF(psNodeIter, PVRSRV_CLEANUP_THREAD_WORK, sNode);
+
+                       /* get the function pointer address here so we have acess to it
+                        * in order to report the error in case of failure, without having
+                        * to depend on psData not having been freed
+                        */
+                       pfnFree = psData->pfnFree;
+
+                       eError = pfnFree(psData->pvData);
+
+                       if(eError != PVRSRV_OK)
+                       {
+                               /* move to back of the list, if this item's
+                                * retry count hasn't hit zero.
+                                */
+                               if(psData->ui32RetryCount-- > 0)
+                               {
+                                       OSLockAcquire(psPVRSRVData->hCleanupThreadWorkListLock);
+                                       dllist_add_to_tail(&psPVRSRVData->sCleanupThreadWorkList, psNodeIter);
+                                       OSLockRelease(psPVRSRVData->hCleanupThreadWorkListLock);
+                                       bNeedRetry = IMG_TRUE;
+                               }
+                               else
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR, "Failed to free resource "
+                                                               "(callback " IMG_PFN_FMTSPEC "). "
+                                                               "Retry limit reached",
+                                                               pfnFree));
+                               }
+                       }
+               }
+       } while((psNodeIter != NULL) && (psNodeIter != psNodeLast));
+
+       return bNeedRetry;
+}
+
+// #define CLEANUP_DPFL PVR_DBG_WARNING
+#define CLEANUP_DPFL    PVR_DBG_MESSAGE
+
+static IMG_VOID CleanupThread(IMG_PVOID pvData)
+{
+       PVRSRV_DATA *psPVRSRVData = pvData;
+       IMG_BOOL     bRetryWorkList = IMG_FALSE;
+       IMG_HANDLE       hOSEvent;
+       PVRSRV_ERROR eRc;
+
+       /* Store the process id (pid) of the clean-up thread */
+       psPVRSRVData->cleanupThreadPid = OSGetCurrentProcessID();
+
+       PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread starting... "));
+
+       /* Open an event on the clean up event object so we can listen on it,
+        * abort the clean up thread and driver if this fails.
+        */
+       eRc = OSEventObjectOpen(psPVRSRVData->hCleanupEventObject, &hOSEvent);
+       PVR_ASSERT(eRc == PVRSRV_OK);
+
+       eRc = OSLockCreate(&psPVRSRVData->hCleanupThreadWorkListLock, LOCK_TYPE_PASSIVE);
+       PVR_ASSERT(eRc == PVRSRV_OK);
+
+       dllist_init(&psPVRSRVData->sCleanupThreadWorkList);
+
+       /* While the driver is in a good state and is not being unloaded
+        * try to free any deferred items when signalled
+        */
+       while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && 
+                       (!psPVRSRVData->bUnload))
+       {
+               /* Wait until signalled for deferred clean up OR wait for a
+                * short period if the previous deferred clean up was not able
+                * to release all the resources before trying again.
+                * Bridge lock re-acquired on our behalf before the wait call returns.
+                */
+               eRc = OSEventObjectWaitTimeout(hOSEvent,
+                               bRetryWorkList ?
+                               CLEANUP_THREAD_WAIT_RETRY_TIMEOUT :
+                               CLEANUP_THREAD_WAIT_SLEEP_TIMEOUT);
+               if (eRc == PVRSRV_ERROR_TIMEOUT)
+               {
+                       PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait timeout"));
+               }
+               else if (eRc == PVRSRV_OK)
+               {
+                       PVR_DPF((CLEANUP_DPFL, "CleanupThread: wait OK, signal received"));
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "CleanupThread: wait error %d", eRc));
+               }
+
+               bRetryWorkList = _CleanupThreadProcessWorkList(psPVRSRVData);
+       }
+
+       OSLockDestroy(psPVRSRVData->hCleanupThreadWorkListLock);
+
+       eRc = OSEventObjectClose(hOSEvent);
+       PVR_LOG_IF_ERROR(eRc, "OSEventObjectClose");
+
+       PVR_DPF((CLEANUP_DPFL, "CleanupThread: thread ending... "));
+}
+
+static IMG_VOID DevicesWatchdogThread(IMG_PVOID pvData)
+{
+       PVRSRV_DATA *psPVRSRVData = pvData;
+       PVRSRV_DEVICE_HEALTH_STATUS ePreviousHealthStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK;
+       IMG_HANDLE hOSEvent;
+       PVRSRV_ERROR  eError;
+       IMG_UINT32 ui32Timeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT;
+       PVRSRV_DEV_POWER_STATE ePowerState;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power off sleep time: %d.",
+                       DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT));
+
+       /* Open an event on the devices watchdog event object so we can listen on it
+          and abort the devices watchdog thread. */
+       eError = OSEventObjectOpen(psPVRSRVData->hDevicesWatchdogEvObj, &hOSEvent);
+       PVR_LOGRN_IF_ERROR(eError, "OSEventObjectOpen");
+
+       /* Loop continuously checking the device status every few seconds. */
+       while (!psPVRSRVData->bUnload)
+       {
+               IMG_UINT32 i;
+               IMG_BOOL bPwrIsOn = IMG_FALSE;
+
+               /* Wait time between polls (done at the start of the loop to allow devices
+                  to initialise) or for the event signal (shutdown or power on). */
+               eError = OSEventObjectWaitTimeout(hOSEvent, ui32Timeout);
+
+#ifdef PVR_TESTING_UTILS
+               psPVRSRVData->ui32DevicesWdWakeupCounter++;
+#endif
+               if (eError == PVRSRV_OK)
+               {
+                       if (psPVRSRVData->bUnload)
+                       {
+                               PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Shutdown event received."));
+                               break;
+                       }
+                       else
+                       {
+                               PVR_DPF((PVR_DBG_MESSAGE, "DevicesWatchdogThread: Power state change event received."));
+                       }
+               }
+               else if (eError != PVRSRV_ERROR_TIMEOUT)
+               {
+                       /* If timeout do nothing otherwise print warning message. */
+                       PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: "
+                                       "Error (%d) when waiting for event!", eError));
+               }
+
+               eError = PVRSRVPowerLock();
+               if (eError == PVRSRV_ERROR_RETRY)
+               {
+                       /* power lock cannot be acquired at this time (sys power is off) */
+                       ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT;
+               }
+               else if (eError != PVRSRV_OK)
+               {
+                       /* any other error is unexpected */
+                       PVR_DPF((PVR_DBG_ERROR,"DevicesWatchdogThread: Failed to acquire power lock (%s)", PVRSRVGetErrorStringKM(eError)));
+               }
+               else
+               {
+                       /* Check if at least one of the devices is on. */
+                       for (i = 0; i < psPVRSRVData->ui32RegisteredDevices && !bPwrIsOn; i++)
+                       {
+                               if (PVRSRVGetDevicePowerState(i, &ePowerState) == PVRSRV_OK)
+                               {
+                                       bPwrIsOn = ePowerState == PVRSRV_DEV_POWER_STATE_ON;
+                                       break;
+                               }
+                       }
+
+                       if (bPwrIsOn || psPVRSRVData->ui32DevicesWatchdogPwrTrans)
+                       {
+                               psPVRSRVData->ui32DevicesWatchdogPwrTrans = 0;
+                               ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT;
+                       }
+                       else
+                       {
+                               ui32Timeout = psPVRSRVData->ui32DevicesWatchdogTimeout = DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT;
+                       }
+
+                       PVRSRVPowerUnlock();
+               }
+
+               for (i = 0;  i < psPVRSRVData->ui32RegisteredDevices; i++)
+               {
+                       PVRSRV_DEVICE_NODE* psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
+                       PVRSRV_RGXDEV_INFO* psDevInfo = (PVRSRV_RGXDEV_INFO*) psDeviceNode->pvDevice;
+                       
+                       if (psDeviceNode->pfnUpdateHealthStatus != IMG_NULL)
+                       {
+                               eError = psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, IMG_TRUE);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING, "DevicesWatchdogThread: "
+                                                       "Could not check for fatal error (%d)!",
+                                                       eError));
+                               }
+                       }
+
+                       if (psDeviceNode->eHealthStatus != PVRSRV_DEVICE_HEALTH_STATUS_OK)
+                       {
+                               if (psDeviceNode->eHealthStatus != ePreviousHealthStatus)
+                               {
+                                       if (!(psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN))
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR, "DevicesWatchdogThread: Device not responding!!!"));
+                                               PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+                                       }
+                               }
+                       }
+                       ePreviousHealthStatus = psDeviceNode->eHealthStatus;
+                       
+                       /* Attempt to service the HWPerf buffer to regularly transport 
+                        * idle / periodic packets to host buffer. */
+                       if (psDeviceNode->pfnServiceHWPerf != IMG_NULL)
+                       {
+                               eError = psDeviceNode->pfnServiceHWPerf(psDeviceNode);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING, "DevicesWatchdogThread: "
+                                                       "Error occurred when servicing HWPerf buffer (%d)",
+                                                       eError));
+                               }
+                       }
+               }
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+               {
+                       #if defined(EMULATOR)
+                       {
+                               SysPrintAndResetFaultStatusRegister();
+                       }
+                       #endif
+               }
+#endif
+       }
+
+       eError = OSEventObjectClose(hOSEvent);
+       PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
+}
+
+
+PVRSRV_DATA *PVRSRVGetPVRSRVData()
+{
+       return gpsPVRSRVData;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(void *hDevice)
+{
+       PVRSRV_ERROR    eError;
+       PVRSRV_SYSTEM_CONFIG *psSysConfig;
+       IMG_UINT32 i;
+
+#if defined (SUPPORT_RGX)
+       /* FIXME find a way to do this without device-specific code here */
+       sRegisterDevice[PVRSRV_DEVICE_TYPE_RGX] = RGXRegisterDevice;
+#endif
+
+       SET_LOG2_PAGESIZE(OSGetPageShift());
+
+       eError = PhysHeapInit();
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       /* Get the system config */
+       eError = SysCreateConfigData(&psSysConfig, hDevice);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       /* Save to global pointer for later */
+       gpsSysConfig = psSysConfig;
+
+    /*
+     * Allocate the device-independent data
+     */
+    gpsPVRSRVData = OSAllocMem(sizeof(*gpsPVRSRVData));
+    if (gpsPVRSRVData == IMG_NULL)
+    {
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+    OSMemSet(gpsPVRSRVData, 0, sizeof(*gpsPVRSRVData));
+       gpsPVRSRVData->ui32NumDevices = psSysConfig->uiDeviceCount;
+
+       for (i=0;i<SYS_DEVICE_COUNT;i++)
+       {
+               gpsPVRSRVData->sDeviceID[i].uiID = i;
+               gpsPVRSRVData->sDeviceID[i].bInUse = IMG_FALSE;
+       }
+
+       /*
+        * Register the physical memory heaps
+        */
+       PVR_ASSERT(psSysConfig->ui32PhysHeapCount <= SYS_PHYS_HEAP_COUNT);
+       for (i=0;i<psSysConfig->ui32PhysHeapCount;i++)
+       {
+               eError = PhysHeapRegister(&psSysConfig->pasPhysHeaps[i],
+                                                                 &gpsPVRSRVData->apsRegisteredPhysHeaps[i]);
+               if (eError != PVRSRV_OK)
+               {
+                       goto Error;
+               }
+               gpsPVRSRVData->ui32RegisteredPhysHeaps++;
+       }
+
+       /* Init any OS specific's */
+       eError = OSInitEnvData();
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+#if defined(PVR_RI_DEBUG)
+       RIInitKM();
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       eError = DevicememHistoryInitKM();
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to initialise DevicememHistory"));
+               goto Error;
+       }
+#endif
+
+       eError = PMRInit();
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+       eError = DCInit();
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+#endif
+
+       /* Initialise Power Manager Lock */
+       eError = OSLockCreate(&gpsPVRSRVData->hPowerLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       /* Initialise system power state */
+       gpsPVRSRVData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_ON;
+       gpsPVRSRVData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+       /* Initialise overall system state */
+       gpsPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_OK;
+
+       /* Create an event object */
+       eError = OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", &gpsPVRSRVData->hGlobalEventObject);
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+       gpsPVRSRVData->ui32GEOConsecutiveTimeouts = 0;
+
+       /* initialise list of command complete notifiers */
+       dllist_init(&sCmdCompNotifyHead);
+
+       /* Create a lock of the list notifiers */
+       eError = OSWRLockCreate(&hNotifyLock);
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       /* Create a lock of the debug notifiers */
+       eError = OSWRLockCreate(&g_hDbgNotifyLock);
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       eError = PVRSRVRegisterDbgTable(g_aui32DebugOrderTable,
+                                                                       sizeof(g_aui32DebugOrderTable)/sizeof(g_aui32DebugOrderTable[0]),
+                                                                       &g_hDebugTable);
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       PVRSRVRegisterDbgRequestNotify(&g_hDbgSysNotify, &_SysDebugRequestNotify, DEBUG_REQUEST_SYS, gpsPVRSRVData);
+
+       eError = ServerSyncInit();
+       if (eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       /* Initialise pdump */
+       eError = PDUMPINIT();
+       if(eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
+
+       /* Register all the system devices */
+       for (i=0;i<psSysConfig->uiDeviceCount;i++)
+       {
+               if (PVRSRVRegisterDevice(&psSysConfig->pasDevices[i]) != PVRSRV_OK)
+               {
+                       /* FIXME: We should unregister devices if we fail */
+                       return eError;
+               }
+
+               /* Initialise the Transport Layer.
+                * Need to remember the RGX device node for use in the Transport Layer
+                * when allocating stream buffers that are shared with clients.
+                * Note however when the device is an LMA device our buffers will not
+                * be in host memory but card memory.
+                */
+               if (gpsPVRSRVData->apsRegisteredDevNodes[gpsPVRSRVData->ui32RegisteredDevices-1]->psDevConfig->eDeviceType == PVRSRV_DEVICE_TYPE_RGX)
+               {
+                       eError = TLInit(gpsPVRSRVData->apsRegisteredDevNodes[gpsPVRSRVData->ui32RegisteredDevices-1]);
+                       PVR_LOGG_IF_ERROR(eError, "TLInit", Error);
+               }
+       }
+
+       eError = PVRSRVHandleInit();
+       if(eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       eError = PVRSRVConnectionInit();
+       if(eError != PVRSRV_OK)
+       {
+               goto Error;
+       }
+
+       /* Create the clean up event object */
+       eError = OSEventObjectCreate("PVRSRV_CLEANUP_EVENTOBJECT", &gpsPVRSRVData->hCleanupEventObject);
+       PVR_LOGG_IF_ERROR(eError, "OSEventObjectCreate", Error);
+
+       /* Create a thread which is used to do the deferred cleanup */
+       eError = OSThreadCreatePriority(&gpsPVRSRVData->hCleanupThread,
+                                                       "pvr_defer_free",
+                                                       CleanupThread,
+                                                       gpsPVRSRVData,
+                                                       LOWEST_PRIORITY);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to create deferred cleanup thread"));
+               goto Error;
+       }
+
+       /* Create the devices watchdog event object */
+       eError = OSEventObjectCreate("PVRSRV_DEVICESWATCHDOG_EVENTOBJECT", &gpsPVRSRVData->hDevicesWatchdogEvObj);
+       PVR_LOGG_IF_ERROR(eError, "OSEventObjectCreate", Error);
+
+       /* Create a thread which is used to detect fatal errors */
+       eError = OSThreadCreate(&gpsPVRSRVData->hDevicesWatchdogThread,
+                                                       "pvr_devices_wd_thread",
+                                                       DevicesWatchdogThread,
+                                                       gpsPVRSRVData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to create devices watchdog thread"));
+               goto Error;
+       }
+
+#if defined(PVR_TESTING_UTILS)
+       TUtilsInit();
+#endif
+#if defined(PVR_DVFS)
+       eError = InitDVFS(gpsPVRSRVData, hDevice);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to start DVFS"));
+               goto Error;
+       }
+#endif
+       return eError;
+
+Error:
+       PVRSRVDeInit(hDevice);
+       return eError;
+}
+
+
+IMG_VOID IMG_CALLCONV PVRSRVDeInit(IMG_VOID *hDevice)
+{
+       PVRSRV_DATA             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_ERROR    eError;
+       IMG_UINT32              i;
+
+       if (gpsPVRSRVData == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit failed - invalid gpsPVRSRVData"));
+               return;
+       }
+
+#if defined(PVR_TESTING_UTILS)
+       TUtilsDeinit();
+#endif
+
+#if defined (SUPPORT_RGX)
+       sUnregisterDevice[PVRSRV_DEVICE_TYPE_RGX] = DevDeInitRGX;
+#endif
+
+       psPVRSRVData->bUnload = IMG_TRUE;
+       if (psPVRSRVData->hGlobalEventObject)
+       {
+               OSEventObjectSignal(psPVRSRVData->hGlobalEventObject);
+       }
+
+       /* Stop and cleanup the devices watchdog thread */
+       if (psPVRSRVData->hDevicesWatchdogThread)
+       {
+               if (psPVRSRVData->hDevicesWatchdogEvObj)
+               {
+                       eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj);
+                       PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+               }
+               eError = OSThreadDestroy(gpsPVRSRVData->hDevicesWatchdogThread);
+               gpsPVRSRVData->hDevicesWatchdogThread = IMG_NULL;
+               PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
+       }
+
+       if (gpsPVRSRVData->hDevicesWatchdogEvObj)
+       {
+               eError = OSEventObjectDestroy(gpsPVRSRVData->hDevicesWatchdogEvObj);
+               gpsPVRSRVData->hDevicesWatchdogEvObj = IMG_NULL;
+               PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+       }
+
+       /* Stop and cleanup the deferred clean up thread, event object and
+        * deferred context list.
+        */
+       if (psPVRSRVData->hCleanupThread)
+       {
+               if (psPVRSRVData->hCleanupEventObject)
+               {
+                       eError = OSEventObjectSignal(psPVRSRVData->hCleanupEventObject);
+                       PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+               }
+               eError = OSThreadDestroy(gpsPVRSRVData->hCleanupThread);
+               gpsPVRSRVData->hCleanupThread = IMG_NULL;
+               PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
+       }
+
+       if (gpsPVRSRVData->hCleanupEventObject)
+       {
+               eError = OSEventObjectDestroy(gpsPVRSRVData->hCleanupEventObject);
+               gpsPVRSRVData->hCleanupEventObject = IMG_NULL;
+               PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+       }
+
+       eError = PVRSRVConnectionDeInit();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVConnectionDataDeInit failed"));
+       }
+
+       eError = PVRSRVHandleDeInit();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
+       }
+
+       /* Unregister all the system devices */
+       for (i=0;i<psPVRSRVData->ui32RegisteredDevices;i++)
+       {
+               PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
+
+               /* set device state */
+               psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_DEINIT;
+
+               /* Counter part to what gets done in PVRSRVFinaliseSystem */
+               if (psDeviceNode->hSyncPrimContext != IMG_NULL)
+               {
+                       if (psDeviceNode->psSyncPrim != IMG_NULL)
+                       {
+                               /* Free general pupose sync primitive */
+                               SyncPrimFree(psDeviceNode->psSyncPrim);
+                               psDeviceNode->psSyncPrim = IMG_NULL;
+                       }
+
+                       SyncPrimContextDestroy(psDeviceNode->hSyncPrimContext);
+                       psDeviceNode->hSyncPrimContext = IMG_NULL;
+               }
+
+               PVRSRVUnregisterDevice(psDeviceNode);
+               psPVRSRVData->apsRegisteredDevNodes[i] = IMG_NULL;
+       }
+       SysDestroyConfigData(gpsSysConfig);
+
+#if defined(PVR_DVFS)
+       eError = DeinitDVFS(gpsPVRSRVData, hDevice);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to suspend DVFS"));
+       }
+#endif
+
+       /* Clean up Transport Layer resources that remain. 
+        * Done after RGX node clean up as HWPerf stream is destroyed during 
+        * this
+        */
+       TLDeInit();
+
+       ServerSyncDeinit();
+
+       if (g_hDbgSysNotify)
+       {
+               PVRSRVUnregisterDbgRequestNotify(g_hDbgSysNotify);
+       }
+
+       if (g_hDebugTable)
+       {
+               PVRSRVUnregisterDbgTable(g_hDebugTable);
+       }
+
+       if (g_hDbgNotifyLock)
+       {
+               OSWRLockDestroy(g_hDbgNotifyLock);
+       }
+
+       if (hNotifyLock)
+       {
+               OSWRLockDestroy(hNotifyLock);
+       }
+
+       /* deinitialise pdump */
+       if ((g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
+       {
+               PDUMPDEINIT();
+       }
+       
+       /* destroy event object */
+       if (gpsPVRSRVData->hGlobalEventObject)
+       {
+               OSEventObjectDestroy(gpsPVRSRVData->hGlobalEventObject);
+               gpsPVRSRVData->hGlobalEventObject = IMG_NULL;
+       }
+
+       /* Check there is no notify function */
+       if (!dllist_is_empty(&sCmdCompNotifyHead))
+       {
+               PDLLIST_NODE psNode = dllist_get_next_node(&sCmdCompNotifyHead);
+
+               /* some device did not unregistered properly */
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: Notify list for cmd complete is not empty!!"));
+
+               /* clean the nodes anyway */
+               while (psNode != IMG_NULL)
+               {
+                       PVRSRV_CMDCOMP_NOTIFY   *psNotify;
+
+                       dllist_remove_node(psNode);
+                       
+                       psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode);
+                       OSFreeMem(psNotify);
+
+                       psNode = dllist_get_next_node(&sCmdCompNotifyHead);
+               }
+       }
+
+       OSLockDestroy(gpsPVRSRVData->hPowerLock);
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+       eError = DCDeInit();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: DCInit() failed"));
+       }
+#endif
+
+
+    eError = PMRDeInit();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PMRDeInit() failed"));
+       }
+
+#if defined(PVR_RI_DEBUG)
+       RIDeInitKM();
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       DevicememHistoryDeInitKM();
+#endif
+       
+       OSDeInitEnvData();
+
+       for (i=0;i<gpsPVRSRVData->ui32RegisteredPhysHeaps;i++)
+       {
+               PhysHeapUnregister(gpsPVRSRVData->apsRegisteredPhysHeaps[i]);
+       }
+       eError = PhysHeapDeinit();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PhysHeapDeinit() failed"));
+       }
+
+       OSFreeMem(gpsPVRSRVData);
+       gpsPVRSRVData = IMG_NULL;
+}
+
+PVRSRV_ERROR LMA_MMUPxAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize,
+                                                       Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr)
+{
+       IMG_BOOL bSuccess;
+       RA_BASE_T uiCardAddr;
+       RA_LENGTH_T uiActualSize;
+       RA_ARENA        *pArena=psDevNode->psLocalDevMemArena;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+       IMG_UINT32  ui32OSid = 0;
+#endif
+
+       PVR_ASSERT((uiSize & OSGetPageMask()) == 0);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+       IMG_UINT32      ui32OSidReg = 0;
+
+       IMG_PID         pId = OSGetCurrentProcessID();
+
+       RetrieveOSidsfromPidList(pId, &ui32OSid, &ui32OSidReg);
+
+       pArena = psDevNode->psOSidSubArena[ui32OSid];
+}
+#endif
+
+       bSuccess = RA_Alloc(pArena,
+                                               uiSize,
+                                               0,                                                      /* No flags */
+                                               OSGetPageSize(),
+                                               &uiCardAddr,
+                                               &uiActualSize,
+                                               IMG_NULL);                                      /* No private handle */
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+       PVR_DPF((PVR_DBG_MESSAGE,"(GPU Virtualization Validation): LMA_MMUPxAlloc: Address:%llu, size:%llu", uiCardAddr,uiActualSize));
+}
+#endif
+
+       PVR_ASSERT(uiSize == uiActualSize);
+
+       psMemHandle->u.ui64Handle = uiCardAddr;
+       psDevPAddr->uiAddr = (IMG_UINT64) uiCardAddr;
+
+       if (bSuccess)
+       {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+       /* Allocation is done a page at a time */
+       PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, OSGetPageSize());
+#else
+               IMG_CPU_PHYADDR sCpuPAddr;
+               sCpuPAddr.uiAddr = psDevPAddr->uiAddr;
+
+               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA,
+                                                                                                                        IMG_NULL,
+                                                                                                                        sCpuPAddr,
+                                                                                                                        OSGetPageSize(),
+                                                                                                                        IMG_NULL);
+#endif
+#endif
+               return PVRSRV_OK;
+       }
+       else
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+IMG_VOID LMA_MMUPxFree(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle)
+{
+       RA_BASE_T uiCardAddr = (RA_BASE_T) psMemHandle->u.ui64Handle;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+       /* Allocation is done a page at a time */
+       PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, OSGetPageSize());
+#else
+               PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA, (IMG_UINT64)uiCardAddr);
+#endif
+#endif
+
+       RA_Free(psDevNode->psLocalDevMemArena, uiCardAddr);
+}
+
+PVRSRV_ERROR LMA_MMUPxMap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                                       IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+                                                       IMG_VOID **pvPtr)
+{
+       IMG_CPU_PHYADDR sCpuPAddr;
+       PVR_UNREFERENCED_PARAMETER(psMemHandle);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+
+       PhysHeapDevPAddrToCpuPAddr(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], 1, &sCpuPAddr, psDevPAddr);
+       *pvPtr = OSMapPhysToLin(sCpuPAddr,
+                                                       OSGetPageSize(),
+                                                       0);
+       if (*pvPtr == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       else
+       {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+               /* Mapping is done a page at a time */
+               PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, OSGetPageSize());
+#else
+               {
+                       PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA,
+                                                                                *pvPtr,
+                                                                                sCpuPAddr,
+                                                                                uiSize,
+                                                                                IMG_NULL);
+               }
+#endif
+#endif
+               return PVRSRV_OK;
+       }
+}
+
+IMG_VOID LMA_MMUPxUnmap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                               IMG_VOID *pvPtr)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemHandle);
+       PVR_UNREFERENCED_PARAMETER(psDevNode);
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+               /* Mapping is done a page at a time */
+               PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, OSGetPageSize());
+#else
+       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA, (IMG_UINT64)(IMG_UINTPTR_T)pvPtr);
+#endif
+#endif
+
+       OSUnMapPhysToLin(pvPtr, OSGetPageSize(), 0);
+}
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+static PVRSRV_ERROR CreateLMASubArenas(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       IMG_UINT        uiCounter=0;
+
+       for (uiCounter = 0; uiCounter < GPUVIRT_VALIDATION_NUM_OS; uiCounter++)
+       {
+               psDeviceNode->psOSidSubArena[uiCounter] =
+                       RA_Create(psDeviceNode->szRAName,
+                                         OSGetPageShift(),                     /* Use host page size, keeps things simple */
+                                         RA_LOCKCLASS_0,                       /* This arena doesn't use any other arenas. */
+                                         IMG_NULL,                                     /* No Import */
+                                         IMG_NULL,                                     /* No free import */
+                                         IMG_NULL,                                     /* No import handle */
+                                         IMG_FALSE);
+
+               if (psDeviceNode->psOSidSubArena[uiCounter] == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE,"\n(GPU Virtualization Validation): Calling RA_Add with base %u and size %u \n",0, GPUVIRT_SIZEOF_ARENA0));
+
+       /* Arena creation takes place earlier than when the client side reads the apphints and transfers them over the bridge. Since we don't
+        * know how the memory is going to be partitioned and since we already need some memory for all the initial allocations that take place,
+        * we populate the first sub-arena (0) with a span of 64 megabytes. This has been shown to be enough even for cases where EWS is allocated
+        * memory in this sub arena and then a multi app example is executed. This pre-allocation also means that consistency must be maintained
+        * between apphints and reality. That's why in the Apphints, the OSid0 region must start from 0 and end at 3FFFFFF. */
+
+       if (!RA_Add(psDeviceNode->psOSidSubArena[0], 0, GPUVIRT_SIZEOF_ARENA0, 0 , IMG_NULL ))
+       {
+               RA_Delete(psDeviceNode->psOSidSubArena[0]);
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psDeviceNode->psLocalDevMemArena = psDeviceNode->psOSidSubArena[0];
+
+       return PVRSRV_OK;
+}
+
+IMG_VOID PopulateLMASubArenas(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 aui32OSidMin[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS], IMG_UINT32 aui32OSidMax[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS])
+{
+       IMG_UINT        uiCounter;
+
+       /* Since Sub Arena[0] has been populated already, now we populate the rest starting from 1*/
+
+       for (uiCounter = 1; uiCounter < GPUVIRT_VALIDATION_NUM_OS; uiCounter++)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE,"\n[GPU Virtualization Validation]: Calling RA_Add with base %u and size %u \n",aui32OSidMin[uiCounter][0], aui32OSidMax[uiCounter][0]-aui32OSidMin[uiCounter][0]+1));
+
+               if (!RA_Add(psDeviceNode->psOSidSubArena[uiCounter], aui32OSidMin[uiCounter][0], aui32OSidMax[uiCounter][0]-aui32OSidMin[uiCounter][0]+1, 0, IMG_NULL))
+               {
+                       goto error;
+               }
+       }
+
+       #if defined(EMULATOR)
+       {
+               SysSetOSidRegisters(aui32OSidMin, aui32OSidMax);
+       }
+       #endif
+
+       return ;
+
+error:
+       for (uiCounter = 0; uiCounter < GPUVIRT_VALIDATION_NUM_OS; uiCounter++)
+       {
+               RA_Delete(psDeviceNode->psOSidSubArena[uiCounter]);
+       }
+
+       return ;
+}
+
+#endif
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVRegisterDevice
+
+ @Description
+
+ registers a device with the system
+
+ @Input           psDevConfig                  : Device configuration structure
+
+ @Return   PVRSRV_ERROR  :
+
+******************************************************************************/
+static PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PVRSRV_DEVICE_CONFIG *psDevConfig)
+{
+       PVRSRV_DATA                             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_ERROR                    eError;
+       PVRSRV_DEVICE_NODE              *psDeviceNode;
+       PVRSRV_DEVICE_PHYS_HEAP physHeapIndex;
+
+       /* Allocate device node */
+       psDeviceNode = OSAllocMem(sizeof(PVRSRV_DEVICE_NODE));
+       if (psDeviceNode == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+       OSMemSet(psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
+
+       /* set device state */
+       psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_INIT;
+
+       eError = PhysHeapAcquire(psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to acquire PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL physical memory heap"));
+               goto e1;
+       }
+       eError = PhysHeapAcquire(psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL], &psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to acquire PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL physical memory heap"));
+               goto e1;
+       }
+
+       /* Do we have card memory? If so create an RA to manage it */
+       if (PhysHeapGetType(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) == PHYS_HEAP_TYPE_LMA)
+       {
+               RA_BASE_T uBase;
+               RA_LENGTH_T uSize;
+               IMG_CPU_PHYADDR sCpuPAddr;
+               IMG_UINT64 ui64Size;
+
+               eError = PhysHeapGetAddress(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &sCpuPAddr);
+               if (eError != PVRSRV_OK)
+               {
+                       /* We can only get here if there is a bug in this module */
+                       PVR_ASSERT(IMG_FALSE);
+                       return eError;
+               }
+
+               eError = PhysHeapGetSize(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL], &ui64Size);
+               if (eError != PVRSRV_OK)
+               {
+                       /* We can only get here if there is a bug in this module */
+                       PVR_ASSERT(IMG_FALSE);
+                       return eError;
+               }
+
+
+               PVR_DPF((PVR_DBG_MESSAGE, "Creating RA for card memory 0x%016llx-0x%016llx",
+                                (IMG_UINT64) sCpuPAddr.uiAddr, sCpuPAddr.uiAddr + ui64Size));
+
+               OSSNPrintf(psDeviceNode->szRAName, sizeof(psDeviceNode->szRAName),
+                                                                                       "%s card mem",
+                                                                                       psDevConfig->pszName);
+
+               uBase = 0;
+               if (psDevConfig->uiFlags & PVRSRV_DEVICE_CONFIG_LMA_USE_CPU_ADDR)
+               {
+                       uBase = sCpuPAddr.uiAddr;
+               }
+
+               uSize = (RA_LENGTH_T) ui64Size;
+               PVR_ASSERT(uSize == ui64Size);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+               eError = CreateLMASubArenas(psDeviceNode);
+               if (eError != PVRSRV_OK)
+               {
+                       goto e2;
+               }
+}
+#else
+               psDeviceNode->psLocalDevMemArena =
+                       RA_Create(psDeviceNode->szRAName,
+                                               OSGetPageShift(),       /* Use host page size, keeps things simple */
+                                               RA_LOCKCLASS_0,     /* This arena doesn't use any other arenas. */
+                                               IMG_NULL,                       /* No Import */
+                                               IMG_NULL,                       /* No free import */
+                                               IMG_NULL,                       /* No import handle */
+                                               IMG_FALSE);
+
+               if (psDeviceNode->psLocalDevMemArena == IMG_NULL)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto e2;
+               }
+
+               if (!RA_Add(psDeviceNode->psLocalDevMemArena, uBase, uSize, 0 /* No flags */, IMG_NULL /* No private data */))
+               {
+                       RA_Delete(psDeviceNode->psLocalDevMemArena);
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto e2;                
+               }
+#endif
+
+
+               psDeviceNode->pfnMMUPxAlloc = LMA_MMUPxAlloc;
+               psDeviceNode->pfnMMUPxFree = LMA_MMUPxFree;
+               psDeviceNode->pfnMMUPxMap = LMA_MMUPxMap;
+               psDeviceNode->pfnMMUPxUnmap = LMA_MMUPxUnmap;
+               psDeviceNode->uiMMUPxLog2AllocGran = OSGetPageShift();
+               psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = PhysmemNewLocalRamBackedPMR;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "===== OS System memory only, no local card memory"));
+
+               /* else we only have OS system memory */
+               psDeviceNode->pfnMMUPxAlloc = OSMMUPxAlloc;
+               psDeviceNode->pfnMMUPxFree = OSMMUPxFree;
+               psDeviceNode->pfnMMUPxMap = OSMMUPxMap;
+               psDeviceNode->pfnMMUPxUnmap = OSMMUPxUnmap;
+               psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = PhysmemNewOSRamBackedPMR;
+       }
+
+       if (PhysHeapGetType(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) == PHYS_HEAP_TYPE_LMA)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "===== Local card memory only, no OS system memory"));
+               psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = PhysmemNewLocalRamBackedPMR;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "===== OS System memory, 2nd phys heap"));
+               psDeviceNode->pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = PhysmemNewOSRamBackedPMR;
+       }
+
+       /*
+               FIXME: We might want PT memory to come from a different heap so it
+               would make sense to specify the HeapID for it, but need to think
+               if/how this would affect how we do the CPU <> Dev physical address
+               translation.
+       */
+       psDeviceNode->pszMMUPxPDumpMemSpaceName = PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
+       psDeviceNode->uiMMUPxLog2AllocGran = OSGetPageShift();
+
+       /* Add the devnode to our list so we can unregister it later */
+       psPVRSRVData->apsRegisteredDevNodes[psPVRSRVData->ui32RegisteredDevices++] = psDeviceNode;
+
+       psDeviceNode->psDevConfig = psDevConfig;
+
+       /* all devices need a unique identifier */
+       AllocateDeviceID(psPVRSRVData, &psDeviceNode->sDevId.ui32DeviceIndex);
+
+       /* Device type and class will be setup during this callback */
+       eError = sRegisterDevice[psDevConfig->eDeviceType](psDeviceNode);
+       if (eError != PVRSRV_OK)
+       {
+               OSFreeMem(psDeviceNode);
+               /*not nulling pointer, out of scope*/
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
+               eError = PVRSRV_ERROR_DEVICE_REGISTER_FAILED;
+               goto e3;
+       }
+
+
+       PVR_DPF((PVR_DBG_MESSAGE, "Registered device %d of type %d", psDeviceNode->sDevId.ui32DeviceIndex, psDeviceNode->sDevId.eDeviceType));
+       PVR_DPF((PVR_DBG_MESSAGE, "Register bank address = 0x%08lx", (unsigned long)psDevConfig->sRegsCpuPBase.uiAddr));
+       PVR_DPF((PVR_DBG_MESSAGE, "IRQ = %d", psDevConfig->ui32IRQ));
+       
+       /* and finally insert the device into the dev-list */
+       List_PVRSRV_DEVICE_NODE_Insert(&psPVRSRVData->psDeviceNodeList, psDeviceNode);
+
+       /* set device state */
+       psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_ACTIVE;
+
+       return PVRSRV_OK;
+e3:
+       if (psDeviceNode->psLocalDevMemArena)
+       {
+               RA_Delete(psDeviceNode->psLocalDevMemArena);
+       }
+e2:
+e1:
+       for(physHeapIndex=0; physHeapIndex < PVRSRV_DEVICE_PHYS_HEAP_LAST; physHeapIndex++)
+       {
+               if (psDeviceNode->apsPhysHeap[physHeapIndex])
+               {
+                       PhysHeapRelease(psDeviceNode->apsPhysHeap[physHeapIndex]);
+               }
+       }
+       OSFreeMem(psDeviceNode);
+e0:
+       return eError;
+}
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_UNREFERENCED_PARAMETER(bForced);
+
+       if (gpsSysConfig->pfnSysPrePowerState)
+       {
+               eError = gpsSysConfig->pfnSysPrePowerState(eNewPowerState);
+       }
+       return eError;
+}
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_UNREFERENCED_PARAMETER(bForced);
+
+       if (gpsSysConfig->pfnSysPostPowerState)
+       {
+               eError = gpsSysConfig->pfnSysPostPowerState(eNewPowerState);
+       }
+       return eError;
+}
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                                       IMG_UINT32 *pui32DeviceIndex,
+                                                                                                       IMG_UINT32 ui32PhysHeapID)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PHYS_HEAP   *psPhysHeapTmp;
+       PVRSRV_DEVICE_PHYS_HEAP eDevPhysHeap;
+       PVRSRV_ERROR eError;
+
+       eError = PhysHeapAcquire(ui32PhysHeapID, &psPhysHeapTmp);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterExtDevice: Failed to acquire physical memory heap"));
+               goto e0;
+       }
+       if (PhysHeapGetType(psPhysHeapTmp) == PHYS_HEAP_TYPE_LMA)
+       {
+               eDevPhysHeap = PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL;
+       }
+       else
+       {
+               eDevPhysHeap = PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL;
+       }
+       psDeviceNode->apsPhysHeap[eDevPhysHeap] = psPhysHeapTmp;
+
+       /* allocate a unique device id */
+       eError = AllocateDeviceID(psPVRSRVData, &psDeviceNode->sDevId.ui32DeviceIndex);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterExtDevice: Failed to allocate Device ID"));
+               goto e1;
+       }
+
+       if (pui32DeviceIndex)
+       {
+               *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
+       }
+
+       List_PVRSRV_DEVICE_NODE_Insert(&psPVRSRVData->psDeviceNodeList, psDeviceNode);
+
+       return PVRSRV_OK;
+e1:
+       PhysHeapRelease(psDeviceNode->apsPhysHeap[eDevPhysHeap]);
+e0:
+       return eError;
+}
+
+IMG_VOID IMG_CALLCONV PVRSRVUnregisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_PHYS_HEAP eDevPhysHeap;
+
+       List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+       (IMG_VOID)FreeDeviceID(psPVRSRVData, psDeviceNode->sDevId.ui32DeviceIndex);
+       for (eDevPhysHeap = 0; eDevPhysHeap < PVRSRV_DEVICE_PHYS_HEAP_LAST; eDevPhysHeap++)
+       {
+               if (psDeviceNode->apsPhysHeap[eDevPhysHeap])
+               {
+                       PhysHeapRelease(psDeviceNode->apsPhysHeap[eDevPhysHeap]);
+               }
+       }
+}
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+       PVRSRV_ERROR eError;
+       PVRSRV_DEV_POWER_STATE ePowState;
+
+       ePowState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                ePowState,
+                                                                                IMG_TRUE);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (%s, device index: %d)", 
+                                               PVRSRVGetErrorStringKM(eError),
+                                               psDeviceNode->sDevId.ui32DeviceIndex));
+       }
+
+       return eError;
+}
+
+/*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/
+static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_Any_va(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 *pui32ClientBuildOptions;
+
+       pui32ClientBuildOptions = va_arg(va, IMG_UINT32*);
+
+       eError = PVRSRVDevInitCompatCheck(psDeviceNode, *pui32ClientBuildOptions);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+       }
+       return eError;
+}
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetIdleState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+       PVRSRV_ERROR eError;
+       PVRSRV_DEV_POWER_STATE ePowState;
+
+       ePowState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+       eError = PVRSRVDeviceIdleRequestKM(IMG_FALSE, psDeviceNode->sDevId.ui32DeviceIndex, &PVRSRVDeviceIsDefaultStateOFF, IMG_TRUE);
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDeviceIdleRequestKM call (%s, device index: %d)",
+                                               PVRSRVGetErrorStringKM(eError),
+                                               psDeviceNode->sDevId.ui32DeviceIndex));
+       }
+
+       return eError;
+}
+/*!
+******************************************************************************
+
+ @Function     PVRSRVFinaliseSystem
+
+ @Description
+
+ Final part of system initialisation.
+
+ @Input           ui32DevIndex : Index to the required device
+
+ @Return   PVRSRV_ERROR  :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful, IMG_UINT32 ui32ClientBuildOptions)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_ERROR            eError;
+       IMG_UINT32                      i;
+       PVRSRV_DEVICE_NODE *psRGXDeviceNode = IMG_NULL;
+       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
+
+       if (bInitSuccessful)
+       {
+               for (i=0;i<psPVRSRVData->ui32RegisteredDevices;i++)
+               {
+                       PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[i];
+                       if(psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_RGX)
+                       {
+                               psRGXDeviceNode = psDeviceNode; 
+                       }
+                       eError = SyncPrimContextCreate(IMG_NULL,
+                                                                 psDeviceNode,
+                                                                 &psDeviceNode->hSyncPrimContext);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to create SyncPrimContext (%u)", eError));
+                               return eError;
+                       }
+
+                       /* Allocate general purpose sync primitive */
+                       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psDeviceNode->psSyncPrim, "pvrsrv dev general");
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to allocate sync primitive with error (%u)", eError));
+                               return eError;
+                       }
+               }
+
+               eError = PVRSRVPowerLock();
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem_SetPowerState_AnyCb: Failed to acquire power lock"));
+                       return eError;
+               }
+
+               /* Always ensure a single power on command appears in the pdump.
+                * This should be the only power related call outside of PDUMPPOWCMDSTART/END.
+                * Place all devices into ON power state. */
+               eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
+                                                                                                               &PVRSRVFinaliseSystem_SetPowerState_AnyCb,
+                                                                                                               PVRSRV_DEV_POWER_STATE_ON);
+               if (eError != PVRSRV_OK)
+               {
+                       PVRSRVPowerUnlock();
+                       return eError;
+               }
+
+               /* Verify firmware compatibility for devices */
+               eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
+                                                                                                       &PVRSRVFinaliseSystem_CompatCheck_Any_va,
+                                                                                                       &ui32ClientBuildOptions);
+               if (eError != PVRSRV_OK)
+               {
+                       PVRSRVPowerUnlock();
+                       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+                       return eError;
+               }
+
+               PDUMPPOWCMDSTART();
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               { /* Force idle all devices whose default power state is off*/
+                       eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
+                                                                                                       &PVRSRVFinaliseSystem_SetIdleState_AnyCb,
+                                                                                                       &ui32ClientBuildOptions);
+
+                       if (eError == PVRSRV_OK)
+                       {
+                               break;
+                       }
+                       else if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+                       {
+                               PVRSRV_ERROR            eError2;
+
+                               PVRSRVPowerUnlock();
+                               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+                               eError2 = PVRSRVPowerLock();
+
+                               if (eError2 != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to acquire power lock"));
+                                       return eError2;
+                               }
+                       }
+                       else
+                       {
+                               PVRSRVPowerUnlock();
+                               return eError;
+                       }
+
+               } END_LOOP_UNTIL_TIMEOUT();
+
+               /* Place all devices into their default power state. */
+               eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psPVRSRVData->psDeviceNodeList,
+                                                                                                               &PVRSRVFinaliseSystem_SetPowerState_AnyCb,
+                                                                                                               PVRSRV_DEV_POWER_STATE_DEFAULT);
+               PDUMPPOWCMDEND();
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVRSRVPowerUnlock();
+                       return eError;
+               }
+
+               PVRSRVPowerUnlock();
+
+/* If PDUMP is enabled and RGX device is supported, then initialise the performance counters that can be further modified in PDUMP.
+Then, before ending the init phase of the pdump, drain the commands put in the kCCBs during the init phase */
+#if defined(SUPPORT_RGX) && defined(PDUMP)
+               if(psRGXDeviceNode)
+               {
+                       PVRSRV_RGXDEV_INFO      *psDevInfo = (PVRSRV_RGXDEV_INFO *) (psRGXDeviceNode->pvDevice);
+                       IMG_UINT32 ui32Idx;
+
+                       eError = PVRSRVRGXInitHWPerfCountersKM(psRGXDeviceNode);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "PVSRVFinaliseSystem: failed to init hwperf counters(%d)", eError));
+                               return eError;
+                       }
+
+                       for (ui32Idx = 0; ui32Idx < RGXFWIF_DM_LAST; ui32Idx++)
+                       {
+                               eError = RGXPdumpDrainKCCB(psDevInfo, psDevInfo->apsKernelCCBCtl[ui32Idx]->ui32WriteOffset, ui32Idx);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR, "PVSRVFinaliseSystem: problem draining kCCB (%d)", eError));
+                                       return eError;
+                               }
+                       }
+               }
+#endif
+       }
+
+       eError = PDumpStopInitPhaseKM(IMG_SRV_INIT);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to stop PDump init phase"));
+               return eError;
+       }
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode,IMG_UINT32 ui32ClientBuildOptions)
+{
+       /* Only check devices which specify a compatibility check callback */
+       if (psDeviceNode->pfnInitDeviceCompatCheck)
+               return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode, ui32ClientBuildOptions);
+       else
+               return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVAcquireDeviceDataKM
+
+ @Description
+
+ Matchs a device given a device type and a device index.
+
+ @input        psDeviceNode :The device node to be matched.
+
+ @Input           va : Variable argument list with:
+                       eDeviceType : Required device type. If type is unknown use ui32DevIndex
+                                                to locate device data
+
+                       ui32DevIndex : Index to the required device obtained from the
+                                               PVRSRVEnumerateDevice function
+
+ @Return   PVRSRV_ERROR  :
+
+******************************************************************************/
+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;
+       }
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVAcquireDeviceDataKM
+
+ @Description
+
+ Returns device information
+
+ @Input           ui32DevIndex : Index to the required device obtained from the
+                                               PVRSRVEnumerateDevice function
+
+ @Input           eDeviceType : Required device type. If type is unknown use ui32DevIndex
+                                                to locate device data
+
+ @Output  *phDevCookie : Dev Cookie
+
+
+ @Return   PVRSRV_ERROR  :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32                        ui32DevIndex,
+                                                                                                        PVRSRV_DEVICE_TYPE     eDeviceType,
+                                                                                                        IMG_HANDLE                     *phDevCookie)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_NODE      *psDeviceNode;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
+
+       /* Find device in the list */
+       psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                                                                               &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
+                                                                                               eDeviceType,
+                                                                                               ui32DevIndex);
+
+
+       if (!psDeviceNode)
+       {
+               /* device can't be found in the list so it isn't in the system */
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
+               return PVRSRV_ERROR_INIT_FAILURE;
+       }
+
+/*FoundDevice:*/
+
+       /* return the dev cookie? */
+       if (phDevCookie)
+       {
+               *phDevCookie = (IMG_HANDLE)psDeviceNode;
+       }
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseDeviceDataKM (IMG_HANDLE hDevCookie)
+{
+       PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+       /* 
+         Empty release body as the lifetime of this resource accessed by 
+         PVRSRVAcquireDeviceDataKM is linked to driver lifetime, not API allocation.
+         This is one reason why this type crosses the bridge with a shared handle.
+         Thus no server release action is required, just bridge action to ensure
+         associated handle is freed.
+    */ 
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVUnregisterDevice
+
+ @Description
+
+ This De-inits device
+
+ @Input           ui32DevIndex : Index to the required device
+
+ @Return   PVRSRV_ERROR  :
+
+******************************************************************************/
+static PVRSRV_ERROR IMG_CALLCONV PVRSRVUnregisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_DATA                             *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_PHYS_HEAP ePhysHeapIdx;
+       PVRSRV_ERROR                    eError;
+
+       eError = PVRSRVPowerLock();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnregisterDevice: Failed to acquire power lock"));
+               return eError;
+       }
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               /* Force idle device*/
+               eError = PVRSRVDeviceIdleRequestKM(IMG_FALSE,
+                                                       psDeviceNode->sDevId.ui32DeviceIndex,
+                                                       IMG_NULL,
+                                                       IMG_TRUE);
+
+               if (eError == PVRSRV_OK)
+               {
+                       break;
+               }
+               else if (eError == PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+               {
+                       PVRSRV_ERROR    eError2;
+
+                       PVRSRVPowerUnlock();
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+                       eError2 = PVRSRVPowerLock();
+                       if (eError2 != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnregisterDevice: Failed to acquire power lock"));
+                               return eError2;
+                       }
+               }
+               else
+               {
+                       PVRSRVPowerUnlock();
+                       return eError;
+               }
+       } END_LOOP_UNTIL_TIMEOUT();
+       /*
+               Power down the device if necessary.
+        */
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE_OFF,
+                                                                                IMG_TRUE);
+
+       PVRSRVPowerUnlock();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnregisterDevice: Failed PVRSRVSetDevicePowerStateKM call (%s). Dump debug.", PVRSRVGetErrorStringKM(eError)));
+
+               PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+
+               /* If the driver is okay then return the error, otherwise we can ignore this error. */
+               if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
+               {
+                       return eError;
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVUnregisterDevice: Will continue to unregister as driver status is not OK"));
+               }
+       }
+
+       /*
+               De-init the device.
+       */
+       sUnregisterDevice[psDeviceNode->sDevId.eDeviceType](psDeviceNode);
+
+       /* Remove RA for local card memory */
+       if (psDeviceNode->psLocalDevMemArena)
+       {
+               RA_Delete(psDeviceNode->psLocalDevMemArena);
+       }
+
+       /* remove node from list */
+       List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+       /* deallocate id and memory */
+       (IMG_VOID)FreeDeviceID(psPVRSRVData, psDeviceNode->sDevId.ui32DeviceIndex);
+
+       for (ePhysHeapIdx = 0; ePhysHeapIdx < PVRSRV_DEVICE_PHYS_HEAP_LAST; ePhysHeapIdx++)
+       {
+               if (psDeviceNode->apsPhysHeap[ePhysHeapIdx])
+               {
+                       PhysHeapRelease(psDeviceNode->apsPhysHeap[ePhysHeapIdx]);
+               }
+       }
+
+       OSFreeMem(psDeviceNode);
+       /*not nulling pointer, out of scope*/
+
+       return (PVRSRV_OK);
+}
+
+
+/*
+       PollForValueKM
+*/
+static
+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(NO_HARDWARE)
+       PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       PVR_UNREFERENCED_PARAMETER(ui32Timeoutus);
+       PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
+       PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
+       return PVRSRV_OK;
+#else
+       IMG_UINT32      ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */
+
+       if (bAllowPreemption)
+       {
+               PVR_ASSERT(ui32PollPeriodus >= 1000);
+       }
+
+       LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
+       {
+               ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
+               if(ui32ActualValue == ui32Value)
+               {
+                       return PVRSRV_OK;
+               }
+
+               if (gpsPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+               {
+                       return PVRSRV_ERROR_TIMEOUT;
+               }
+
+               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));
+       
+       return PVRSRV_ERROR_TIMEOUT;
+#endif /* NO_HARDWARE */
+}
+
+
+/*
+       PVRSRVPollForValueKM
+*/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPollForValueKM (volatile IMG_UINT32    *pui32LinMemAddr,
+                                                                                               IMG_UINT32                      ui32Value,
+                                                                                               IMG_UINT32                      ui32Mask)
+{
+       return PollForValueKM(pui32LinMemAddr, ui32Value, ui32Mask,
+                                                 MAX_HW_TIME_US,
+                                                 MAX_HW_TIME_US/WAIT_TRY_COUNT,
+                                                 IMG_FALSE);
+}
+
+static
+PVRSRV_ERROR IMG_CALLCONV WaitForValueKM(volatile IMG_UINT32  *pui32LinMemAddr,
+                                         IMG_UINT32           ui32Value,
+                                         IMG_UINT32           ui32Mask,
+                                         IMG_BOOL             bHoldBridgeLock)
+{
+#if defined(NO_HARDWARE)
+       PVR_UNREFERENCED_PARAMETER(pui32LinMemAddr);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       return PVRSRV_OK;
+#else
+
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       IMG_HANDLE hOSEvent;
+       PVRSRV_ERROR eError;
+       PVRSRV_ERROR eErrorWait;
+       IMG_UINT32 ui32ActualValue;
+
+       eError = OSEventObjectOpen(psPVRSRVData->hGlobalEventObject, &hOSEvent);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVWaitForValueKM: Failed to setup EventObject with error (%d)", eError));
+               goto EventObjectOpenError;
+       }
+
+       eError = PVRSRV_ERROR_TIMEOUT;
+       
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
+
+               if (ui32ActualValue == ui32Value)
+               {
+                       /* Expected value has been found */
+                       eError = PVRSRV_OK;
+                       break;
+               }
+               else if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+               {
+                       /* Services in bad state, don't wait any more */
+                       eError = PVRSRV_ERROR_NOT_READY;
+                       break;
+               }
+               else
+               {
+                       /* wait for event and retry */
+                       eErrorWait = bHoldBridgeLock ? OSEventObjectWaitAndHoldBridgeLock(hOSEvent) : OSEventObjectWait(hOSEvent);
+                       if (eErrorWait != PVRSRV_OK  &&  eErrorWait != PVRSRV_ERROR_TIMEOUT)
+                       {
+                               PVR_DPF((PVR_DBG_WARNING,"PVRSRVWaitForValueKM: Waiting for value failed with error %d. Expected 0x%x but found 0x%x (Mask 0x%08x). Retrying",
+                                                       eErrorWait,
+                                                       ui32Value,
+                                                       ui32ActualValue,
+                                                       ui32Mask));
+                       }
+               }
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       OSEventObjectClose(hOSEvent);
+
+       /* One last check incase the object wait ended after the loop timeout... */
+       if (eError != PVRSRV_OK  &&  (*pui32LinMemAddr & ui32Mask) == ui32Value)
+       {
+               eError = PVRSRV_OK;
+       }
+
+       /* Provide event timeout information to aid the Device Watchdog Thread... */
+       if (eError == PVRSRV_OK)
+       {
+               psPVRSRVData->ui32GEOConsecutiveTimeouts = 0;
+       }
+       else if (eError == PVRSRV_ERROR_TIMEOUT)
+       {
+               psPVRSRVData->ui32GEOConsecutiveTimeouts++;
+       }
+
+EventObjectOpenError:
+
+       return eError;
+
+#endif /* NO_HARDWARE */
+}
+
+/*
+       PVRSRVWaitForValueKM
+*/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForValueKM (volatile IMG_UINT32    *pui32LinMemAddr,
+                                                                                               IMG_UINT32                      ui32Value,
+                                                                                               IMG_UINT32                      ui32Mask)
+{
+       /* In this case we are NOT retaining bridge lock while waiting
+          for bridge lock. */
+       return WaitForValueKM(pui32LinMemAddr, ui32Value, ui32Mask, IMG_FALSE);
+}
+
+/*
+       PVRSRVWaitForValueKMAndHoldBridgeLock
+*/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForValueKMAndHoldBridgeLockKM(volatile IMG_UINT32 *pui32LinMemAddr,
+                                                                  IMG_UINT32          ui32Value,
+                                                                  IMG_UINT32          ui32Mask)
+{
+       return WaitForValueKM(pui32LinMemAddr, ui32Value, ui32Mask, IMG_TRUE);
+}
+
+#if !defined(NO_HARDWARE)
+static IMG_BOOL _CheckStatus(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       PVRSRV_CMDCOMP_HANDLE   hCmdCompCallerHandle = (PVRSRV_CMDCOMP_HANDLE) pvCallbackData;
+       PVRSRV_CMDCOMP_NOTIFY   *psNotify;
+
+       psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_CMDCOMP_NOTIFY, sListNode);
+
+       /* A device has finished some processing, check if that unblocks other devices */
+       if (hCmdCompCallerHandle != psNotify->hCmdCompHandle)
+       {
+               psNotify->pfnCmdCompleteNotify(psNotify->hCmdCompHandle);
+       }
+
+       /* keep processing until the end of the list */
+       return IMG_TRUE;
+}
+#endif
+
+IMG_VOID IMG_CALLCONV PVRSRVCheckStatus(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle)
+{
+       PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       /* notify any registered device to check if block work items can now proceed */
+#if !defined(NO_HARDWARE)
+       OSWRLockAcquireRead(hNotifyLock);
+       dllist_foreach_node(&sCmdCompNotifyHead, _CheckStatus, hCmdCompCallerHandle);
+       OSWRLockReleaseRead(hNotifyLock);
+#endif
+
+       /* signal global event object */
+       if (psPVRSRVData->hGlobalEventObject)
+       {
+               IMG_HANDLE hOSEventKM = psPVRSRVData->hGlobalEventObject;
+               if(hOSEventKM)
+               {
+                       OSEventObjectSignal(hOSEventKM);
+               }
+       }
+}
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVKickDevicesKM(IMG_VOID)
+{
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVKickDevicesKM"));
+       PVRSRVCheckStatus(IMG_NULL);
+       return PVRSRV_OK;
+}
+
+/*!
+ ******************************************************************************
+
+ @Function             PVRSRVGetErrorStringKM
+
+ @Description  Returns a text string relating to the PVRSRV_ERROR enum.
+
+ @Note         case statement used rather than an indexed arrary to ensure text is
+                       synchronised with the correct enum
+
+ @Input                eError : PVRSRV_ERROR enum
+
+ @Return       const IMG_CHAR * : Text string
+
+ @Note         Must be kept in sync with servicesext.h
+
+******************************************************************************/
+
+IMG_EXPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
+{
+       switch(eError)
+       {
+               case PVRSRV_OK:
+                       return "PVRSRV_OK";
+#define PVRE(x) \
+               case x: \
+                       return #x;
+#include "pvrsrv_errors.h"
+#undef PVRE
+               default:
+                       return "Unknown PVRSRV error number";
+       }
+}
+
+/*
+       PVRSRVSystemDebugInfo
+ */
+PVRSRV_ERROR PVRSRVSystemDebugInfo( DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       return SysDebugInfo(gpsSysConfig, pfnDumpDebugPrintf);
+}
+
+/*
+       PVRSRVGetSystemName
+*/
+const IMG_CHAR *PVRSRVGetSystemName(IMG_VOID)
+{
+       return gpsSysConfig->pszSystemName;
+}
+
+/*
+       PVRSRVSystemHasCacheSnooping
+*/
+IMG_BOOL PVRSRVSystemHasCacheSnooping(IMG_VOID)
+{
+       if (gpsSysConfig->eCacheSnoopingMode != PVRSRV_SYSTEM_SNOOP_NONE)
+       {
+               return IMG_TRUE;
+       }
+       return IMG_FALSE;
+}
+
+IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(IMG_VOID)
+{
+       if ((gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CPU_ONLY) ||
+               (gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CROSS))
+       {
+               return IMG_TRUE;
+       }
+       return IMG_FALSE;       
+}
+
+IMG_BOOL PVRSRVSystemSnoopingOfDeviceCache(IMG_VOID)
+{
+       if ((gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_DEVICE_ONLY) ||
+               (gpsSysConfig->eCacheSnoopingMode == PVRSRV_SYSTEM_SNOOP_CROSS))
+       {
+               return IMG_TRUE;
+       }
+       return IMG_FALSE;
+}
+
+/*
+       PVRSRVSystemWaitCycles
+*/
+IMG_VOID PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT32 ui32Cycles)
+{
+       /* Delay in us */
+       IMG_UINT32 ui32Delayus = 1;
+
+       /* obtain the device freq */
+       if (psDevConfig->pfnClockFreqGet != IMG_NULL)
+       {
+               IMG_UINT32 ui32DeviceFreq;
+
+               ui32DeviceFreq = psDevConfig->pfnClockFreqGet(psDevConfig->hSysData);
+
+               ui32Delayus = (ui32Cycles*1000000)/ui32DeviceFreq;
+
+               if (ui32Delayus == 0)
+               {
+                       ui32Delayus = 1;
+               }
+       }
+
+       OSWaitus(ui32Delayus);
+}
+
+/*
+       PVRSRVRegisterCmdCompleteNotify
+*/
+PVRSRV_ERROR PVRSRVRegisterCmdCompleteNotify(IMG_HANDLE *phNotify, PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, PVRSRV_CMDCOMP_HANDLE hCmdCompHandle)
+{
+       PVRSRV_CMDCOMP_NOTIFY *psNotify;
+
+       if ((phNotify == IMG_NULL) || (pfnCmdCompleteNotify == IMG_NULL) || (hCmdCompHandle == IMG_NULL))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p, %p, %p)", __FUNCTION__, phNotify, pfnCmdCompleteNotify, hCmdCompHandle));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psNotify = OSAllocMem(sizeof(*psNotify));
+       if (psNotify == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Not enough memory to allocate CmdCompleteNotify function", __FUNCTION__));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;              
+       }
+
+       /* Set-up the notify data */
+       psNotify->hCmdCompHandle = hCmdCompHandle;
+       psNotify->pfnCmdCompleteNotify = pfnCmdCompleteNotify;
+
+       /* Add it to the list of Notify functions */
+       OSWRLockAcquireWrite(hNotifyLock);
+       dllist_add_to_tail(&sCmdCompNotifyHead, &psNotify->sListNode);
+       OSWRLockReleaseWrite(hNotifyLock);
+
+       *phNotify = psNotify;
+
+       return PVRSRV_OK;
+}
+
+/*
+       PVRSRVUnregisterCmdCompleteNotify
+*/
+PVRSRV_ERROR PVRSRVUnregisterCmdCompleteNotify(IMG_HANDLE hNotify)
+{
+       PVRSRV_CMDCOMP_NOTIFY *psNotify = (PVRSRV_CMDCOMP_NOTIFY*) hNotify;
+
+       if (psNotify == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p)", __FUNCTION__, hNotify));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* remove the node from the list */
+       OSWRLockAcquireWrite(hNotifyLock);
+       dllist_remove_node(&psNotify->sListNode);
+       OSWRLockReleaseWrite(hNotifyLock);
+
+       /* free the notify structure that holds the node */
+       OSFreeMem(psNotify);
+
+       return PVRSRV_OK;
+
+}
+
+static IMG_VOID _SysDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA*) hDebugRequestHandle;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = IMG_NULL;
+
+       pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;      
+       /* only dump info on the lowest verbosity level */
+       if (ui32VerbLevel != DEBUG_REQUEST_VERBOSITY_LOW)
+       {
+               return;
+       }
+
+       PVR_DUMPDEBUG_LOG(("DDK info: %s (%s) %s", PVRVERSION_STRING, PVR_BUILD_TYPE, PVR_BUILD_DIR));
+       PVR_DUMPDEBUG_LOG(("Time now: %015llu", OSClockus64()));
+
+       /* Services state */
+       switch (psPVRSRVData->eServicesState)
+       {
+               case PVRSRV_SERVICES_STATE_OK:
+               {
+                       PVR_DUMPDEBUG_LOG(("Services State: OK"));
+                       break;
+               }
+               
+               case PVRSRV_SERVICES_STATE_BAD:
+               {
+                       PVR_DUMPDEBUG_LOG(("Services State: BAD"));
+                       break;
+               }
+               
+               default:
+               {
+                       PVR_DUMPDEBUG_LOG(("Services State: UNKNOWN (%d)", psPVRSRVData->eServicesState));
+                       break;
+               }
+       }
+
+       /* Power state */
+       switch (psPVRSRVData->eCurrentPowerState)
+       {
+               case PVRSRV_SYS_POWER_STATE_OFF:
+               {
+                       PVR_DUMPDEBUG_LOG(("System Power State: OFF"));
+                       break;
+               }
+               case PVRSRV_SYS_POWER_STATE_ON:
+               {
+                       PVR_DUMPDEBUG_LOG(("System Power State: ON"));
+                       break;
+               }
+               default:
+               {
+                       PVR_DUMPDEBUG_LOG(("System Power State: UNKNOWN (%d)", psPVRSRVData->eCurrentPowerState));
+                       break;
+               }
+       }
+
+       /* Dump system specific debug info */
+       PVRSRVSystemDebugInfo(pfnDumpDebugPrintf);
+
+}
+
+static IMG_BOOL _DebugRequest(PDLLIST_NODE psNode, IMG_PVOID hVerbLevel)
+{
+       IMG_UINT32 *pui32VerbLevel = (IMG_UINT32 *) hVerbLevel;
+       PVRSRV_DBGREQ_NOTIFY *psNotify;
+
+       psNotify = IMG_CONTAINER_OF(psNode, PVRSRV_DBGREQ_NOTIFY, sListNode);
+
+       psNotify->pfnDbgRequestNotify(psNotify->hDbgRequestHandle, *pui32VerbLevel);
+
+       /* keep processing until the end of the list */
+       return IMG_TRUE;
+}
+
+/*
+       PVRSRVDebugRequest
+*/
+IMG_VOID IMG_CALLCONV PVRSRVDebugRequest(IMG_UINT32 ui32VerbLevel, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       IMG_UINT32 i,j;
+
+       g_pfnDumpDebugPrintf = pfnDumpDebugPrintf;
+       if (pfnDumpDebugPrintf == IMG_NULL)
+       {
+               /* Only dump the call stack to the kernel log if the debug text is going there. */
+               OSDumpStack();
+       }
+
+       /* notify any registered device to check if block work items can now proceed */
+       /* Lock the lists */
+       OSWRLockAcquireRead(g_hDbgNotifyLock);
+
+       PVR_DUMPDEBUG_LOG(("------------[ PVR DBG: START ]------------"));
+
+       /* For each verbosity level */
+       for (j=0;j<(ui32VerbLevel+1);j++)
+       {
+               /* For each requester */
+               for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
+               {
+                       dllist_foreach_node(&g_psDebugTable->asEntry[i].sListHead, _DebugRequest, &j);
+               }
+       }
+       PVR_DUMPDEBUG_LOG(("------------[ PVR DBG: END ]------------"));
+
+       /* Unlock the lists */
+       OSWRLockReleaseRead(g_hDbgNotifyLock);
+}
+
+/*
+       PVRSRVRegisterDebugRequestNotify
+*/
+PVRSRV_ERROR PVRSRVRegisterDbgRequestNotify(IMG_HANDLE *phNotify, PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, IMG_UINT32 ui32RequesterID, PVRSRV_DBGREQ_HANDLE hDbgRequestHandle)
+{
+       PVRSRV_DBGREQ_NOTIFY *psNotify;
+       PDLLIST_NODE psHead = IMG_NULL;
+       IMG_UINT32 i;
+       PVRSRV_ERROR eError;
+
+       if ((phNotify == IMG_NULL) || (pfnDbgRequestNotify == IMG_NULL))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p, %p,)", __FUNCTION__, phNotify, pfnDbgRequestNotify));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_params;
+       }
+
+       psNotify = OSAllocMem(sizeof(*psNotify));
+       if (psNotify == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Not enough memory to allocate DbgRequestNotify structure", __FUNCTION__));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       /* Set-up the notify data */
+       psNotify->hDbgRequestHandle = hDbgRequestHandle;
+       psNotify->pfnDbgRequestNotify = pfnDbgRequestNotify;
+       psNotify->ui32RequesterID = ui32RequesterID;
+
+       /* Lock down all the lists */
+       OSWRLockAcquireWrite(g_hDbgNotifyLock);
+
+       /* Find which list to add it to */
+       for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
+       {
+               if (g_psDebugTable->asEntry[i].ui32RequesterID == ui32RequesterID)
+               {
+                       psHead = &g_psDebugTable->asEntry[i].sListHead;
+               }
+       }
+
+       if (psHead == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Failed to find debug requester", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_add;
+       }
+
+       /* Add it to the list of Notify functions */
+       dllist_add_to_tail(psHead, &psNotify->sListNode);
+
+       /* Unlock the lists */
+       OSWRLockReleaseWrite(g_hDbgNotifyLock);
+
+       *phNotify = psNotify;
+
+       return PVRSRV_OK;
+
+fail_add:
+       OSWRLockReleaseWrite(g_hDbgNotifyLock);
+       OSFreeMem(psNotify);
+fail_alloc:
+fail_params:
+       return eError;
+}
+
+/*
+       PVRSRVUnregisterCmdCompleteNotify
+*/
+PVRSRV_ERROR PVRSRVUnregisterDbgRequestNotify(IMG_HANDLE hNotify)
+{
+       PVRSRV_DBGREQ_NOTIFY *psNotify = (PVRSRV_DBGREQ_NOTIFY*) hNotify;
+
+       if (psNotify == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Bad arguments (%p)", __FUNCTION__, hNotify));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* remove the node from the list */
+       OSWRLockAcquireWrite(g_hDbgNotifyLock);
+       dllist_remove_node(&psNotify->sListNode);
+       OSWRLockReleaseWrite(g_hDbgNotifyLock);
+
+       /* free the notify structure that holds the node */
+       OSFreeMem(psNotify);
+
+       return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR PVRSRVRegisterDbgTable(IMG_UINT32 *paui32Table, IMG_UINT32 ui32Length, IMG_PVOID *phTable)
+{
+       IMG_UINT32 i;
+       if (g_psDebugTable != IMG_NULL)
+       {
+               return PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED;
+       }
+
+       g_psDebugTable = OSAllocMem(sizeof(DEBUG_REQUEST_TABLE) + (sizeof(DEBUG_REQUEST_ENTRY) * (ui32Length-1)));
+       if (!g_psDebugTable)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       g_psDebugTable->ui32RequestCount = ui32Length;
+
+       /* Init the list heads */
+       for (i=0;i<ui32Length;i++)
+       {
+               g_psDebugTable->asEntry[i].ui32RequesterID = paui32Table[i];
+               dllist_init(&g_psDebugTable->asEntry[i].sListHead);
+       }
+
+       *phTable = g_psDebugTable;
+       return PVRSRV_OK;
+}
+
+static IMG_VOID PVRSRVUnregisterDbgTable(IMG_PVOID hTable)
+{
+       IMG_UINT32 i;
+
+       PVR_ASSERT(hTable == g_psDebugTable);
+
+       for (i=0;i<g_psDebugTable->ui32RequestCount;i++)
+       {
+               if (!dllist_is_empty(&g_psDebugTable->asEntry[i].sListHead))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnregisterDbgTable: Found registered callback(s) on %d", i));
+               }
+       }
+       OSFREEMEM(g_psDebugTable);
+       g_psDebugTable = IMG_NULL;
+}
+
+PVRSRV_ERROR AcquireGlobalEventObjectServer(IMG_HANDLE *phGlobalEventObject)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       *phGlobalEventObject = psPVRSRVData->hGlobalEventObject;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR ReleaseGlobalEventObjectServer(IMG_HANDLE hGlobalEventObject)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       PVR_ASSERT(psPVRSRVData->hGlobalEventObject == hGlobalEventObject);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR GetBIFTilingHeapXStride(IMG_UINT32 uiHeapNum, IMG_UINT32 *puiXStride)
+{
+       IMG_UINT32 uiMaxHeaps;
+
+       PVR_ASSERT(puiXStride != IMG_NULL);
+
+       GetNumBifTilingHeapConfigs(&uiMaxHeaps);
+
+       if(uiHeapNum < 1 || uiHeapNum > uiMaxHeaps) {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *puiXStride = gpsSysConfig->pui32BIFTilingHeapConfigs[uiHeapNum - 1];
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR GetNumBifTilingHeapConfigs(IMG_UINT32 *puiNumHeaps)
+{
+       *puiNumHeaps = gpsSysConfig->ui32BIFTilingHeapCount;
+       return PVRSRV_OK;
+}
+
+/*
+       PVRSRVResetHWRLogsKM
+*/
+PVRSRV_ERROR PVRSRVResetHWRLogsKM(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVR_LOG(("User requested HWR logs reset"));
+
+       if(psDeviceNode && psDeviceNode->pfnResetHWRLogs)
+       {
+               return psDeviceNode->pfnResetHWRLogs(psDeviceNode);
+       }
+
+       return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+}
+
+/*****************************************************************************
+ End of file (pvrsrv.c)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/common/ri_server.c b/drivers/gpu/rogue_m/services/server/common/ri_server.c
new file mode 100644 (file)
index 0000000..6b2f6a3
--- /dev/null
@@ -0,0 +1,1298 @@
+/*************************************************************************/ /*!
+@File                  ri_server.c
+@Title          Resource Information (RI) server implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Resource Information (RI) server functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#include <stdarg.h>
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+
+#include "srvkm.h"
+#include "lock.h"
+/* services/server/include/ */
+#include "ri_server.h"
+
+/* services/include/shared/ */
+#include "hash.h"
+/* services/shared/include/ */
+#include "dllist.h"
+
+#include "pmr.h"
+
+#if defined(PVR_RI_DEBUG)
+
+#define USE_RI_LOCK    1
+
+/*
+ * Initial size use for Hash table.
+ * (Used to index the RI list entries).
+ */
+#define _RI_INITIAL_HASH_TABLE_SIZE    64
+
+/*
+ * Values written to the 'valid' field of
+ * RI structures when created and cleared
+ * prior to being destroyed.
+ * The code can then check this value
+ * before accessing the provided pointer
+ * contents as a valid RI structure.
+ */
+#define _VALID_RI_LIST_ENTRY   0x66bccb66
+#define _VALID_RI_SUBLIST_ENTRY        0x77cddc77
+#define _INVALID                               0x00000000
+
+/*
+ * If this define is set to 1, details of
+ * the linked lists (addresses, prev/next
+ * ptrs, etc) are also output when function
+ * RIDumpList() is called
+ */
+#define _DUMP_LINKEDLIST_INFO          0
+
+
+typedef IMG_UINT64 _RI_BASE_T;
+
+/*
+ *  Length of string used for process name
+ */
+#define TASK_COMM_LEN                          16
+/*
+ *  Length of string used for process ID
+ */
+#define TASK_PID_LEN                           11
+/*
+ *  Length of string used for "[{PID}:_{process_name}]"
+ */
+#define RI_PROC_TAG_CHAR_LEN           (1+TASK_PID_LEN+2+TASK_COMM_LEN+1)
+
+/*
+ *  Length of string used for address
+ */
+#define RI_ADDR_CHAR_LEN                       12
+/*
+ *  Length of string used for size
+ */
+#define RI_SIZE_CHAR_LEN                       12
+/*
+ *  Length of string used for "{Imported from PID nnnnnnnnnn}"
+ */
+#define RI_IMPORT_TAG_CHAR_LEN                 32
+/*
+ *  Total length of string returned to debugfs
+ *  {0xaddr}_{annotation_text}_{0xsize}_{import_tag}
+ */
+#define RI_MAX_DEBUGFS_ENTRY_LEN       (RI_ADDR_CHAR_LEN+1+RI_MAX_TEXT_LEN+1+RI_SIZE_CHAR_LEN+1+RI_IMPORT_TAG_CHAR_LEN+1)
+/*
+ *  Total length of string output to _RIOutput()
+ *  for MEMDESC RI sub-list entries
+ *  {0xaddr}_{annotation_text}_[{PID}:_{process_name}]_{0xsize}_bytes_{import_tag}
+ */
+#define RI_MAX_MEMDESC_RI_ENTRY_LEN    (RI_ADDR_CHAR_LEN+1+RI_MAX_TEXT_LEN+1+RI_PROC_TAG_CHAR_LEN+1+RI_SIZE_CHAR_LEN+7+RI_IMPORT_TAG_CHAR_LEN+1)
+/*
+ *  Total length of string output to _RIOutput()
+ *  for PMR RI list entries
+ *  {annotation_text}_{pmr_handle}_suballocs:{num_suballocs}_{0xsize}
+ */
+#define RI_MAX_PMR_RI_ENTRY_LEN                (RI_MAX_TEXT_LEN+1+RI_ADDR_CHAR_LEN+11+10+1+RI_SIZE_CHAR_LEN)
+
+
+/*
+ * Structure used to make linked sublist of
+ * memory allocations (MEMDESC)
+ */
+struct _RI_SUBLIST_ENTRY_
+{
+       DLLIST_NODE                             sListNode;
+       struct _RI_LIST_ENTRY_  *psRI;
+       IMG_UINT32                              valid;
+       IMG_BOOL                                bIsImport;
+       IMG_BOOL                                bIsExportable;
+       IMG_PID                                 pid;
+       IMG_CHAR                                ai8ProcName[TASK_COMM_LEN];
+       IMG_DEV_VIRTADDR                sVAddr;
+       IMG_UINT64                              ui64Offset;
+       IMG_UINT64                              ui64Size;
+       IMG_CHAR                                ai8TextB[RI_MAX_TEXT_LEN+1];
+       DLLIST_NODE                             sProcListNode;
+};
+
+/*
+ * Structure used to make linked list of
+ * PMRs. Sublists of allocations (MEMDESCs) made
+ * from these PMRs are chained off these entries.
+ */
+struct _RI_LIST_ENTRY_
+{
+       DLLIST_NODE                             sListNode;
+       DLLIST_NODE                             sSubListFirst;
+       IMG_UINT32                              valid;
+       PMR                                             *hPMR;
+       IMG_UINT64                              ui64LogicalSize;
+       IMG_PID                                 pid;
+       IMG_CHAR                                ai8ProcName[TASK_COMM_LEN];
+       IMG_CHAR                                ai8TextA[RI_MAX_TEXT_LEN+1];
+       IMG_UINT16                              ui16SubListCount;
+       IMG_UINT16                              ui16MaxSubListCount;
+};
+
+typedef struct _RI_LIST_ENTRY_ RI_LIST_ENTRY;
+typedef struct _RI_SUBLIST_ENTRY_ RI_SUBLIST_ENTRY;
+
+static IMG_UINT16      g_ui16RICount = 0;
+static HASH_TABLE      *g_pRIHashTable = IMG_NULL;
+static IMG_UINT16      g_ui16ProcCount = 0;
+static HASH_TABLE      *g_pProcHashTable = IMG_NULL;
+
+static POS_LOCK                g_hRILock;
+/*
+ * Flag used to indicate if RILock should be destroyed when final PMR entry
+ * is deleted, i.e. if RIDeInitKM() has already been called before that point
+ * but the handle manager has deferred deletion of RI entries.
+ */
+static IMG_BOOL        bRIDeInitDeferred = IMG_FALSE;
+
+/*
+ *  Used as head of linked-list of PMR RI entries -
+ *  this is useful when we wish to iterate all PMR
+ *  list entries (when we don't have a PMR ref)
+ */
+static DLLIST_NODE     sListFirst;
+
+/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */
+static IMG_VOID _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry, IMG_BOOL bDebugFs, IMG_UINT16 ui16MaxStrLen, IMG_CHAR *pszEntryString);
+
+static PVRSRV_ERROR _DumpAllEntries (IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+static PVRSRV_ERROR _DeleteAllEntries (IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+static PVRSRV_ERROR _DumpList(PMR *hPMR, IMG_PID pid);
+#define _RIOutput(x) PVR_LOG(x)
+
+IMG_INTERNAL IMG_UINT32
+_ProcHashFunc (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+IMG_INTERNAL IMG_UINT32
+_ProcHashFunc (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen)
+{
+       IMG_UINT32 *p = (IMG_UINT32 *)pKey;
+       IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32);
+       IMG_UINT32 ui;
+       IMG_UINT32 uHashKey = 0;
+
+       PVR_UNREFERENCED_PARAMETER(uHashTabLen);
+
+       for (ui = 0; ui < uKeyLen; ui++)
+       {
+               IMG_UINT32 uHashPart = *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_INTERNAL IMG_BOOL
+_ProcHashComp (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+IMG_INTERNAL IMG_BOOL
+_ProcHashComp (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2)
+{
+       IMG_UINT32 *p1 = (IMG_UINT32 *)pKey1;
+       IMG_UINT32 *p2 = (IMG_UINT32 *)pKey2;
+       IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32);
+       IMG_UINT32 ui;
+
+       for (ui = 0; ui < uKeyLen; ui++)
+       {
+               if (*p1++ != *p2++)
+                       return IMG_FALSE;
+       }
+
+       return IMG_TRUE;
+}
+
+static IMG_VOID _RILock(IMG_VOID)
+{
+#if (USE_RI_LOCK == 1)
+       OSLockAcquire(g_hRILock);
+#endif
+}
+
+static IMG_VOID _RIUnlock(IMG_VOID)
+{
+#if (USE_RI_LOCK == 1)
+       OSLockRelease(g_hRILock);
+#endif
+}
+
+PVRSRV_ERROR RIInitKM(IMG_VOID)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       bRIDeInitDeferred = IMG_FALSE;
+#if (USE_RI_LOCK == 1)
+       eError = OSLockCreate(&g_hRILock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: OSLockCreate failed (returned %d)",__func__,eError));
+       }
+#endif
+       return eError;
+}
+IMG_VOID RIDeInitKM(IMG_VOID)
+{
+#if (USE_RI_LOCK == 1)
+       if (g_ui16RICount > 0)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "%s: called with %d entries remaining - deferring OSLockDestroy()",__func__,g_ui16RICount));
+               bRIDeInitDeferred = IMG_TRUE;
+       }
+       else
+       {
+               OSLockDestroy(g_hRILock);
+       }
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIWritePMREntryKM
+
+ @Description
+            Writes a new Resource Information list entry.
+            The new entry will be inserted at the head of the list of
+            PMR RI entries and assigned the values provided.
+
+ @input     hPMR - Reference (handle) to the PMR to which this reference relates
+ @input     ai8TextA - String describing this PMR (may be null)
+ @input     uiLogicalSize - Size of PMR
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIWritePMREntryKM(PMR *hPMR,
+                                                      IMG_UINT32 ui32TextASize,
+                                                      const IMG_CHAR *psz8TextA,
+                                                      IMG_UINT64 ui64LogicalSize)
+{
+       IMG_UINTPTR_T hashData = 0;
+       PMR                     *pPMRHashKey = hPMR;
+       IMG_PCHAR pszText = (IMG_PCHAR)psz8TextA;
+       RI_LIST_ENTRY *psRIEntry = IMG_NULL;
+
+
+       /* if Hash table has not been created, create it now */
+       if (!g_pRIHashTable)
+       {
+               g_pRIHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(PMR*), HASH_Func_Default, HASH_Key_Comp_Default);
+               g_pProcHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(IMG_PID), _ProcHashFunc, _ProcHashComp);
+       }
+       if (!g_pRIHashTable || !g_pProcHashTable)
+       {
+               /* Error - no memory to allocate for Hash table(s) */
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       if (!hPMR)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       else
+       {
+               /* Acquire RI Lock */
+               _RILock();
+
+               /* look-up hPMR in Hash Table */
+               hashData = HASH_Retrieve_Extended (g_pRIHashTable, (IMG_VOID *)&pPMRHashKey);
+               psRIEntry = (RI_LIST_ENTRY *)hashData;
+               if (!psRIEntry)
+               {
+                       /*
+                        * If failed to find a matching existing entry, create a new one
+                        */
+                       psRIEntry = (RI_LIST_ENTRY *)OSAllocZMem(sizeof(RI_LIST_ENTRY));
+                       if (!psRIEntry)
+                       {
+                               /* Release RI Lock */
+                               _RIUnlock();
+                               /* Error - no memory to allocate for new RI entry */
+                               return PVRSRV_ERROR_OUT_OF_MEMORY;
+                       }
+                       else
+                       {
+                               /*
+                                * Add new RI Entry
+                                */
+                               if (g_ui16RICount == 0)
+                               {
+                                       /* Initialise PMR entry linked-list head */
+                                       dllist_init(&sListFirst);
+                               }
+                               g_ui16RICount++;
+
+                               dllist_init (&(psRIEntry->sSubListFirst));
+                               psRIEntry->ui16SubListCount = 0;
+                               psRIEntry->ui16MaxSubListCount = 0;
+                               psRIEntry->valid = _VALID_RI_LIST_ENTRY;
+                               psRIEntry->pid = OSGetCurrentProcessID();
+                               OSSNPrintf((IMG_CHAR *)psRIEntry->ai8ProcName, TASK_COMM_LEN, "%s", OSGetCurrentProcessName());
+                               /* Add PMR entry to linked-list of PMR entries */
+                               dllist_init (&(psRIEntry->sListNode));
+                               dllist_add_to_tail(&sListFirst,(PDLLIST_NODE)&(psRIEntry->sListNode));
+                       }
+
+                       if (pszText)
+                       {
+                               if (ui32TextASize > RI_MAX_TEXT_LEN)
+                                       ui32TextASize = RI_MAX_TEXT_LEN;
+
+                               /* copy ai8TextA field data */
+                               OSSNPrintf((IMG_CHAR *)psRIEntry->ai8TextA, ui32TextASize+1, "%s", pszText);
+
+                               /* ensure string is NUL-terminated */
+                               psRIEntry->ai8TextA[ui32TextASize] = '\0';
+                       }
+                       else
+                       {
+                               /* ensure string is NUL-terminated */
+                               psRIEntry->ai8TextA[0] = '\0';
+                       }
+                       psRIEntry->hPMR = hPMR;
+                       psRIEntry->ui64LogicalSize = ui64LogicalSize;
+
+                       /* Create index entry in Hash Table */
+                       HASH_Insert_Extended (g_pRIHashTable, (IMG_VOID *)&pPMRHashKey, (IMG_UINTPTR_T)psRIEntry);
+
+                       /* Store phRIHandle in PMR structure, so it can delete the associated RI entry when it destroys the PMR */
+                       PMRStoreRIHandle(hPMR, (IMG_PVOID)psRIEntry);
+               }
+               /* Release RI Lock */
+               _RIUnlock();
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIWriteMEMDESCEntryKM
+
+ @Description
+            Writes a new Resource Information sublist entry.
+            The new entry will be inserted at the head of the sublist of
+            the indicated PMR list entry, and assigned the values provided.
+
+ @input     hPMR - Reference (handle) to the PMR to which this MEMDESC RI entry relates
+ @input     ai8TextB - String describing this secondary reference (may be null)
+ @input     uiOffset - Offset from the start of the PMR at which this allocation begins
+ @input     uiSize - Size of this allocation
+ @input     bIsImport - Flag indicating if this is an allocation or an import
+ @input     bIsExportable - Flag indicating if this allocation is exportable
+ @output    phRIHandle - Handle to the created RI entry
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIWriteMEMDESCEntryKM(PMR *hPMR,
+                                                                  IMG_UINT32 ui32TextBSize,
+                                                                  const IMG_CHAR *psz8TextB,
+                                                                  IMG_UINT64 ui64Offset,
+                                                                  IMG_UINT64 ui64Size,
+                                                                  IMG_BOOL bIsImport,
+                                                                  IMG_BOOL bIsExportable,
+                                                                  RI_HANDLE *phRIHandle)
+{
+       IMG_UINTPTR_T hashData = 0;
+       PMR             *pPMRHashKey = hPMR;
+       IMG_PID         pid;
+       IMG_PCHAR pszText = (IMG_PCHAR)psz8TextB;
+       RI_LIST_ENTRY *psRIEntry = IMG_NULL;
+       RI_SUBLIST_ENTRY *psRISubEntry = IMG_NULL;
+
+
+       /* check Hash tables have been created (meaning at least one PMR has been defined) */
+       if (!g_pRIHashTable || !g_pProcHashTable)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       if (!hPMR || !phRIHandle)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       else
+       {
+               /* Acquire RI Lock */
+               _RILock();
+
+               *phRIHandle = IMG_NULL;
+
+               /* look-up hPMR in Hash Table */
+               hashData = HASH_Retrieve_Extended (g_pRIHashTable, (IMG_VOID *)&pPMRHashKey);
+               psRIEntry = (RI_LIST_ENTRY *)hashData;
+               if (!psRIEntry)
+               {
+                       /* Release RI Lock */
+                       _RIUnlock();
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+               }
+
+               psRISubEntry = (RI_SUBLIST_ENTRY *)OSAllocZMem(sizeof(RI_SUBLIST_ENTRY));
+               if (!psRISubEntry)
+               {
+                       /* Release RI Lock */
+                       _RIUnlock();
+                       /* Error - no memory to allocate for new RI sublist entry */
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+               else
+               {
+                       /*
+                        * Insert new entry in sublist
+                        */
+                       PDLLIST_NODE currentNode = dllist_get_next_node(&(psRIEntry->sSubListFirst));
+
+                       /*
+                        * Insert new entry before currentNode
+                        */
+                       if (!currentNode)
+                       {
+                               currentNode = &(psRIEntry->sSubListFirst);
+                       }
+                       dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sListNode));
+
+                       psRISubEntry->psRI = psRIEntry;
+
+                       /* Increment number of entries in sublist */
+                       psRIEntry->ui16SubListCount++;
+                       if (psRIEntry->ui16SubListCount > psRIEntry->ui16MaxSubListCount)
+                       {
+                               psRIEntry->ui16MaxSubListCount = psRIEntry->ui16SubListCount;
+                       }
+                       psRISubEntry->valid = _VALID_RI_SUBLIST_ENTRY;
+               }
+
+               psRISubEntry->pid = OSGetCurrentProcessID();
+
+               if (ui32TextBSize > RI_MAX_TEXT_LEN)
+                       ui32TextBSize = RI_MAX_TEXT_LEN;
+               /* copy ai8TextB field data */
+               OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8TextB, ui32TextBSize+1, "%s", pszText);
+               /* ensure string is NUL-terminated */
+               psRISubEntry->ai8TextB[ui32TextBSize] = '\0';
+
+               psRISubEntry->ui64Offset = ui64Offset;
+               psRISubEntry->ui64Size = ui64Size;
+               psRISubEntry->bIsImport = bIsImport;
+               psRISubEntry->bIsExportable = bIsExportable;
+               OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8ProcName, TASK_COMM_LEN, "%s", OSGetCurrentProcessName());
+               dllist_init (&(psRISubEntry->sProcListNode));
+
+               /*
+                *      Now insert this MEMDESC into the proc list
+                */
+               /* look-up pid in Hash Table */
+               pid = psRISubEntry->pid;
+               hashData = HASH_Retrieve_Extended (g_pProcHashTable, (IMG_VOID *)&pid);
+               if (!hashData)
+               {
+                       /*
+                        * No allocations for this pid yet
+                        */
+                       HASH_Insert_Extended (g_pProcHashTable, (IMG_VOID *)&pid, (IMG_UINTPTR_T)&(psRISubEntry->sProcListNode));
+                       /* Increment number of entries in proc hash table */
+                       g_ui16ProcCount++;
+               }
+               else
+               {
+                       /*
+                        * Insert allocation into pid allocations linked list
+                        */
+                       PDLLIST_NODE currentNode = (PDLLIST_NODE)hashData;
+
+                       /*
+                        * Insert new entry
+                        */
+                       dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sProcListNode));
+               }
+               *phRIHandle = (RI_HANDLE)psRISubEntry;
+               /* Release RI Lock */
+               _RIUnlock();
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIUpdateMEMDESCAddrKM
+
+ @Description
+            Update a Resource Information entry.
+
+ @input     hRIHandle - Handle of object whose reference info is to be updated
+ @input     uiAddr - New address for the RI entry
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIUpdateMEMDESCAddrKM(RI_HANDLE hRIHandle,
+                                                                  IMG_DEV_VIRTADDR sVAddr)
+{
+       RI_SUBLIST_ENTRY *psRISubEntry = IMG_NULL;
+
+       if (!hRIHandle)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle;
+       if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
+       {
+               /* Pointer does not point to valid structure */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+    /* Acquire RI lock*/
+       _RILock();
+
+       psRISubEntry->sVAddr.uiAddr = sVAddr.uiAddr;
+
+       /* Release RI lock */
+       _RIUnlock();
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDeletePMREntryKM
+
+ @Description
+            Delete a Resource Information entry.
+
+ @input     hRIHandle - Handle of object whose reference info is to be deleted
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDeletePMREntryKM(RI_HANDLE hRIHandle)
+{
+       RI_LIST_ENTRY *psRIEntry = IMG_NULL;
+       PMR                     *pPMRHashKey;
+       PVRSRV_ERROR eResult = PVRSRV_OK;
+
+
+       if (!hRIHandle)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       else
+       {
+               psRIEntry = (RI_LIST_ENTRY *)hRIHandle;
+
+               if (psRIEntry->valid != _VALID_RI_LIST_ENTRY)
+               {
+                       /* Pointer does not point to valid structure */
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+               }
+
+               if(psRIEntry->ui16SubListCount == 0)
+               {
+                   /* Acquire RI lock*/
+                       _RILock();
+
+                       /* Remove the HASH table index entry */
+                       pPMRHashKey = psRIEntry->hPMR;
+                       HASH_Remove_Extended(g_pRIHashTable, (IMG_VOID *)&pPMRHashKey);
+
+                       psRIEntry->valid = _INVALID;
+
+                       /* Remove PMR entry from linked-list of PMR entries */
+                       dllist_remove_node((PDLLIST_NODE)&(psRIEntry->sListNode));
+
+                       /* Now, free the memory used to store the RI entry */
+                       OSFreeMem(psRIEntry);
+                       psRIEntry = IMG_NULL;
+
+                   /* Release RI lock*/
+                       _RIUnlock();
+
+                       /*
+                        * Decrement number of RI entries - if this is now zero,
+                        * we can delete the RI hash table
+                        */
+                       if(--g_ui16RICount == 0)
+                       {
+                               HASH_Delete(g_pRIHashTable);
+                               g_pRIHashTable = IMG_NULL;
+                               /* If deInit has been deferred, we can now destroy the RI Lock */
+                               if (bRIDeInitDeferred)
+                               {
+                                       OSLockDestroy(g_hRILock);
+                               }
+                       }
+                       /*
+                        * Make the handle NULL once PMR RI entry is deleted
+                        */
+                       hRIHandle = IMG_NULL;
+               }
+               else
+               {
+                       eResult = PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
+               }
+       }
+
+       return eResult;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDeleteMEMDESCEntryKM
+
+ @Description
+            Delete a Resource Information entry.
+
+ @input     hRIHandle - Handle of object whose reference info is to be deleted
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDeleteMEMDESCEntryKM(RI_HANDLE hRIHandle)
+{
+       RI_LIST_ENTRY *psRIEntry = IMG_NULL;
+       RI_SUBLIST_ENTRY *psRISubEntry = IMG_NULL;
+       IMG_UINTPTR_T hashData = 0;
+       IMG_PID     pid;
+       PVRSRV_ERROR eResult = PVRSRV_OK;
+
+
+       if (!hRIHandle)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle;
+       if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
+       {
+               /* Pointer does not point to valid structure */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+    /* Acquire RI lock*/
+       _RILock();
+
+       psRIEntry = (RI_LIST_ENTRY *)psRISubEntry->psRI;
+
+       /* Now, remove entry from the sublist */
+       dllist_remove_node(&(psRISubEntry->sListNode));
+
+       psRISubEntry->valid = _INVALID;
+
+       /* Remove the entry from the proc allocations linked list */
+       pid = psRISubEntry->pid;
+       /* If this is the only allocation for this pid, just remove it from the hash table */
+       if (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == IMG_NULL)
+       {
+               HASH_Remove_Extended(g_pProcHashTable, (IMG_VOID *)&pid);
+               /* Decrement number of entries in proc hash table, and delete the hash table if there are now none */
+               if(--g_ui16ProcCount == 0)
+               {
+                       HASH_Delete(g_pProcHashTable);
+                       g_pProcHashTable = IMG_NULL;
+               }
+       }
+       else
+       {
+               hashData = HASH_Retrieve_Extended (g_pProcHashTable, (IMG_VOID *)&pid);
+               if ((PDLLIST_NODE)hashData == &(psRISubEntry->sProcListNode))
+               {
+                       HASH_Remove_Extended(g_pProcHashTable, (IMG_VOID *)&pid);
+                       HASH_Insert_Extended (g_pProcHashTable, (IMG_VOID *)&pid, (IMG_UINTPTR_T)dllist_get_next_node(&(psRISubEntry->sProcListNode)));
+               }
+       }
+       dllist_remove_node(&(psRISubEntry->sProcListNode));
+
+       /* Now, free the memory used to store the sublist entry */
+       OSFreeMem(psRISubEntry);
+       psRISubEntry = IMG_NULL;
+
+       /*
+        * Decrement number of entries in sublist
+        */
+       psRIEntry->ui16SubListCount--;
+
+    /* Release RI lock*/
+       _RIUnlock();
+
+       /*
+        * Make the handle NULL once MEMDESC RI entry is deleted
+        */
+       hRIHandle = IMG_NULL;
+
+       return eResult;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDeleteListKM
+
+ @Description
+            Delete all Resource Information entries and free associated
+            memory.
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDeleteListKM(IMG_VOID)
+{
+       PVRSRV_ERROR eResult = PVRSRV_OK;
+
+
+       if (g_pRIHashTable)
+       {
+               eResult = HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DeleteAllEntries);
+               if (eResult == PVRSRV_ERROR_RESOURCE_UNAVAILABLE)
+               {
+                       /*
+                        * PVRSRV_ERROR_RESOURCE_UNAVAILABLE is used to stop the Hash iterator when
+                        * the hash table gets deleted as a result of deleting the final PMR entry,
+                        * so this is not a real error condition...
+                        */
+                       eResult = PVRSRV_OK;
+               }
+       }
+       return eResult;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDumpListKM
+
+ @Description
+            Dumps out the contents of the RI List entry for the
+            specified PMR, and all MEMDESC allocation entries
+            in the associated sub linked list.
+            At present, output is directed to Kernel log
+            via PVR_DPF.
+
+ @input     hPMR - PMR for which RI entry details are to be output
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDumpListKM(PMR *hPMR)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       /* Acquire RI lock*/
+       _RILock();
+
+       eError = _DumpList(hPMR,0);
+
+    /* Release RI lock*/
+       _RIUnlock();
+
+       return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIGetListEntryKM
+
+ @Description
+            Returns pointer to a formatted string with details of the specified
+            list entry. If no entry exists (e.g. it may have been deleted
+            since the previous call), IMG_NULL is returned.
+
+ @input     pid - pid for which RI entry details are to be output
+ @input     ppHandle - handle to the entry, if IMG_NULL, the first entry will be
+                     returned.
+ @output    pszEntryString - string to be output for the entry
+ @output    hEntry - hEntry will be returned pointing to the next entry
+                     (or IMG_NULL if there is no next entry)
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+IMG_BOOL RIGetListEntryKM(IMG_PID pid,
+                                                 IMG_HANDLE **ppHandle,
+                                                 IMG_CHAR **ppszEntryString)
+{
+       RI_SUBLIST_ENTRY  *psRISubEntry = IMG_NULL;
+       IMG_UINTPTR_T     hashData      = 0;
+       IMG_PID           hashKey  = pid;
+
+       static IMG_CHAR   ai8DebugfsSummaryString[RI_MAX_DEBUGFS_ENTRY_LEN+1];
+       static IMG_UINT64 ui64TotalAlloc = 0;
+       static IMG_UINT64 ui64TotalImport = 0;
+       static IMG_BOOL bDisplaySummary = IMG_FALSE;
+       static IMG_BOOL bTerminateNextCall = IMG_FALSE;
+
+       if (bDisplaySummary)
+       {
+               OSSNPrintf((IMG_CHAR *)&ai8DebugfsSummaryString[0],
+                           RI_MAX_TEXT_LEN,
+                           "Alloc:0x%llx + Imports:0x%llx = Total:0x%llx\n",
+                           (unsigned long long)ui64TotalAlloc,
+                           (unsigned long long)ui64TotalImport,
+                           (unsigned long long)(ui64TotalAlloc+ui64TotalImport));
+               *ppszEntryString = &ai8DebugfsSummaryString[0];
+               ui64TotalAlloc = 0;
+               ui64TotalImport = 0;
+               bTerminateNextCall = IMG_TRUE;
+               bDisplaySummary = IMG_FALSE;
+               return IMG_TRUE;
+       }
+
+       if (bTerminateNextCall)
+       {
+               *ppszEntryString = IMG_NULL;
+               *ppHandle        = IMG_NULL;
+               bTerminateNextCall = IMG_FALSE;
+               return IMG_FALSE;
+       }
+
+    /* Acquire RI lock*/
+       _RILock();
+
+       /* look-up pid in Hash Table, to obtain first entry for pid */
+       hashData = HASH_Retrieve_Extended(g_pProcHashTable, (IMG_VOID *)&hashKey);
+       if (hashData)
+       {
+               if (*ppHandle)
+               {
+                       psRISubEntry = (RI_SUBLIST_ENTRY *)*ppHandle;
+                       if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
+                       {
+                               psRISubEntry = IMG_NULL;
+                       }
+               }
+               else
+               {
+                       psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode);
+                       if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
+                       {
+                               psRISubEntry = IMG_NULL;
+                       }
+               }
+       }
+
+       if (psRISubEntry)
+       {
+               PDLLIST_NODE  psNextProcListNode = dllist_get_next_node(&psRISubEntry->sProcListNode);
+
+               if (psNextProcListNode == IMG_NULL  ||
+                   psNextProcListNode == (PDLLIST_NODE)hashData)
+               {
+                       bDisplaySummary = IMG_TRUE;
+               }
+
+
+               if (psRISubEntry->bIsImport)
+               {
+                       ui64TotalImport += psRISubEntry->ui64Size;
+               }
+               else
+               {
+                       ui64TotalAlloc += psRISubEntry->ui64Size;
+               }
+
+
+               _GenerateMEMDESCEntryString(psRISubEntry,
+                                           IMG_TRUE,
+                                           RI_MAX_DEBUGFS_ENTRY_LEN,
+                                           (IMG_CHAR *)&ai8DebugfsSummaryString);
+               ai8DebugfsSummaryString[RI_MAX_DEBUGFS_ENTRY_LEN] = '\0';
+
+               *ppszEntryString = (IMG_CHAR *)&ai8DebugfsSummaryString;
+               *ppHandle        = (IMG_HANDLE)IMG_CONTAINER_OF(psNextProcListNode, RI_SUBLIST_ENTRY, sProcListNode);
+
+       }
+       else
+       {
+               bDisplaySummary = IMG_TRUE;
+               if (ui64TotalAlloc == 0)
+               {
+                       ai8DebugfsSummaryString[0] = '\0';
+                       *ppszEntryString = (IMG_CHAR *)&ai8DebugfsSummaryString;
+               }
+       }
+
+    /* Release RI lock*/
+       _RIUnlock();
+
+       return IMG_TRUE;
+}
+
+/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */
+static IMG_VOID _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry,
+                                            IMG_BOOL bDebugFs,
+                                            IMG_UINT16 ui16MaxStrLen,
+                                            IMG_CHAR *pszEntryString)
+{
+       IMG_CHAR        szProc[RI_PROC_TAG_CHAR_LEN];
+       IMG_CHAR        szImport[RI_IMPORT_TAG_CHAR_LEN];
+       IMG_PCHAR   pszAnnotationText = IMG_NULL;
+
+       if (!bDebugFs)
+       {
+               /* we don't include process ID info for debugfs output */
+               OSSNPrintf( (IMG_CHAR *)&szProc,
+                           RI_PROC_TAG_CHAR_LEN,
+                           "[%d: %s]",
+                           psRISubEntry->pid,
+                           (IMG_CHAR *)psRISubEntry->ai8ProcName);
+       }
+       if (psRISubEntry->bIsImport)
+       {
+               OSSNPrintf( (IMG_CHAR *)&szImport,
+                           RI_IMPORT_TAG_CHAR_LEN,
+                           "{Import from PID %d}",
+                           psRISubEntry->psRI->pid);
+               /* Set pszAnnotationText to that of the 'parent' PMR RI entry */
+               pszAnnotationText = (IMG_PCHAR)psRISubEntry->psRI->ai8TextA;
+       }
+       else
+       {
+               if (psRISubEntry->bIsExportable)
+               {
+                       /* Set pszAnnotationText to that of the 'parent' PMR RI entry */
+                       pszAnnotationText = (IMG_PCHAR)psRISubEntry->psRI->ai8TextA;
+               }
+               else
+               {
+                       /* Set pszAnnotationText to that of the MEMDESC RI entry */
+                       pszAnnotationText = (IMG_PCHAR)psRISubEntry->ai8TextB;
+               }
+       }
+       OSSNPrintf(pszEntryString,
+                  ui16MaxStrLen,
+                  "%s 0x%llx %-80s %s 0x%llx %s%c",
+                  (bDebugFs ? "" : "  "),
+                  (unsigned long long)(psRISubEntry->sVAddr.uiAddr + psRISubEntry->ui64Offset),
+                  pszAnnotationText,
+                  (bDebugFs ? "" : (char *)szProc),
+                  (unsigned long long)psRISubEntry->ui64Size,
+                  (psRISubEntry->bIsImport ? (char *)&szImport : ""),
+                  (bDebugFs ? '\n' : ' '));
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     _DumpList
+ @Description
+            Dumps out RI List entries according to parameters passed.
+
+ @input     hPMR - If not NULL, function will output the RI entries for
+                   the specified PMR only
+ @input     pid - If non-zero, the function will only output MEMDESC RI
+                                 entries made by the process with ID pid.
+                  If zero, all MEMDESC RI entries will be output.
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR _DumpList(PMR *hPMR, IMG_PID pid)
+{
+       RI_LIST_ENTRY *psRIEntry = IMG_NULL;
+       RI_SUBLIST_ENTRY *psRISubEntry = IMG_NULL;
+       IMG_UINT16 ui16SubEntriesParsed = 0;
+       IMG_UINTPTR_T hashData = 0;
+       IMG_PID           hashKey;
+       PMR                     *pPMRHashKey = hPMR;
+       IMG_BOOL        bDisplayedThisPMR = IMG_FALSE;
+
+
+       if (!hPMR)
+       {
+               /* NULL handle provided */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       if (g_pRIHashTable && g_pProcHashTable)
+       {
+               if (pid != 0)
+               {
+                       /* look-up pid in Hash Table */
+                       hashKey = pid;
+                       hashData = HASH_Retrieve_Extended (g_pProcHashTable, (IMG_VOID *)&hashKey);
+                       if (hashData)
+                       {
+                               psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode);
+                               if (psRISubEntry)
+                               {
+                                       psRIEntry = psRISubEntry->psRI;
+                               }
+                       }
+               }
+               else
+               {
+                       /* look-up hPMR in Hash Table */
+                       hashData = HASH_Retrieve_Extended (g_pRIHashTable, (IMG_VOID *)&pPMRHashKey);
+                       psRIEntry = (RI_LIST_ENTRY *)hashData;
+               }
+               if (!psRIEntry)
+               {
+                       /* No entry found in hash table */
+                       return PVRSRV_ERROR_NOT_FOUND;
+               }
+               while (psRIEntry)
+               {
+                       bDisplayedThisPMR = IMG_FALSE;
+                       /* Output details for RI entry */
+                       if (!pid)
+                       {
+                               _RIOutput (("%s (0x%p) suballocs:%d size:0x%llx",
+                                           psRIEntry->ai8TextA,
+                                           psRIEntry->hPMR,
+                                           (IMG_UINT)psRIEntry->ui16SubListCount,
+                                           (unsigned long long)psRIEntry->ui64LogicalSize));
+                               bDisplayedThisPMR = IMG_TRUE;
+                       }
+                       ui16SubEntriesParsed = 0;
+                       if(psRIEntry->ui16SubListCount)
+                       {
+#if _DUMP_LINKEDLIST_INFO
+                               _RIOutput (("RI LIST: {sSubListFirst.psNextNode:0x%x}",
+                                           (IMG_UINT)psRIEntry->sSubListFirst.psNextNode));
+#endif /* _DUMP_LINKEDLIST_INFO */
+                               if (!pid)
+                               {
+                                       psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)),
+                                                                       RI_SUBLIST_ENTRY, sListNode);
+                               }
+                               /* Traverse RI sublist and output details for each entry */
+                               while (psRISubEntry && (ui16SubEntriesParsed < psRIEntry->ui16SubListCount))
+                               {
+                                       if (!bDisplayedThisPMR)
+                                       {
+                                               _RIOutput (("%s (0x%p) suballocs:%d size:0x%llx",
+                                                           psRIEntry->ai8TextA,
+                                                           psRIEntry->hPMR,
+                                                           (IMG_UINT)psRIEntry->ui16SubListCount,
+                                                           (unsigned long long)psRIEntry->ui64LogicalSize));
+                                               bDisplayedThisPMR = IMG_TRUE;
+                                       }
+#if _DUMP_LINKEDLIST_INFO
+                                       _RIOutput (("RI LIST:    [this subentry:0x%x]",(IMG_UINT)psRISubEntry));
+                                       _RIOutput (("RI LIST:     psRI:0x%x",(IMG_UINT32)psRISubEntry->psRI));
+#endif /* _DUMP_LINKEDLIST_INFO */
+
+                                       {
+                                               IMG_CHAR szEntryString[RI_MAX_MEMDESC_RI_ENTRY_LEN];
+
+                                               _GenerateMEMDESCEntryString(psRISubEntry,
+                                                                           IMG_FALSE,
+                                                                           RI_MAX_MEMDESC_RI_ENTRY_LEN,
+                                                                           (IMG_CHAR *)&szEntryString);
+                                               szEntryString[RI_MAX_MEMDESC_RI_ENTRY_LEN-1] = '\0';
+                                               _RIOutput (("%s",(IMG_CHAR *)&szEntryString));
+                                       }
+
+                                       if (pid)
+                                       {
+                                               if((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == 0) ||
+                                                  (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData))
+                                               {
+                                                       psRISubEntry = IMG_NULL;
+                                               }
+                                               else
+                                               {
+                                                       psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)),
+                                                                                       RI_SUBLIST_ENTRY, sProcListNode);
+                                                       if (psRISubEntry)
+                                                       {
+                                                               if (psRIEntry != psRISubEntry->psRI)
+                                                               {
+                                                                       /*
+                                                                        * The next MEMDESC in the process linked list is in a different PMR
+                                                                        */
+                                                                       psRIEntry = psRISubEntry->psRI;
+                                                                       bDisplayedThisPMR = IMG_FALSE;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               ui16SubEntriesParsed++;
+                                               psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sListNode)),
+                                                                               RI_SUBLIST_ENTRY, sListNode);
+                                       }
+                               }
+                       }
+                       if (!pid)
+                       {
+                               if (ui16SubEntriesParsed != psRIEntry->ui16SubListCount)
+                               {
+                                       /*
+                                        * Output error message as sublist does not contain the
+                                        * number of entries indicated by sublist count
+                                        */
+                                       _RIOutput (("RI ERROR: RI sublist contains %d entries, not %d entries",
+                                                   ui16SubEntriesParsed,psRIEntry->ui16SubListCount));
+                               }
+                               else if (psRIEntry->ui16SubListCount && !dllist_get_next_node(&(psRIEntry->sSubListFirst)))
+                               {
+                                       /*
+                                        * Output error message as sublist is empty but sublist count
+                                        * is not zero
+                                        */
+                                       _RIOutput (("RI ERROR: ui16SubListCount=%d for empty RI sublist",
+                                                   psRIEntry->ui16SubListCount));
+                               }
+                       }
+                       psRIEntry = IMG_NULL;
+               }
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDumpAllKM
+
+ @Description
+            Dumps out the contents of all RI List entries (i.e. for all
+            MEMDESC allocations for each PMR).
+            At present, output is directed to Kernel log
+            via PVR_DPF.
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDumpAllKM(IMG_VOID)
+{
+       if (g_pRIHashTable)
+       {
+               return HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DumpAllEntries);
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     RIDumpProcessKM
+
+ @Description
+            Dumps out the contents of all MEMDESC RI List entries (for every
+            PMR) which have been allocate by the specified process only.
+            At present, output is directed to Kernel log
+            via PVR_DPF.
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RIDumpProcessKM(IMG_PID pid)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       IMG_UINT32  dummyPMR;
+
+       if (g_pProcHashTable)
+       {
+               /* Acquire RI lock*/
+               _RILock();
+
+               eError = _DumpList((PMR *)&dummyPMR,pid);
+
+           /* Release RI lock*/
+               _RIUnlock();
+       }
+       return eError;
+}
+
+static PVRSRV_ERROR _DumpAllEntries (IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+       RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v;
+
+       PVR_UNREFERENCED_PARAMETER (k);
+
+       return RIDumpListKM(psRIEntry->hPMR);
+}
+
+static PVRSRV_ERROR _DeleteAllEntries (IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+       RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v;
+       RI_SUBLIST_ENTRY *psRISubEntry;
+       PVRSRV_ERROR eResult = PVRSRV_OK;
+
+       PVR_UNREFERENCED_PARAMETER (k);
+
+       while ((eResult == PVRSRV_OK) && (psRIEntry->ui16SubListCount > 0))
+       {
+               psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)), RI_SUBLIST_ENTRY, sListNode);
+               eResult = RIDeleteMEMDESCEntryKM((RI_HANDLE)psRISubEntry);
+       }
+       if (eResult == PVRSRV_OK)
+       {
+               eResult = RIDeletePMREntryKM((RI_HANDLE)psRIEntry);
+               /*
+                * If we've deleted the Hash table, return
+                * an error to stop the iterator...
+                */
+               if (!g_pRIHashTable)
+               {
+                       eResult = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+               }
+       }
+       return eResult;
+}
+
+#endif /* if defined(PVR_RI_DEBUG) */
diff --git a/drivers/gpu/rogue_m/services/server/common/srvcore.c b/drivers/gpu/rogue_m/services/server/common/srvcore.c
new file mode 100644 (file)
index 0000000..72b1076
--- /dev/null
@@ -0,0 +1,791 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Common Bridge Module (kernel side)
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements core PVRSRV API, server side
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "ra.h"
+#include "pvr_bridge.h"
+#include "connection_server.h"
+#include "device.h"
+
+#include "pdump_km.h"
+
+#include "srvkm.h"
+#include "allocmem.h"
+#include "devicemem.h"
+
+#include "srvcore.h"
+#include "pvrsrv.h"
+#include "power.h"
+#include "lists.h"
+
+#include "rgx_options_km.h"
+#include "pvrversion.h"
+#include "lock.h"
+#include "osfunc.h"
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "physmem_lma.h"
+#include "services.h"
+#endif
+
+/* For the purpose of maintainability, it is intended that this file should not
+ * contain any OS specific #ifdefs. Please find a way to add e.g.
+ * an osfunc.c abstraction or override the entire function in question within
+ * env,*,pvr_bridge_k.c
+ */
+
+PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+static IMG_UINT16 g_BridgeDispatchTableStartOffsets[BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT] =
+{
+               [PVRSRV_BRIDGE_SRVCORE] = PVRSRV_BRIDGE_SRVCORE_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_SYNC] = PVRSRV_BRIDGE_SYNC_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_SYNCEXPORT] = PVRSRV_BRIDGE_SYNCEXPORT_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_SYNCSEXPORT] = PVRSRV_BRIDGE_SYNCSEXPORT_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_PDUMPCTRL] = PVRSRV_BRIDGE_PDUMPCTRL_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_MM] = PVRSRV_BRIDGE_MM_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_MMPLAT] = PVRSRV_BRIDGE_MMPLAT_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_CMM] = PVRSRV_BRIDGE_CMM_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_PDUMPMM] = PVRSRV_BRIDGE_PDUMPMM_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_PDUMP] = PVRSRV_BRIDGE_PDUMP_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_DMABUF] = PVRSRV_BRIDGE_DMABUF_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_DC] = PVRSRV_BRIDGE_DC_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_CACHEGENERIC] = PVRSRV_BRIDGE_CACHEGENERIC_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_SMM] = PVRSRV_BRIDGE_SMM_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_PVRTL] = PVRSRV_BRIDGE_PVRTL_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RI] = PVRSRV_BRIDGE_RI_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_VALIDATION] = PVRSRV_BRIDGE_VALIDATION_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_TUTILS] = PVRSRV_BRIDGE_TUTILS_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_DEVICEMEMHISTORY] = PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_FIRST,
+#if defined(SUPPORT_RGX)
+               /* Need a gap here to start next entry at element 150 */
+               [PVRSRV_BRIDGE_RGXTQ] = PVRSRV_BRIDGE_RGXTQ_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXCMP] = PVRSRV_BRIDGE_RGXCMP_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXINIT] = PVRSRV_BRIDGE_RGXINIT_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXTA3D] = PVRSRV_BRIDGE_RGXTA3D_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_BREAKPOINT] = PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_DEBUGMISC] = PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXPDUMP] = PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXHWPERF] = PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_RGXRAY] = PVRSRV_BRIDGE_RGXRAY_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_REGCONFIG] = PVRSRV_BRIDGE_REGCONFIG_DISPATCH_FIRST,
+               [PVRSRV_BRIDGE_TIMERQUERY] = PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_FIRST,
+#endif
+};
+
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+
+#if defined(DEBUG_BRIDGE_KM)
+PVRSRV_ERROR
+CopyFromUserWrapper(CONNECTION_DATA *psConnection,
+                                       IMG_UINT32 ui32DispatchTableEntry,
+                                       IMG_VOID *pvDest,
+                                       IMG_VOID *pvSrc,
+                                       IMG_UINT32 ui32Size)
+{
+       g_BridgeDispatchTable[ui32DispatchTableEntry].ui32CopyFromUserTotalBytes+=ui32Size;
+       g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size;
+       return OSBridgeCopyFromUser(psConnection, pvDest, pvSrc, ui32Size);
+}
+PVRSRV_ERROR
+CopyToUserWrapper(CONNECTION_DATA *psConnection,
+                                 IMG_UINT32 ui32DispatchTableEntry,
+                                 IMG_VOID *pvDest,
+                                 IMG_VOID *pvSrc,
+                                 IMG_UINT32 ui32Size)
+{
+       g_BridgeDispatchTable[ui32DispatchTableEntry].ui32CopyToUserTotalBytes+=ui32Size;
+       g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size;
+       return OSBridgeCopyToUser(psConnection, pvDest, pvSrc, ui32Size);
+}
+#else
+INLINE PVRSRV_ERROR
+CopyFromUserWrapper(CONNECTION_DATA *psConnection,
+                                       IMG_UINT32 ui32DispatchTableEntry,
+                                       IMG_VOID *pvDest,
+                                       IMG_VOID *pvSrc,
+                                       IMG_UINT32 ui32Size)
+{
+       PVR_UNREFERENCED_PARAMETER (ui32DispatchTableEntry);
+       return OSBridgeCopyFromUser(psConnection, pvDest, pvSrc, ui32Size);
+}
+INLINE PVRSRV_ERROR
+CopyToUserWrapper(CONNECTION_DATA *psConnection,
+                                 IMG_UINT32 ui32DispatchTableEntry,
+                                 IMG_VOID *pvDest,
+                                 IMG_VOID *pvSrc,
+                                 IMG_UINT32 ui32Size)
+{
+       PVR_UNREFERENCED_PARAMETER (ui32DispatchTableEntry);
+       return OSBridgeCopyToUser(psConnection, pvDest, pvSrc, ui32Size);
+}
+#endif
+
+PVRSRV_ERROR
+PVRSRVConnectKM(CONNECTION_DATA *psConnection,
+                               IMG_UINT32 ui32Flags,
+                               IMG_UINT32 ui32ClientBuildOptions,
+                               IMG_UINT32 ui32ClientDDKVersion,
+                               IMG_UINT32 ui32ClientDDKBuild,
+                               IMG_UINT8  *pui8KernelArch,
+                               IMG_UINT32 *ui32Log2PageSize)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       IMG_UINT32                      ui32BuildOptions, ui32BuildOptionsMismatch;
+       IMG_UINT32                      ui32DDKVersion, ui32DDKBuild;
+       
+       *ui32Log2PageSize = GET_LOG2_PAGESIZE();
+
+       psConnection->ui32ClientFlags = ui32Flags;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+       IMG_UINT32      ui32OSid = 0, ui32OSidReg = 0;
+
+       IMG_PID pIDCurrent = OSGetCurrentProcessID();
+
+       ui32OSid    = (ui32Flags & (OSID_BITS_FLAGS_MASK<<(OSID_BITS_FLAGS_OFFSET  ))) >> (OSID_BITS_FLAGS_OFFSET);
+       ui32OSidReg = (ui32Flags & (OSID_BITS_FLAGS_MASK<<(OSID_BITS_FLAGS_OFFSET+3))) >> (OSID_BITS_FLAGS_OFFSET+3);
+
+       InsertPidOSidsCoupling(pIDCurrent, ui32OSid, ui32OSidReg);
+
+       PVR_DPF((PVR_DBG_MESSAGE,"[GPU Virtualization Validation]: OSIDs: %d, %d\n",ui32OSid, ui32OSidReg));
+}
+#endif
+
+       PVR_UNREFERENCED_PARAMETER(ui32Flags);
+       if(ui32Flags & SRV_FLAGS_INIT_PROCESS)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: Connecting as init process", __func__));
+               if ((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Rejecting init process", __func__));
+                       eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
+                       goto chk_exit;
+               }
+#if defined (__linux__)
+               PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
+#endif
+       }
+       else
+       {
+               if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+               {
+                       if (!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed.  Driver unusable.",
+                                       __FUNCTION__));
+                               eError = PVRSRV_ERROR_INIT_FAILURE;
+                               goto chk_exit;
+                       }
+               }
+               else
+               {
+                       if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
+                                                __FUNCTION__));
+                               eError = PVRSRV_ERROR_RETRY;
+                               goto chk_exit;
+                       }
+                       else
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
+                                                __FUNCTION__));
+                               eError = PVRSRV_ERROR_RETRY;
+                               goto chk_exit;
+                       }
+               }
+       }
+       ui32ClientBuildOptions &= RGX_BUILD_OPTIONS_MASK_KM;
+       /*
+        * Validate the build options
+        */
+       ui32BuildOptions = (RGX_BUILD_OPTIONS_KM);
+       if (ui32BuildOptions != ui32ClientBuildOptions)
+       {
+               ui32BuildOptionsMismatch = ui32BuildOptions ^ ui32ClientBuildOptions;
+               if ( (ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) %s: Mismatch in client-side and KM driver build options; "
+                               "extra options present in client-side driver: (0x%x). Please check rgx_options.h",
+                               __FUNCTION__,
+                               ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
+               }
+
+               if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) %s: Mismatch in client-side and KM driver build options; "
+                               "extra options present in KM driver: (0x%x). Please check rgx_options.h",
+                               __FUNCTION__,
+                               ui32BuildOptions & ui32BuildOptionsMismatch ));
+               }
+               eError = PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH;
+               goto chk_exit;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: Client-side and KM driver build options match. [ OK ]", __FUNCTION__));
+       }
+
+       /*
+        * Validate DDK version
+        */
+       ui32DDKVersion = PVRVERSION_PACK(PVRVERSION_MAJ, PVRVERSION_MIN);
+       if (ui32ClientDDKVersion != ui32DDKVersion)
+       {
+               PVR_LOG(("(FAIL) %s: Incompatible driver DDK revision (%u.%u) / client DDK revision (%u.%u).",
+                               __FUNCTION__,
+                               PVRVERSION_MAJ, PVRVERSION_MIN,
+                               PVRVERSION_UNPACK_MAJ(ui32ClientDDKVersion),
+                               PVRVERSION_UNPACK_MIN(ui32ClientDDKVersion)));
+               eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
+               PVR_DBG_BREAK;
+               goto chk_exit;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: driver DDK revision (%u.%u) and client DDK revision (%u.%u) match. [ OK ]",
+                               __FUNCTION__,
+                               PVRVERSION_MAJ, PVRVERSION_MIN, PVRVERSION_MAJ, PVRVERSION_MIN));
+       }
+       
+       /*
+        * Validate DDK build
+        */
+       ui32DDKBuild = PVRVERSION_BUILD;
+       if (ui32ClientDDKBuild != ui32DDKBuild)
+       {
+               PVR_LOG(("(FAIL) %s: Incompatible driver DDK build (%d) / client DDK build (%d).",
+                               __FUNCTION__, ui32DDKBuild, ui32ClientDDKBuild));
+               eError = PVRSRV_ERROR_DDK_BUILD_MISMATCH;
+               PVR_DBG_BREAK;
+               goto chk_exit;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: driver DDK build (%d) and client DDK build (%d) match. [ OK ]",
+                               __FUNCTION__, ui32DDKBuild, ui32ClientDDKBuild));
+       }
+
+       /* Success so far so is it the PDump client that is connecting? */
+       if (ui32Flags & SRV_FLAGS_PDUMPCTRL)
+       {
+               PDumpConnectionNotify();
+       }
+
+       PVR_ASSERT(pui8KernelArch != NULL);
+       /* Can't use __SIZEOF_POINTER__ here as it is not defined on Windows */
+       if (sizeof(IMG_PVOID) == 8)
+       {
+               *pui8KernelArch = 64;
+       }
+       else
+       {
+               *pui8KernelArch = 32;
+       }
+
+
+#if defined(DEBUG_BRIDGE_KM)
+       {
+               int ii;
+
+               /* dump dispatch table offset lookup table */
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: g_BridgeDispatchTableStartOffsets[0-%lu] entries:", __FUNCTION__, BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT - 1));
+               for (ii=0; ii < BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT; ii++)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE, "g_BridgeDispatchTableStartOffsets[%d]: %u", ii, g_BridgeDispatchTableStartOffsets[ii]));
+               }
+       }
+#endif
+
+chk_exit:
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVDisconnectKM(IMG_VOID)
+{
+       /* just return OK, per-process data is cleaned up by resmgr */
+
+       return PVRSRV_OK;
+}
+
+/*
+       PVRSRVDumpDebugInfoKM
+*/
+PVRSRV_ERROR
+PVRSRVDumpDebugInfoKM(IMG_UINT32 ui32VerbLevel)
+{
+       if (ui32VerbLevel > DEBUG_REQUEST_VERBOSITY_MAX)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       PVR_LOG(("User requested PVR debug info"));
+
+       PVRSRVDebugRequest(ui32VerbLevel, IMG_NULL);
+                                                                          
+       return PVRSRV_OK;
+}
+
+/*
+       PVRSRVGetDevClockSpeedKM
+*/
+PVRSRV_ERROR
+PVRSRVGetDevClockSpeedKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                IMG_PUINT32  pui32RGXClockSpeed)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVR_ASSERT(psDeviceNode->pfnDeviceClockSpeed != IMG_NULL);
+
+       eError = psDeviceNode->pfnDeviceClockSpeed(psDeviceNode, pui32RGXClockSpeed);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetDevClockSpeedKM: "
+                               "Could not get device clock speed (%d)!",
+                               eError));
+       }
+
+       return eError;
+}
+
+
+/*
+       PVRSRVHWOpTimeoutKM
+*/
+PVRSRV_ERROR
+PVRSRVHWOpTimeoutKM(IMG_VOID)
+{
+#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
+       PVR_LOG(("User requested OS reset"));
+       OSPanic();
+#endif
+       PVR_LOG(("HW operation timeout, dump server info"));
+       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_LOW,IMG_NULL);
+       return PVRSRV_OK;
+}
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32DispatchTableEntry,
+               IMG_VOID *psBridgeIn,
+               IMG_VOID *psBridgeOut,
+               CONNECTION_DATA *psConnection)
+{
+#if !defined(DEBUG)
+       PVR_UNREFERENCED_PARAMETER(ui32DispatchTableEntry);
+#endif
+       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+       PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+#if defined(DEBUG_BRIDGE_KM)
+       PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: ui32DispatchTableEntry %u (%s) mapped to "
+                        "Dummy Wrapper (probably not what you want!)",
+                        __FUNCTION__, ui32DispatchTableEntry, g_BridgeDispatchTable[ui32DispatchTableEntry].pszIOCName));
+#else
+       PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: ui32DispatchTableEntry %u mapped to "
+                        "Dummy Wrapper (probably not what you want!)",
+                        __FUNCTION__, ui32DispatchTableEntry));
+#endif
+       return -ENOTTY;
+}
+
+
+/*
+       PVRSRVSoftResetKM
+*/
+PVRSRV_ERROR
+PVRSRVSoftResetKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+                  IMG_UINT64 ui64ResetValue1,
+                  IMG_UINT64 ui64ResetValue2)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if ((psDeviceNode == IMG_NULL) || (psDeviceNode->pfnSoftReset == IMG_NULL))
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       eError = psDeviceNode->pfnSoftReset(psDeviceNode, ui64ResetValue1, ui64ResetValue2);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "PVRSRVSoftResetKM: "
+                               "Failed to soft reset (error %d)",
+                               eError));
+       }
+
+       return eError;
+}
+
+
+/*!
+ * *****************************************************************************
+ * @brief A wrapper for filling in the g_BridgeDispatchTable array that does
+ *               error checking.
+ *
+ * @param ui32Index
+ * @param pszIOCName
+ * @param pfFunction
+ * @param pszFunctionName
+ *
+ * @return
+ ********************************************************************************/
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup,
+                                          IMG_UINT32 ui32Index,
+                                          const IMG_CHAR *pszIOCName,
+                                          BridgeWrapperFunction pfFunction,
+                                          const IMG_CHAR *pszFunctionName,
+                                          POS_LOCK hBridgeLock,
+                                          const IMG_CHAR *pszBridgeLockName,
+                                          IMG_BYTE* pbyBridgeBuffer,
+                                          IMG_UINT32 ui32BridgeInBufferSize,
+                                          IMG_UINT32 ui32BridgeOutBufferSize)
+{
+       static IMG_UINT32 ui32PrevIndex = IMG_UINT32_MAX;               /* -1 */
+#if !defined(DEBUG)
+       PVR_UNREFERENCED_PARAMETER(pszIOCName);
+#endif
+#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
+       PVR_UNREFERENCED_PARAMETER(pszFunctionName);
+       PVR_UNREFERENCED_PARAMETER(pszBridgeLockName);
+#endif
+
+       ui32Index += g_BridgeDispatchTableStartOffsets[ui32BridgeGroup];
+
+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
+       /* Enable this to dump out the dispatch table entries */
+       PVR_DPF((PVR_DBG_WARNING, "%s: g_BridgeDispatchTableStartOffsets[%d]=%d", __FUNCTION__, ui32BridgeGroup, g_BridgeDispatchTableStartOffsets[ui32BridgeGroup]));
+       PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName, pszBridgeLockName));
+#endif
+
+       /* Any gaps are sub-optimal in-terms of memory usage, but we are mainly
+        * interested in spotting any large gap of wasted memory that could be
+        * accidentally introduced.
+        *
+        * This will currently flag up any gaps > 5 entries.
+        *
+        * NOTE: This shouldn't be debug only since switching from debug->release
+        * etc is likely to modify the available ioctls and thus be a point where
+        * mistakes are exposed. This isn't run at at a performance critical time.
+        */
+       if((ui32PrevIndex != IMG_UINT32_MAX) &&
+          ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
+               (ui32Index <= ui32PrevIndex)))
+       {
+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
+               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_MESSAGE,
+                                "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
+                                __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
+#endif
+       }
+
+       if (ui32Index >= BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Index %u (%s) out of range",
+                                __FUNCTION__, (IMG_UINT)ui32Index, pszIOCName));
+
+#if defined(DEBUG_BRIDGE_KM)
+               PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE_DISPATCH_TABLE_ENTRY_COUNT = %lu",
+                                __FUNCTION__, BRIDGE_DISPATCH_TABLE_ENTRY_COUNT));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_TIMERQUERY_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_REGCONFIG_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_REGCONFIG_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXRAY_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXHWPERF_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXPDUMP_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_DEBUGMISC_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_BREAKPOINT_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXTA3D_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXINIT_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXINIT_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXCMP_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST = %lu\n",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGXTQ_DISPATCH_LAST));
+
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGX_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGX_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_RGX_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_RGX_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_TUTILS_DISPATCH_LAST));
+               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST = %lu",
+                                __FUNCTION__, PVRSRV_BRIDGE_VALIDATION_DISPATCH_LAST));
+#endif
+
+               OSPanic();
+       }
+
+       /* Panic if the previous entry has been overwritten as this is not allowed!
+        * NOTE: This shouldn't be debug only since switching from debug->release
+        * etc is likely to modify the available ioctls and thus be a point where
+        * mistakes are exposed. This isn't run at at a performance critical time.
+        */
+       if(g_BridgeDispatchTable[ui32Index].pfFunction)
+       {
+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
+               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));
+               PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+#endif
+               OSPanic();
+       }
+
+       g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
+       g_BridgeDispatchTable[ui32Index].hBridgeLock = hBridgeLock;
+       g_BridgeDispatchTable[ui32Index].pvBridgeBuffer = (IMG_PVOID) pbyBridgeBuffer;
+       g_BridgeDispatchTable[ui32Index].ui32BridgeInBufferSize = ui32BridgeInBufferSize;
+       g_BridgeDispatchTable[ui32Index].ui32BridgeOutBufferSize = ui32BridgeOutBufferSize;
+#if defined(DEBUG_BRIDGE_KM)
+       g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
+       g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
+       g_BridgeDispatchTable[ui32Index].pszBridgeLockName = pszBridgeLockName;
+       g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
+       g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
+#endif
+
+       ui32PrevIndex = ui32Index;
+}
+
+PVRSRV_ERROR
+PVRSRVInitSrvDisconnectKM(CONNECTION_DATA *psConnection,
+                                                       IMG_BOOL bInitSuccesful,
+                                                       IMG_UINT32 ui32ClientBuildOptions)
+{
+       PVRSRV_ERROR eError;
+
+       if(!(psConnection->ui32ClientFlags & SRV_FLAGS_INIT_PROCESS))
+       {
+               return PVRSRV_ERROR_SRV_DISCONNECT_FAILED;
+       }
+
+       PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
+       PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
+
+       eError = PVRSRVFinaliseSystem(bInitSuccesful, ui32ClientBuildOptions);
+
+       PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
+                               (eError == PVRSRV_OK) && bInitSuccesful);
+
+       return eError;
+}
+
+IMG_INT BridgedDispatchKM(CONNECTION_DATA * psConnection,
+                                         PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM)
+{
+
+       IMG_VOID   * psBridgeIn;
+       IMG_VOID   * psBridgeOut;
+       BridgeWrapperFunction pfBridgeHandler;
+       IMG_UINT32   ui32DispatchTableEntry;
+       IMG_INT      err          = -EFAULT;
+       IMG_UINT32      ui32BridgeInBufferSize;
+       IMG_UINT32      ui32BridgeOutBufferSize;
+
+#if defined(DEBUG_BRIDGE_KM_STOP_AT_DISPATCH)
+       PVR_DBG_BREAK;
+#endif
+
+       ui32DispatchTableEntry = g_BridgeDispatchTableStartOffsets[psBridgePackageKM->ui32BridgeID] + psBridgePackageKM->ui32FunctionID;
+
+#if defined(DEBUG_BRIDGE_KM)
+       PVR_DPF((PVR_DBG_MESSAGE, "%s: Dispatch table entry=%d, (bridge module %d, function %d)",
+                       __FUNCTION__, 
+                       ui32DispatchTableEntry, psBridgePackageKM->ui32BridgeID, psBridgePackageKM->ui32FunctionID));
+       PVR_DPF((PVR_DBG_MESSAGE, "%s: %s",
+                        __FUNCTION__,
+                        g_BridgeDispatchTable[ui32DispatchTableEntry].pszIOCName));
+       g_BridgeDispatchTable[ui32DispatchTableEntry].ui32CallCount++;
+       g_BridgeGlobalStats.ui32IOCTLCount++;
+#endif
+
+       if (g_BridgeDispatchTable[ui32DispatchTableEntry].hBridgeLock)
+       {
+               /* Acquire module specific bridge lock */
+               OSLockAcquire(g_BridgeDispatchTable[ui32DispatchTableEntry].hBridgeLock);
+               
+               /* Use buffers which are allocated for this bridge module */
+               psBridgeIn = g_BridgeDispatchTable[ui32DispatchTableEntry].pvBridgeBuffer;
+               ui32BridgeInBufferSize = g_BridgeDispatchTable[ui32DispatchTableEntry].ui32BridgeInBufferSize;
+               psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + ui32BridgeInBufferSize);
+               ui32BridgeOutBufferSize = g_BridgeDispatchTable[ui32DispatchTableEntry].ui32BridgeOutBufferSize;
+       }
+       else
+       {
+               /* Acquire default global bridge lock if calling module has no independent lock */
+               OSAcquireBridgeLock();
+
+               /* Request for global bridge buffers */
+               OSGetGlobalBridgeBuffers(&psBridgeIn,
+                                       &ui32BridgeInBufferSize,
+                                       &psBridgeOut,
+                                       &ui32BridgeOutBufferSize);
+       }
+
+       if (psBridgePackageKM->ui32InBufferSize > ui32BridgeInBufferSize)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Bridge input buffer too small "
+                       "(data size %u, buffer size %u)!", __FUNCTION__,
+                       psBridgePackageKM->ui32InBufferSize, ui32BridgeInBufferSize));
+               err = PVRSRV_ERROR_BUFFER_TOO_SMALL;
+               goto unlock_and_return_fault;
+       }
+
+       if (psBridgePackageKM->ui32OutBufferSize > ui32BridgeOutBufferSize)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Bridge output buffer too small "
+                       "(data size %u, buffer size %u)!", __FUNCTION__,
+                       psBridgePackageKM->ui32OutBufferSize, ui32BridgeOutBufferSize));
+               err = PVRSRV_ERROR_BUFFER_TOO_SMALL;
+               goto unlock_and_return_fault;
+       }
+
+       if((CopyFromUserWrapper (psConnection,
+                                       ui32DispatchTableEntry,
+                                       psBridgeIn,
+                                       psBridgePackageKM->pvParamIn,
+                                       psBridgePackageKM->ui32InBufferSize) != PVRSRV_OK)
+#if defined __QNXNTO__
+/* For Neutrino, the output bridge buffer acts as an input as well */
+                                       || (CopyFromUserWrapper(psConnection,
+                                                                                       ui32DispatchTableEntry,
+                                                                                       psBridgeOut,
+                                                                                       (IMG_PVOID)((IMG_UINT32)psBridgePackageKM->pvParamIn + psBridgePackageKM->ui32InBufferSize),
+                                                                                       psBridgePackageKM->ui32OutBufferSize) != PVRSRV_OK)
+#endif
+               ) /* end of if-condition */
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: CopyFromUserWrapper returned an error!", __FUNCTION__));
+               goto unlock_and_return_fault;
+       }
+
+       if(ui32DispatchTableEntry > (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: ui32DispatchTableEntry = %d is out if range!",
+                                __FUNCTION__, ui32DispatchTableEntry));
+               goto unlock_and_return_fault;
+       }
+       pfBridgeHandler =
+               (BridgeWrapperFunction)g_BridgeDispatchTable[ui32DispatchTableEntry].pfFunction;
+       
+       if (pfBridgeHandler == NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: ui32DispatchTableEntry = %d is not a registered function!",
+                                __FUNCTION__, ui32DispatchTableEntry));
+               goto unlock_and_return_fault;
+       }
+       
+       err = pfBridgeHandler(ui32DispatchTableEntry,
+                                                 psBridgeIn,
+                                                 psBridgeOut,
+                                                 psConnection);
+       if(err < 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: ...done (err=%d)", __FUNCTION__, err));
+               goto unlock_and_return_fault;
+       }
+
+       /* 
+          This should always be true as a.t.m. all bridge calls have to
+          return an error message, but this could change so we do this
+          check to be safe.
+       */
+       if (psBridgePackageKM->ui32OutBufferSize > 0)
+       {
+               err = -EFAULT;
+               if (CopyToUserWrapper (psConnection,
+                                               ui32DispatchTableEntry,
+                                               psBridgePackageKM->pvParamOut,
+                                               psBridgeOut,
+                                               psBridgePackageKM->ui32OutBufferSize) != PVRSRV_OK)
+               {
+                       goto unlock_and_return_fault;
+               }
+       }
+
+       err = 0;
+
+unlock_and_return_fault:
+       if (g_BridgeDispatchTable[ui32DispatchTableEntry].hBridgeLock)
+       {
+               OSLockRelease(g_BridgeDispatchTable[ui32DispatchTableEntry].hBridgeLock);
+       }
+       else
+       {
+               OSReleaseBridgeLock();
+       }
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: returning (err = %d)", __FUNCTION__, err));
+       }
+       return err;
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/sync_server.c b/drivers/gpu/rogue_m/services/server/common/sync_server.c
new file mode 100644 (file)
index 0000000..85d6f65
--- /dev/null
@@ -0,0 +1,2029 @@
+/*************************************************************************/ /*!
+@File           sync_server.c
+@Title          Server side synchronisation functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side functions that for synchronisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "img_types.h"
+#include "sync_server.h"
+#include "sync_server_internal.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "osfunc.h"
+#include "pdump.h"
+#include "pvr_debug.h"
+#include "pdump_km.h"
+#include "sync.h"
+#include "sync_internal.h"
+#include "pvrsrv.h"
+#include "debug_request_ids.h"
+#include "connection_server.h"
+
+#if defined(SUPPORT_SECURE_EXPORT)
+#include "ossecure_export.h"
+#endif
+
+#if defined(SUPPORT_EXTRA_METASP_DEBUG)
+#include "rgxdebug.h"
+#endif
+
+struct _SYNC_PRIMITIVE_BLOCK_
+{
+       PVRSRV_DEVICE_NODE      *psDevNode;
+       DEVMEM_MEMDESC          *psMemDesc;
+       DEVMEM_EXPORTCOOKIE     sExportCookie;
+       IMG_UINT32                      *pui32LinAddr;
+       IMG_UINT32                      ui32BlockSize;          /*!< Size of the Sync Primitive Block */
+       IMG_UINT32                      ui32RefCount;
+       POS_LOCK                        hLock;
+       DLLIST_NODE                     sConnectionNode;
+       SYNC_CONNECTION_DATA *psSyncConnectionData;     /*!< Link back to the sync connection data if there is one */
+       PRGXFWIF_UFO_ADDR               uiFWAddr;       /*!< The firmware address of the sync prim block */
+};
+
+struct _SERVER_SYNC_PRIMITIVE_
+{
+       PVRSRV_CLIENT_SYNC_PRIM *psSync;
+       IMG_UINT32                              ui32NextOp;
+       IMG_UINT32                              ui32RefCount;
+       IMG_UINT32                              ui32UID;
+       IMG_UINT32                              ui32LastSyncRequesterID;
+       DLLIST_NODE                             sNode;
+       /* PDump only data */
+       IMG_BOOL                                bSWOperation;
+       IMG_BOOL                                bSWOpStartedInCaptRange;
+       IMG_UINT32                              ui32LastHWUpdate;
+       IMG_BOOL                                bPDumped;
+       POS_LOCK                                hLock;
+       IMG_CHAR                                szClassName[SYNC_MAX_CLASS_NAME_LEN];
+};
+
+struct _SERVER_SYNC_EXPORT_
+{
+       SERVER_SYNC_PRIMITIVE *psSync;
+};
+
+struct _SERVER_OP_COOKIE_
+{
+       IMG_BOOL                                bActive;
+       /*
+               Client syncblock(s) info.
+               If this changes update the calculation of ui32BlockAllocSize
+       */
+       IMG_UINT32                              ui32SyncBlockCount;
+       SYNC_PRIMITIVE_BLOCK    **papsSyncPrimBlock;
+
+       /*
+               Client sync(s) info.
+               If this changes update the calculation of ui32ClientAllocSize
+       */
+       IMG_UINT32                              ui32ClientSyncCount;
+       IMG_UINT32                              *paui32SyncBlockIndex;
+       IMG_UINT32                              *paui32Index;
+       IMG_UINT32                              *paui32Flags;
+       IMG_UINT32                              *paui32FenceValue;
+       IMG_UINT32                              *paui32UpdateValue;
+
+       /*
+               Server sync(s) info
+               If this changes update the calculation of ui32ServerAllocSize
+       */
+       IMG_UINT32                              ui32ServerSyncCount;
+       SERVER_SYNC_PRIMITIVE   **papsServerSync;
+       IMG_UINT32                              *paui32ServerFenceValue;
+       IMG_UINT32                              *paui32ServerUpdateValue;
+
+};
+
+struct _SYNC_CONNECTION_DATA_
+{
+       DLLIST_NODE     sListHead;
+       IMG_UINT32      ui32RefCount;
+       POS_LOCK        hLock;
+};
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+#define DECREMENT_WITH_WRAP(value, sz) ((value) ? ((value) - 1) : ((sz) - 1))
+
+enum SYNC_RECORD_TYPE
+{
+       SYNC_RECORD_TYPE_UNKNOWN = 0,
+       SYNC_RECORD_TYPE_CLIENT,
+       SYNC_RECORD_TYPE_SERVER,
+};
+
+struct SYNC_RECORD
+{
+       SYNC_PRIMITIVE_BLOCK    *psServerSyncPrimBlock; /*!< handle to _SYNC_PRIMITIVE_BLOCK_ */
+       IMG_UINT32                              ui32SyncOffset;                 /*!< offset to sync in block */
+       IMG_UINT32                              ui32FwBlockAddr;
+       IMG_PID                                 uiPID;
+       IMG_UINT64                              ui64OSTime;
+       enum SYNC_RECORD_TYPE   eRecordType;
+       DLLIST_NODE                             sNode;
+       IMG_CHAR                                szClassName[SYNC_MAX_CLASS_NAME_LEN];
+};
+
+static POS_LOCK g_hSyncRecordListLock;
+static DLLIST_NODE g_sSyncRecordList;
+static IMG_UINT g_uiFreedSyncRecordIdx = 0;
+static struct SYNC_RECORD * g_apsFreedSyncRecords[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN] = {0};
+static IMG_HANDLE g_hSyncRecordNotify;
+#endif /* #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
+
+static IMG_UINT32 g_ServerSyncUID = 0;
+
+POS_LOCK g_hListLock;
+static DLLIST_NODE g_sAllServerSyncs;
+IMG_HANDLE g_hNotify;
+
+#define SYNC_REQUESTOR_UNKNOWN 0
+static IMG_UINT32 g_ui32NextSyncRequestorID = 1;
+
+#if defined(SYNC_DEBUG) || defined(REFCOUNT_DEBUG)
+#define SYNC_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__)
+#else
+#define SYNC_REFCOUNT_PRINT(fmt, ...)
+#endif
+
+#if defined(SYNC_DEBUG)
+#define SYNC_UPDATES_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__)
+#else
+#define SYNC_UPDATES_PRINT(fmt, ...)
+#endif
+
+/*!
+*****************************************************************************
+ @Function      : SyncPrimitiveBlockToFWAddr
+
+ @Description   : Given a pointer to a sync primitive block and an offset,
+                  returns the firmware address of the sync.
+
+ @Input           psSyncPrimBlock : Sync primitive block which contains the sync
+ @Input           ui32Offset      : Offset of sync within the sync primitive block
+ @Output          psAddrOut       : Absolute FW address of the sync is written out through
+                                    this pointer
+ @Return :        PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input
+                  parameters are invalid.
+*****************************************************************************/
+
+PVRSRV_ERROR
+SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock,
+                                                       IMG_UINT32 ui32Offset,
+                                               PRGXFWIF_UFO_ADDR *psAddrOut)
+{
+       /* check offset is legal */
+       if((ui32Offset >= psSyncPrimBlock->ui32BlockSize) ||
+                                               (ui32Offset % sizeof(IMG_UINT32)))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncPrimitiveBlockToFWAddr: parameters check failed"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psAddrOut->ui32Addr = psSyncPrimBlock->uiFWAddr.ui32Addr + ui32Offset;
+       return PVRSRV_OK;
+}
+
+/*!
+*****************************************************************************
+ @Function      : SyncAddrListGrow
+
+ @Description   : Grow the SYNC_ADDR_LIST so it can accommodate the given
+                  number of syncs
+
+ @Input           psList       : The SYNC_ADDR_LIST to grow
+ @Input           ui32NumSyncs : The number of sync addresses to be able to hold
+ @Return :        PVRSRV_OK on success
+*****************************************************************************/
+
+static PVRSRV_ERROR SyncAddrListGrow(SYNC_ADDR_LIST *psList, IMG_UINT32 ui32NumSyncs)
+{
+       if(ui32NumSyncs > psList->ui32NumSyncs)
+       {
+               OSFreeMem(psList->pasFWAddrs);
+               psList->pasFWAddrs = OSAllocMem(sizeof(PRGXFWIF_UFO_ADDR) * ui32NumSyncs);
+               if(psList->pasFWAddrs == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+
+               psList->ui32NumSyncs = ui32NumSyncs;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+*****************************************************************************
+ @Function      : SyncAddrListInit
+
+ @Description   : Initialise a SYNC_ADDR_LIST structure ready for use
+
+ @Input           psList        : The SYNC_ADDR_LIST structure to initialise
+ @Return        : None
+*****************************************************************************/
+
+IMG_VOID
+SyncAddrListInit(SYNC_ADDR_LIST *psList)
+{
+       psList->ui32NumSyncs = 0;
+}
+
+/*!
+*****************************************************************************
+ @Function      : SyncAddrListDeinit
+
+ @Description   : Frees any resources associated with the given SYNC_ADDR_LIST
+
+ @Input           psList        : The SYNC_ADDR_LIST structure to deinitialise
+ @Return        : None
+*****************************************************************************/
+
+IMG_VOID
+SyncAddrListDeinit(SYNC_ADDR_LIST *psList)
+{
+       if(psList->ui32NumSyncs != 0)
+       {
+               OSFreeMem(psList->pasFWAddrs);
+       }
+}
+
+/*!
+*****************************************************************************
+ @Function      : SyncAddrListPopulate
+
+ @Description   : Populate the given SYNC_ADDR_LIST with the FW addresses
+                  of the syncs given by the SYNC_PRIMITIVE_BLOCKs and sync offsets
+
+ @Input           ui32NumSyncs    : The number of syncs being passed in
+ @Input           apsSyncPrimBlock: Array of pointers to SYNC_PRIMITIVE_BLOCK structures
+                                    in which the syncs are based
+ @Input           paui32SyncOffset: Array of offsets within each of the sync primitive blocks
+                                    where the syncs are located
+ @Return :        PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input
+                  parameters are invalid.
+*****************************************************************************/
+
+PVRSRV_ERROR
+SyncAddrListPopulate(SYNC_ADDR_LIST *psList,
+                                               IMG_UINT32 ui32NumSyncs,
+                                               SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock,
+                                               IMG_UINT32 *paui32SyncOffset)
+{
+       IMG_UINT32 i;
+       PVRSRV_ERROR eError;
+
+       if(ui32NumSyncs > psList->ui32NumSyncs)
+       {
+               eError = SyncAddrListGrow(psList, ui32NumSyncs);
+
+               if(eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+       for(i = 0; i < ui32NumSyncs; i++)
+       {
+               eError = SyncPrimitiveBlockToFWAddr(apsSyncPrimBlock[i],
+                                                               paui32SyncOffset[i],
+                                                               &psList->pasFWAddrs[i]);
+
+               if(eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+PVRSRV_ERROR
+PVRSRVSyncRecordAddKM(
+                       SYNC_RECORD_HANDLE * phRecord,
+                       SYNC_PRIMITIVE_BLOCK * hServerSyncPrimBlock,
+                       IMG_UINT32 ui32FwBlockAddr,
+                       IMG_UINT32 ui32SyncOffset,
+                       IMG_BOOL bServerSync,
+                       IMG_UINT32 ui32ClassNameSize,
+                       const IMG_CHAR *pszClassName)
+{
+       struct SYNC_RECORD * psSyncRec;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if (!phRecord)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       *phRecord = IMG_NULL;
+
+       psSyncRec = OSAllocMem(sizeof(*psSyncRec));
+       if (!psSyncRec)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       psSyncRec->psServerSyncPrimBlock = hServerSyncPrimBlock;
+       psSyncRec->ui32SyncOffset = ui32SyncOffset;
+       psSyncRec->ui32FwBlockAddr = ui32FwBlockAddr;
+       psSyncRec->ui64OSTime = OSClockns64();
+       psSyncRec->uiPID = OSGetCurrentProcessID();
+       psSyncRec->eRecordType = bServerSync? SYNC_RECORD_TYPE_SERVER: SYNC_RECORD_TYPE_CLIENT;
+
+       if(pszClassName)
+       {
+               if (ui32ClassNameSize >= SYNC_MAX_CLASS_NAME_LEN)
+                       ui32ClassNameSize = SYNC_MAX_CLASS_NAME_LEN - 1;
+               /* Copy over the class name annotation */
+               OSStringNCopy(psSyncRec->szClassName, pszClassName, ui32ClassNameSize);
+               psSyncRec->szClassName[ui32ClassNameSize] = 0;
+       }
+       else
+       {
+               /* No class name annotation */
+               psSyncRec->szClassName[0] = 0;
+       }
+
+       OSLockAcquire(g_hSyncRecordListLock);
+       dllist_add_to_head(&g_sSyncRecordList, &psSyncRec->sNode);
+       OSLockRelease(g_hSyncRecordListLock);
+
+       *phRecord = (SYNC_RECORD_HANDLE)psSyncRec;
+
+fail_alloc:
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncRecordRemoveByHandleKM(
+                       SYNC_RECORD_HANDLE hRecord)
+{
+       struct SYNC_RECORD **ppFreedSync;
+       struct SYNC_RECORD *pSync = (struct SYNC_RECORD*)hRecord;
+
+       if (!hRecord)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       OSLockAcquire(g_hSyncRecordListLock);
+
+       dllist_remove_node(&pSync->sNode);
+
+       if (g_uiFreedSyncRecordIdx >= PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: g_uiFreedSyncRecordIdx out of range", __FUNCTION__));
+               g_uiFreedSyncRecordIdx = 0;
+       }
+       ppFreedSync = &g_apsFreedSyncRecords[g_uiFreedSyncRecordIdx];
+       g_uiFreedSyncRecordIdx = (g_uiFreedSyncRecordIdx + 1) % PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN;
+
+       if (*ppFreedSync)
+       {
+               OSFreeMem(*ppFreedSync);
+       }
+       pSync->psServerSyncPrimBlock = NULL;
+       pSync->ui64OSTime = OSClockns64();
+       *ppFreedSync = pSync;
+
+       OSLockRelease(g_hSyncRecordListLock);
+
+       return PVRSRV_OK;
+}
+#else
+PVRSRV_ERROR
+PVRSRVSyncRecordAddKM(
+                       SYNC_RECORD_HANDLE * phRecord,
+                       SYNC_PRIMITIVE_BLOCK * hServerSyncPrimBlock,
+                       IMG_UINT32 ui32FwBlockAddr,
+                       IMG_UINT32 ui32SyncOffset,
+                       IMG_BOOL bServerSync,
+                       IMG_UINT32 ui32ClassNameSize,
+                       const IMG_CHAR *pszClassName)
+{
+       *phRecord = IMG_NULL;
+       PVR_UNREFERENCED_PARAMETER(phRecord);
+       PVR_UNREFERENCED_PARAMETER(hServerSyncPrimBlock);
+       PVR_UNREFERENCED_PARAMETER(ui32FwBlockAddr);
+       PVR_UNREFERENCED_PARAMETER(ui32SyncOffset);
+       PVR_UNREFERENCED_PARAMETER(bServerSync);
+       PVR_UNREFERENCED_PARAMETER(ui32ClassNameSize);
+       PVR_UNREFERENCED_PARAMETER(pszClassName);
+       return PVRSRV_OK;
+}
+PVRSRV_ERROR
+PVRSRVSyncRecordRemoveByHandleKM(
+                       SYNC_RECORD_HANDLE hRecord)
+{
+       PVR_UNREFERENCED_PARAMETER(hRecord);
+       return PVRSRV_OK;
+}
+#endif /* #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
+
+static
+IMG_VOID _SyncConnectionRef(SYNC_CONNECTION_DATA *psSyncConnectionData)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSyncConnectionData->hLock);
+       ui32RefCount = ++psSyncConnectionData->ui32RefCount;
+       OSLockRelease(psSyncConnectionData->hLock);     
+
+       SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d",
+                                               __FUNCTION__, psSyncConnectionData, ui32RefCount);
+}
+
+static
+IMG_VOID _SyncConnectionUnref(SYNC_CONNECTION_DATA *psSyncConnectionData)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSyncConnectionData->hLock);
+       ui32RefCount = --psSyncConnectionData->ui32RefCount;
+       OSLockRelease(psSyncConnectionData->hLock);
+
+       if (ui32RefCount == 0)
+       {
+               SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d",
+                                                       __FUNCTION__, psSyncConnectionData, ui32RefCount);
+
+               PVR_ASSERT(dllist_is_empty(&psSyncConnectionData->sListHead));
+               OSLockDestroy(psSyncConnectionData->hLock);
+               OSFreeMem(psSyncConnectionData);
+       }
+       else
+       {
+               SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d",
+                                                       __FUNCTION__, psSyncConnectionData, ui32RefCount);
+       }
+}
+
+static
+IMG_VOID _SyncConnectionAddBlock(CONNECTION_DATA *psConnection, SYNC_PRIMITIVE_BLOCK *psBlock)
+{
+       if (psConnection)
+       {
+               SYNC_CONNECTION_DATA *psSyncConnectionData = psConnection->psSyncConnectionData;
+
+               /*
+                       Make sure the connection doesn't go away. It doesn't matter that we will release
+                       the lock between as the refcount and list don't have to be atomic w.r.t. to each other
+               */
+               _SyncConnectionRef(psSyncConnectionData);
+       
+               OSLockAcquire(psSyncConnectionData->hLock);
+               if (psConnection != IMG_NULL)
+               {
+                       dllist_add_to_head(&psSyncConnectionData->sListHead, &psBlock->sConnectionNode);
+               }
+               OSLockRelease(psSyncConnectionData->hLock);
+               psBlock->psSyncConnectionData = psSyncConnectionData;
+       }
+       else
+       {
+               psBlock->psSyncConnectionData = IMG_NULL;
+       }
+}
+
+static
+IMG_VOID _SyncConnectionRemoveBlock(SYNC_PRIMITIVE_BLOCK *psBlock)
+{
+       SYNC_CONNECTION_DATA *psSyncConnectionData = psBlock->psSyncConnectionData;
+
+       if (psBlock->psSyncConnectionData)
+       {
+               OSLockAcquire(psSyncConnectionData->hLock);
+               dllist_remove_node(&psBlock->sConnectionNode);
+               OSLockRelease(psSyncConnectionData->hLock);
+
+               _SyncConnectionUnref(psBlock->psSyncConnectionData);
+       }
+}
+
+static
+IMG_VOID _SyncPrimitiveBlockRef(SYNC_PRIMITIVE_BLOCK *psSyncBlk)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSyncBlk->hLock);
+       ui32RefCount = ++psSyncBlk->ui32RefCount;
+       OSLockRelease(psSyncBlk->hLock);
+
+       SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d",
+                                               __FUNCTION__, psSyncBlk, ui32RefCount);
+}
+
+static
+IMG_VOID _SyncPrimitiveBlockUnref(SYNC_PRIMITIVE_BLOCK *psSyncBlk)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSyncBlk->hLock);
+       ui32RefCount = --psSyncBlk->ui32RefCount;
+       OSLockRelease(psSyncBlk->hLock);
+
+       if (ui32RefCount == 0)
+       {
+               PVRSRV_DEVICE_NODE *psDevNode = psSyncBlk->psDevNode;
+
+               SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d (remove)",
+                                                       __FUNCTION__, psSyncBlk, ui32RefCount);
+
+               _SyncConnectionRemoveBlock(psSyncBlk);
+               OSLockDestroy(psSyncBlk->hLock);
+               DevmemUnexport(psSyncBlk->psMemDesc, &psSyncBlk->sExportCookie);
+               DevmemReleaseCpuVirtAddr(psSyncBlk->psMemDesc);
+               psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->psMemDesc);
+               OSFreeMem(psSyncBlk);
+       }
+       else
+       {
+               SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d",
+                                                       __FUNCTION__, psSyncBlk, ui32RefCount);
+       }
+}
+
+PVRSRV_ERROR
+PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection,
+                                                               PVRSRV_DEVICE_NODE *psDevNode,
+                                                               SYNC_PRIMITIVE_BLOCK **ppsSyncBlk,
+                                                               IMG_UINT32 *puiSyncPrimVAddr,
+                                                               IMG_UINT32 *puiSyncPrimBlockSize,
+                                                               DEVMEM_EXPORTCOOKIE **psExportCookie)
+{
+       SYNC_PRIMITIVE_BLOCK *psNewSyncBlk;
+       PVRSRV_ERROR eError;
+
+       psNewSyncBlk = OSAllocMem(sizeof(SYNC_PRIMITIVE_BLOCK));
+       if (psNewSyncBlk == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+       psNewSyncBlk->psDevNode = psDevNode;
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Allocate UFO block");
+
+       eError = psDevNode->pfnAllocUFOBlock(psDevNode,
+                                                                                &psNewSyncBlk->psMemDesc,
+                                                                                &psNewSyncBlk->uiFWAddr.ui32Addr,
+                                                                                &psNewSyncBlk->ui32BlockSize);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       *puiSyncPrimVAddr = psNewSyncBlk->uiFWAddr.ui32Addr;
+
+       eError = DevmemAcquireCpuVirtAddr(psNewSyncBlk->psMemDesc,
+                                                                         (IMG_PVOID *) &psNewSyncBlk->pui32LinAddr);
+       if (eError != PVRSRV_OK)
+       {
+               goto e2;
+       }
+
+       eError = DevmemExport(psNewSyncBlk->psMemDesc, &psNewSyncBlk->sExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               goto e3;
+       }
+
+       eError = OSLockCreate(&psNewSyncBlk->hLock, LOCK_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               goto e4;
+       }
+
+       psNewSyncBlk->ui32RefCount = 1;
+
+       /* If there is a connection pointer then add the new block onto it's list */
+       _SyncConnectionAddBlock(psConnection, psNewSyncBlk);
+
+       *psExportCookie = &psNewSyncBlk->sExportCookie;
+       *ppsSyncBlk = psNewSyncBlk;
+       *puiSyncPrimBlockSize = psNewSyncBlk->ui32BlockSize;
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+                                                 "Allocated UFO block (FirmwareVAddr = 0x%08x)",
+                                                 *puiSyncPrimVAddr);
+
+       return PVRSRV_OK;
+e4:
+       DevmemUnexport(psNewSyncBlk->psMemDesc, &psNewSyncBlk->sExportCookie);
+
+e3:
+       DevmemReleaseCpuVirtAddr(psNewSyncBlk->psMemDesc);
+e2:
+       psDevNode->pfnFreeUFOBlock(psDevNode, psNewSyncBlk->psMemDesc);
+e1:
+       OSFreeMem(psNewSyncBlk);
+e0:
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVFreeSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk)
+{
+       _SyncPrimitiveBlockUnref(psSyncBlk);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimSetKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Index,
+                                       IMG_UINT32 ui32Value)
+{
+       if((ui32Index * sizeof(IMG_UINT32)) < psSyncBlk->ui32BlockSize)
+       {
+               psSyncBlk->pui32LinAddr[ui32Index] = ui32Value;
+               return PVRSRV_OK;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncPrimSetKM: Index %u out of range for "
+                                                       "0x%08X byte sync block (value 0x%08X)",
+                                                       ui32Index,
+                                                       psSyncBlk->ui32BlockSize,
+                                                       ui32Value));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncPrimSetKM(SERVER_SYNC_PRIMITIVE *psServerSync, IMG_UINT32 ui32Value)
+{
+       *psServerSync->psSync->pui32LinAddr = ui32Value;
+
+       return PVRSRV_OK;
+}
+
+IMG_VOID
+ServerSyncRef(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSync->hLock);
+       ui32RefCount = ++psSync->ui32RefCount;
+       OSLockRelease(psSync->hLock);
+
+       SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
+                                               __FUNCTION__, psSync, ui32RefCount);
+}
+
+IMG_VOID
+ServerSyncUnref(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       IMG_UINT32 ui32RefCount;
+
+       OSLockAcquire(psSync->hLock);
+       ui32RefCount = --psSync->ui32RefCount;
+       OSLockRelease(psSync->hLock);
+
+       if (ui32RefCount == 0)
+       {
+               SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
+                                                       __FUNCTION__, psSync, ui32RefCount);
+
+               /* Remove the sync from the global list */
+               OSLockAcquire(g_hListLock);
+               dllist_remove_node(&psSync->sNode);
+               OSLockRelease(g_hListLock);
+
+               OSLockDestroy(psSync->hLock);
+               SyncPrimFree(psSync->psSync);
+               OSFreeMem(psSync);
+       }
+       else
+       {
+               SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
+                                                       __FUNCTION__, psSync, ui32RefCount);
+       }
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncAllocKM(PVRSRV_DEVICE_NODE *psDevNode,
+                                               SERVER_SYNC_PRIMITIVE **ppsSync,
+                                               IMG_UINT32 *pui32SyncPrimVAddr,
+                                               IMG_UINT32 ui32ClassNameSize,
+                                               const IMG_CHAR *pszClassName)
+{
+       SERVER_SYNC_PRIMITIVE *psNewSync;
+       PVRSRV_ERROR eError;
+
+       psNewSync = OSAllocMem(sizeof(SERVER_SYNC_PRIMITIVE));
+       if (psNewSync == IMG_NULL)
+       {
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* szClassName must be setup now and used for the SyncPrimAlloc call because
+        * pszClassName is allocated in the bridge code is not NULL terminated 
+        */
+       if(pszClassName)
+       {
+               if (ui32ClassNameSize >= SYNC_MAX_CLASS_NAME_LEN)
+                       ui32ClassNameSize = SYNC_MAX_CLASS_NAME_LEN - 1;
+               /* Copy over the class name annotation */
+               OSStringNCopy(psNewSync->szClassName, pszClassName, ui32ClassNameSize);
+               psNewSync->szClassName[ui32ClassNameSize] = 0;
+       }
+       else
+       {
+               /* No class name annotation */
+               psNewSync->szClassName[0] = 0;
+       }
+
+       eError = SyncPrimAllocForServerSync(psDevNode->hSyncPrimContext,
+                                                  &psNewSync->psSync,
+                                                  psNewSync->szClassName);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_sync_alloc;
+       }
+
+       eError = OSLockCreate(&psNewSync->hLock, LOCK_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_lock_create;
+       }
+
+       SyncPrimSet(psNewSync->psSync, 0);
+
+       psNewSync->ui32NextOp = 0;
+       psNewSync->ui32RefCount = 1;
+       psNewSync->ui32UID = g_ServerSyncUID++;
+       psNewSync->ui32LastSyncRequesterID = SYNC_REQUESTOR_UNKNOWN;
+       psNewSync->bSWOperation = IMG_FALSE;
+       psNewSync->ui32LastHWUpdate = 0x0bad592c;
+       psNewSync->bPDumped = IMG_FALSE;
+
+       /* Add the sync to the global list */
+       OSLockAcquire(g_hListLock);
+       dllist_add_to_head(&g_sAllServerSyncs, &psNewSync->sNode);
+       OSLockRelease(g_hListLock);
+
+       *pui32SyncPrimVAddr = SyncPrimGetFirmwareAddr(psNewSync->psSync);
+       SYNC_UPDATES_PRINT("%s: sync: %p, fwaddr: %8.8X", __FUNCTION__, psNewSync, *pui32SyncPrimVAddr);
+       *ppsSync = psNewSync;
+       return PVRSRV_OK;
+
+fail_lock_create:
+       SyncPrimFree(psNewSync->psSync);
+
+fail_sync_alloc:
+       OSFreeMem(psNewSync);
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncFreeKM(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       ServerSyncUnref(psSync);
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncGetStatusKM(IMG_UINT32 ui32SyncCount,
+                                                       SERVER_SYNC_PRIMITIVE **papsSyncs,
+                                                       IMG_UINT32 *pui32UID,
+                                                       IMG_UINT32 *pui32FWAddr,
+                                                       IMG_UINT32 *pui32CurrentOp,
+                                                       IMG_UINT32 *pui32NextOp)
+{
+       IMG_UINT32 i;
+
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               PVRSRV_CLIENT_SYNC_PRIM *psClientSync = papsSyncs[i]->psSync;
+
+               pui32UID[i] = papsSyncs[i]->ui32UID;
+               pui32FWAddr[i] = SyncPrimGetFirmwareAddr(psClientSync);
+               pui32CurrentOp[i] = *psClientSync->pui32LinAddr;
+               pui32NextOp[i] = papsSyncs[i]->ui32NextOp;
+       }
+       return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_INSECURE_EXPORT) || defined(SUPPORT_SECURE_EXPORT)
+static PVRSRV_ERROR
+_PVRSRVSyncPrimServerExportKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                         SERVER_SYNC_EXPORT **ppsExport)
+{
+       SERVER_SYNC_EXPORT *psNewExport;
+       PVRSRV_ERROR eError;
+
+       psNewExport = OSAllocMem(sizeof(SERVER_SYNC_EXPORT));
+       if (!psNewExport)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       ServerSyncRef(psSync);
+
+       psNewExport->psSync = psSync;
+       *ppsExport = psNewExport;
+
+       return PVRSRV_OK;
+e0:
+       return eError;
+}
+
+static PVRSRV_ERROR
+_PVRSRVSyncPrimServerUnexportKM(SERVER_SYNC_EXPORT *psExport)
+{
+       ServerSyncUnref(psExport->psSync);
+
+       OSFreeMem(psExport);
+
+       return PVRSRV_OK;
+}
+
+static IMG_VOID
+_PVRSRVSyncPrimServerImportKM(SERVER_SYNC_EXPORT *psExport,
+                                                         SERVER_SYNC_PRIMITIVE **ppsSync,
+                                                         IMG_UINT32 *pui32SyncPrimVAddr)
+{
+       ServerSyncRef(psExport->psSync);
+
+       *ppsSync = psExport->psSync;
+       *pui32SyncPrimVAddr = SyncPrimGetFirmwareAddr(psExport->psSync->psSync);
+}
+#endif /* defined(SUPPORT_INSECURE_EXPORT) || defined(SUPPORT_SECURE_EXPORT) */
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+PVRSRV_ERROR
+PVRSRVSyncPrimServerExportKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                       SERVER_SYNC_EXPORT **ppsExport)
+{
+       return _PVRSRVSyncPrimServerExportKM(psSync,
+                                                                                ppsExport);
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerUnexportKM(SERVER_SYNC_EXPORT *psExport)
+{
+       return _PVRSRVSyncPrimServerUnexportKM(psExport);
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerImportKM(SERVER_SYNC_EXPORT *psExport,
+                                                       SERVER_SYNC_PRIMITIVE **ppsSync,
+                                                       IMG_UINT32 *pui32SyncPrimVAddr)
+{
+       _PVRSRVSyncPrimServerImportKM(psExport,
+                                                                 ppsSync,
+                                                                 pui32SyncPrimVAddr);
+
+       return PVRSRV_OK;
+}
+#endif /* defined(SUPPORT_INSECURE_EXPORT) */
+
+#if defined(SUPPORT_SECURE_EXPORT)
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureExportKM(CONNECTION_DATA *psConnection,
+                                                                  SERVER_SYNC_PRIMITIVE *psSync,
+                                                                  IMG_SECURE_TYPE *phSecure,
+                                                                  SERVER_SYNC_EXPORT **ppsExport,
+                                                                  CONNECTION_DATA **ppsSecureConnection)
+{
+       SERVER_SYNC_EXPORT *psNewExport;
+       PVRSRV_ERROR eError;
+
+       /* Create an export server sync */
+       eError = _PVRSRVSyncPrimServerExportKM(psSync,
+                                                                                  &psNewExport);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       /* Transform it into a secure export */
+       eError = OSSecureExport(psConnection,
+                                                       (IMG_PVOID) psNewExport,
+                                                       phSecure,
+                                                       ppsSecureConnection);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       *ppsExport = psNewExport;
+       return PVRSRV_OK;
+e1:
+       _PVRSRVSyncPrimServerUnexportKM(psNewExport);
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/* FIXME: This is the same as the non-secure version. */
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureUnexportKM(SERVER_SYNC_EXPORT *psExport)
+{
+       _PVRSRVSyncPrimServerUnexportKM(psExport);
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureImportKM(IMG_SECURE_TYPE hSecure,
+                                                                  SERVER_SYNC_PRIMITIVE **ppsSync,
+                                                                  IMG_UINT32 *pui32SyncPrimVAddr)
+{
+       PVRSRV_ERROR eError;
+       SERVER_SYNC_EXPORT *psImport;
+
+       /* Retrieve the data from the secure import */
+       eError = OSSecureImport(hSecure, (IMG_PVOID *) &psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       _PVRSRVSyncPrimServerImportKM(psImport,
+                                                                 ppsSync,
+                                                                 pui32SyncPrimVAddr);
+       return PVRSRV_OK;
+
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+#endif /* defined(SUPPORT_SECURE_EXPORT) */
+
+IMG_UINT32 PVRSRVServerSyncRequesterRegisterKM(IMG_UINT32 *pui32SyncRequesterID)
+{
+       *pui32SyncRequesterID = g_ui32NextSyncRequestorID++;
+
+       return PVRSRV_OK;
+}
+
+IMG_VOID PVRSRVServerSyncRequesterUnregisterKM(IMG_UINT32 ui32SyncRequesterID)
+{
+       PVR_UNREFERENCED_PARAMETER(ui32SyncRequesterID);
+}
+
+static IMG_VOID
+_ServerSyncTakeOperation(SERVER_SYNC_PRIMITIVE *psSync,
+                                                 IMG_BOOL bUpdate,
+                                                 IMG_UINT32 *pui32FenceValue,
+                                                 IMG_UINT32 *pui32UpdateValue)
+{
+       IMG_BOOL bInCaptureRange;
+
+       /* Only advance the pending if the an update is required */
+       if (bUpdate)
+       {
+               *pui32FenceValue = psSync->ui32NextOp++;
+       }
+       else
+       {
+               *pui32FenceValue = psSync->ui32NextOp;
+       }
+
+       *pui32UpdateValue = psSync->ui32NextOp;
+
+       PDumpIsCaptureFrameKM(&bInCaptureRange);
+       /*
+               If this is the 1st operation (in this capture range) then PDump
+               this sync
+       */
+       if (!psSync->bPDumped && bInCaptureRange)
+       {
+               IMG_CHAR azTmp[100];
+               OSSNPrintf(azTmp,
+                                  sizeof(azTmp),
+                                  "Dump initial sync state (0x%p, FW VAddr = 0x%08x) = 0x%08x\n",
+                                  psSync,
+                                  SyncPrimGetFirmwareAddr(psSync->psSync),
+                                  *psSync->psSync->pui32LinAddr);
+               PDumpCommentKM(azTmp, 0);
+
+               SyncPrimPDump(psSync->psSync);
+               psSync->bPDumped = IMG_TRUE;
+       }
+
+       /*
+               When exiting capture range clear down bPDumped as we might re-enter
+               capture range and thus need to PDump this sync again
+       */
+       if (!bInCaptureRange)
+       {
+               psSync->bPDumped = IMG_FALSE;
+       }
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncQueueSWOpKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                 IMG_UINT32 *pui32FenceValue,
+                                                 IMG_UINT32 *pui32UpdateValue,
+                                                 IMG_UINT32 ui32SyncRequesterID,
+                                                 IMG_BOOL bUpdate,
+                                                 IMG_BOOL *pbFenceRequired)
+{
+
+       ServerSyncRef(psSync);
+
+       /*
+               ServerSyncRef will acquire and release the lock but we need to
+               reacquire here to ensure the state that we're modifying below
+               will be consistent with itself. But it doesn't matter if another
+               thread acquires the lock in between as we've ensured the sync
+               wont go away
+       */
+       OSLockAcquire(psSync->hLock);
+       _ServerSyncTakeOperation(psSync,
+                                                        bUpdate,
+                                                        pui32FenceValue,
+                                                        pui32UpdateValue);
+
+       /*
+               The caller want to know if a fence command is required
+               i.e. was the last operation done on this sync done by the
+               the same sync requestor
+       */
+       if (pbFenceRequired)
+       {
+               if (ui32SyncRequesterID == psSync->ui32LastSyncRequesterID)
+               {
+                       *pbFenceRequired = IMG_FALSE;
+               }
+               else
+               {
+                       *pbFenceRequired = IMG_TRUE;
+               }
+       }
+       /*
+               If we're transitioning from a HW operation to a SW operation we
+               need to save the last update the HW will do so that when we PDump
+               we can issue a POL for it before the next HW operation and then
+               LDB in the last SW fence update
+       */
+       if (psSync->bSWOperation == IMG_FALSE)
+       {
+               psSync->bSWOperation = IMG_TRUE;
+               psSync->ui32LastHWUpdate = *pui32FenceValue;
+               PDumpIsCaptureFrameKM(&psSync->bSWOpStartedInCaptRange);
+       }
+
+       if (pbFenceRequired)
+       {
+               if (*pbFenceRequired)
+               {
+                       SYNC_UPDATES_PRINT("%s: sync: %p, fence: %d, value: %d", __FUNCTION__, psSync, *pui32FenceValue, *pui32UpdateValue);
+               }
+       }
+
+       /* Only update the last requester id if we are make changes to this sync
+        * object. */
+       if (bUpdate)
+               psSync->ui32LastSyncRequesterID = ui32SyncRequesterID;
+
+       OSLockRelease(psSync->hLock);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVServerSyncQueueHWOpKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                      IMG_BOOL bUpdate,
+                                                      IMG_UINT32 *pui32FenceValue,
+                                                      IMG_UINT32 *pui32UpdateValue)
+{
+       /*
+               For HW operations the client is required to ensure the
+               operation has completed before freeing the sync as we
+               no way of dropping the refcount if we where to acquire it
+               here.
+
+               Take the lock to ensure the state that we're modifying below
+               will be consistent with itself.
+       */
+       OSLockAcquire(psSync->hLock);
+       _ServerSyncTakeOperation(psSync,
+                                                        bUpdate,
+                                                        pui32FenceValue,
+                                                        pui32UpdateValue);
+
+       /*
+               Note:
+
+               We might want to consider optimising the fences that we write for
+               HW operations but for now just clear it back to unknown
+       */
+       psSync->ui32LastSyncRequesterID = SYNC_REQUESTOR_UNKNOWN;
+
+       if (psSync->bSWOperation)
+       {
+#if defined(PDUMP)             
+               IMG_CHAR azTmp[256];
+               OSSNPrintf(azTmp,
+                                  sizeof(azTmp),
+                                  "Wait for HW ops and dummy update for SW ops (0x%p, FW VAddr = 0x%08x, value = 0x%08x)\n",
+                                  psSync,
+                                  SyncPrimGetFirmwareAddr(psSync->psSync),
+                                  *pui32FenceValue);
+               PDumpCommentKM(azTmp, 0);
+#endif
+
+               if (psSync->bSWOpStartedInCaptRange)
+               {
+                       /* Dump a POL for the previous HW operation */
+                       SyncPrimPDumpPol(psSync->psSync,
+                                                               psSync->ui32LastHWUpdate,
+                                                               0xffffffff,
+                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                               0);
+               }
+
+               /* Dump the expected value (i.e. the value after all the SW operations) */
+               SyncPrimPDumpValue(psSync->psSync, *pui32FenceValue);
+
+               /* Reset the state as we've just done a HW operation */
+               psSync->bSWOperation = IMG_FALSE;
+       }
+       OSLockRelease(psSync->hLock);
+
+       SYNC_UPDATES_PRINT("%s: sync: %p, fence: %d, value: %d", __FUNCTION__, psSync, *pui32FenceValue, *pui32UpdateValue);
+
+       return PVRSRV_OK;
+}
+
+IMG_BOOL ServerSyncFenceIsMet(SERVER_SYNC_PRIMITIVE *psSync,
+                                                          IMG_UINT32 ui32FenceValue)
+{
+       SYNC_UPDATES_PRINT("%s: sync: %p, value(%d) == fence(%d)?", __FUNCTION__, psSync, *psSync->psSync->pui32LinAddr, ui32FenceValue);
+       return (*psSync->psSync->pui32LinAddr == ui32FenceValue);
+}
+
+IMG_VOID
+ServerSyncCompleteOp(SERVER_SYNC_PRIMITIVE *psSync,
+                                        IMG_BOOL bDoUpdate,
+                                        IMG_UINT32 ui32UpdateValue)
+{
+       if (bDoUpdate)
+       {
+               SYNC_UPDATES_PRINT("%s: sync: %p (%d) = %d", __FUNCTION__, psSync, *psSync->psSync->pui32LinAddr, ui32UpdateValue);
+
+               *psSync->psSync->pui32LinAddr = ui32UpdateValue;
+       }
+
+       ServerSyncUnref(psSync);
+}
+
+IMG_UINT32 ServerSyncGetId(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       return psSync->ui32UID;
+}
+
+IMG_UINT32 ServerSyncGetFWAddr(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       return SyncPrimGetFirmwareAddr(psSync->psSync);
+}
+
+IMG_UINT32 ServerSyncGetValue(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       return *psSync->psSync->pui32LinAddr;
+}
+
+IMG_UINT32 ServerSyncGetNextValue(SERVER_SYNC_PRIMITIVE *psSync)
+{
+       return psSync->ui32NextOp;
+}
+
+static IMG_BOOL _ServerSyncState(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       SERVER_SYNC_PRIMITIVE *psSync = IMG_CONTAINER_OF(psNode, SERVER_SYNC_PRIMITIVE, sNode);
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = IMG_NULL;
+
+       pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;
+
+       if (*psSync->psSync->pui32LinAddr != psSync->ui32NextOp)
+       {
+#if !defined(SUPPORT_EXTRA_METASP_DEBUG)
+               PVR_DUMPDEBUG_LOG(("\tPending server sync (ID = %d, FWAddr = 0x%08x): Current = 0x%08x, NextOp = 0x%08x (%s)",
+                                  psSync->ui32UID,
+                                  ServerSyncGetFWAddr(psSync),
+                                  ServerSyncGetValue(psSync),
+                                  psSync->ui32NextOp,
+                                  psSync->szClassName));
+#else
+               PVR_DUMPDEBUG_LOG(("\tPending server sync (ID = %d, FWAddr = 0x%08x): Value (Host) = 0x%08x, Value (FW) = 0x%08x, NextOp = 0x%08x (%s)",
+                                  psSync->ui32UID,
+                                  ServerSyncGetFWAddr(psSync),
+                                  ServerSyncGetValue(psSync),
+                                  RGXReadWithSP(ServerSyncGetFWAddr(psSync)),
+                                  psSync->ui32NextOp,
+                                  psSync->szClassName));
+#endif
+       }
+       return IMG_TRUE;
+}
+
+static IMG_VOID _ServerSyncDebugRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel)
+{
+
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = IMG_NULL;
+
+       PVR_UNREFERENCED_PARAMETER(hDebugRequestHandle);
+       
+       pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;
+       if (ui32VerbLevel == DEBUG_REQUEST_VERBOSITY_HIGH)
+       {
+               PVR_DUMPDEBUG_LOG(("Dumping all pending server syncs"));
+               OSLockAcquire(g_hListLock);
+               dllist_foreach_node(&g_sAllServerSyncs, _ServerSyncState, IMG_NULL);
+               OSLockRelease(g_hListLock);
+       }
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpCreateKM(IMG_UINT32 ui32SyncBlockCount,
+                                                SYNC_PRIMITIVE_BLOCK **papsSyncPrimBlock,
+                                                IMG_UINT32 ui32ClientSyncCount,
+                                                IMG_UINT32 *paui32SyncBlockIndex,
+                                                IMG_UINT32 *paui32Index,
+                                                IMG_UINT32 ui32ServerSyncCount,
+                                                SERVER_SYNC_PRIMITIVE **papsServerSync,
+                                                SERVER_OP_COOKIE **ppsServerCookie)
+{
+       SERVER_OP_COOKIE *psNewCookie;
+       IMG_UINT32 ui32BlockAllocSize;
+       IMG_UINT32 ui32ServerAllocSize;
+       IMG_UINT32 ui32ClientAllocSize;
+       IMG_UINT32 ui32TotalAllocSize;
+       IMG_UINT32 i;
+       IMG_CHAR *pcPtr;
+       PVRSRV_ERROR eError;
+
+       /* Allocate space for all the sync block list */
+       ui32BlockAllocSize = ui32SyncBlockCount * (sizeof(SYNC_PRIMITIVE_BLOCK *));
+
+       /* Allocate space for all the client sync size elements */
+       ui32ClientAllocSize = ui32ClientSyncCount * (5 * sizeof(IMG_UINT32));
+
+       /* Allocate space for all the server sync size elements */
+       ui32ServerAllocSize = ui32ServerSyncCount * (sizeof(SERVER_SYNC_PRIMITIVE *)
+                                                       + (2 * sizeof(IMG_UINT32)));
+
+       ui32TotalAllocSize = sizeof(SERVER_OP_COOKIE) +
+                                                        ui32BlockAllocSize +
+                                                        ui32ServerAllocSize +
+                                                        ui32ClientAllocSize;
+
+       psNewCookie = OSAllocMem(ui32TotalAllocSize);
+       pcPtr = (IMG_CHAR *) psNewCookie;
+
+       if (!psNewCookie)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+       OSMemSet(psNewCookie, 0, ui32TotalAllocSize);
+
+       /* Setup the pointers */
+       pcPtr += sizeof(SERVER_OP_COOKIE);
+       psNewCookie->papsSyncPrimBlock = (SYNC_PRIMITIVE_BLOCK **) pcPtr;
+
+       pcPtr += sizeof(SYNC_PRIMITIVE_BLOCK *) * ui32SyncBlockCount;
+       psNewCookie->paui32SyncBlockIndex = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32Index = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32Flags = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32FenceValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32UpdateValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->papsServerSync =(SERVER_SYNC_PRIMITIVE **) pcPtr;
+
+       pcPtr += sizeof(SERVER_SYNC_PRIMITIVE *) * ui32ServerSyncCount;
+       psNewCookie->paui32ServerFenceValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;
+       psNewCookie->paui32ServerUpdateValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;
+
+       /* Check the pointer setup went ok */
+       PVR_ASSERT(pcPtr == (((IMG_CHAR *) psNewCookie) + ui32TotalAllocSize));
+
+       psNewCookie->ui32SyncBlockCount= ui32SyncBlockCount;
+       psNewCookie->ui32ServerSyncCount = ui32ServerSyncCount;
+       psNewCookie->ui32ClientSyncCount = ui32ClientSyncCount;
+       psNewCookie->bActive = IMG_FALSE;
+
+       /* Copy all the data into our server cookie */
+       OSMemCopy(psNewCookie->papsSyncPrimBlock,
+                         papsSyncPrimBlock,
+                         sizeof(SYNC_PRIMITIVE_BLOCK *) * ui32SyncBlockCount);
+
+       OSMemCopy(psNewCookie->paui32SyncBlockIndex,
+                         paui32SyncBlockIndex,
+                         sizeof(IMG_UINT32) * ui32ClientSyncCount);
+       OSMemCopy(psNewCookie->paui32Index,
+                         paui32Index,
+                         sizeof(IMG_UINT32) * ui32ClientSyncCount);
+
+       OSMemCopy(psNewCookie->papsServerSync,
+                         papsServerSync,
+                         sizeof(SERVER_SYNC_PRIMITIVE *) *ui32ServerSyncCount);
+
+       /*
+               Take a reference on all the sync blocks and server syncs so they can't
+               be freed while we're using them
+       */
+       for (i=0;i<ui32SyncBlockCount;i++)
+       {
+               _SyncPrimitiveBlockRef(psNewCookie->papsSyncPrimBlock[i]);
+       }
+
+       for (i=0;i<ui32ServerSyncCount;i++)
+       {
+               ServerSyncRef(psNewCookie->papsServerSync[i]);
+       }
+
+       *ppsServerCookie = psNewCookie;
+       return PVRSRV_OK;
+
+e0:
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpTakeKM(SERVER_OP_COOKIE *psServerCookie,
+                                              IMG_UINT32 ui32ClientSyncCount,
+                                              IMG_UINT32 *paui32Flags,
+                                              IMG_UINT32 *paui32FenceValue,
+                                              IMG_UINT32 *paui32UpdateValue,
+                                              IMG_UINT32 ui32ServerSyncCount,
+                                                  IMG_UINT32 *paui32ServerFlags)
+{
+       IMG_UINT32 i;
+
+       if ((ui32ClientSyncCount != psServerCookie->ui32ClientSyncCount) ||
+               (ui32ServerSyncCount != psServerCookie->ui32ServerSyncCount))
+       {
+               /* The bridge layer should have stopped us getting here but check incase */
+               PVR_DPF((PVR_DBG_ERROR, "%s: Invalid sync counts", __FUNCTION__));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       for (i=0;i<ui32ServerSyncCount;i++)
+       {
+               /* Server syncs must fence */
+               if ((paui32ServerFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK) == 0)
+               {
+                       return PVRSRV_ERROR_INVALID_SYNC_PRIM_OP;
+               }
+       }
+
+       /*
+               For client syncs all we need to do is save the values
+               that we've been passed
+       */
+       OSMemCopy(psServerCookie->paui32Flags,
+                         paui32Flags,
+                         sizeof(IMG_UINT32) * ui32ClientSyncCount);
+       OSMemCopy(psServerCookie->paui32FenceValue,
+                         paui32FenceValue,
+                         sizeof(IMG_UINT32) * ui32ClientSyncCount);
+       OSMemCopy(psServerCookie->paui32UpdateValue,
+                         paui32UpdateValue,
+                         sizeof(IMG_UINT32) * ui32ClientSyncCount);
+
+       /*
+               For server syncs we just take an operation
+       */
+       for (i=0;i<ui32ServerSyncCount;i++)
+       {
+               /*
+                       Take op can only take one operation at a time so we can't
+                       optimise away fences so just report the requestor as unknown
+               */
+               PVRSRVServerSyncQueueSWOpKM(psServerCookie->papsServerSync[i],
+                                                                 &psServerCookie->paui32ServerFenceValue[i],
+                                                                 &psServerCookie->paui32ServerUpdateValue[i],
+                                                                 SYNC_REQUESTOR_UNKNOWN,
+                                                                 (paui32ServerFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE) ? IMG_TRUE:IMG_FALSE,
+                                                                 IMG_NULL);
+       }
+
+       psServerCookie->bActive = IMG_TRUE;
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpReadyKM(SERVER_OP_COOKIE *psServerCookie,
+                                               IMG_BOOL *pbReady)
+{
+       IMG_UINT32 i;
+       IMG_BOOL bReady = IMG_TRUE;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if (!psServerCookie->bActive)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Operation cookie not active (no take operation performed)", __FUNCTION__));
+
+               bReady = IMG_FALSE;
+               eError = PVRSRV_ERROR_BAD_SYNC_STATE;
+               goto e0;
+       }
+
+       /* Check the client syncs */
+       for (i=0;i<psServerCookie->ui32ClientSyncCount;i++)
+       {
+               if (psServerCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK)
+               {
+                       IMG_UINT32 ui32BlockIndex = psServerCookie->paui32SyncBlockIndex[i];
+                       IMG_UINT32 ui32Index = psServerCookie->paui32Index[i];
+                       SYNC_PRIMITIVE_BLOCK *psSyncBlock = psServerCookie->papsSyncPrimBlock[ui32BlockIndex];
+
+                       if (psSyncBlock->pui32LinAddr[ui32Index] !=
+                                       psServerCookie->paui32FenceValue[i])
+                       {
+                               bReady = IMG_FALSE;
+                               goto e0;
+                       }
+               }
+       }
+
+       for (i=0;i<psServerCookie->ui32ServerSyncCount;i++)
+       {
+               bReady = ServerSyncFenceIsMet(psServerCookie->papsServerSync[i],
+                                                                         psServerCookie->paui32ServerFenceValue[i]);
+               if (!bReady)
+               {
+                       break;
+               }
+       }
+
+e0:
+       *pbReady = bReady;
+       return eError;
+}
+
+static
+PVRSRV_ERROR _SyncPrimOpComplete(SERVER_OP_COOKIE *psServerCookie)
+{
+       IMG_UINT32 i;
+
+       for (i=0;i<psServerCookie->ui32ClientSyncCount;i++)
+       {
+               if (psServerCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
+               {
+                       IMG_UINT32 ui32BlockIndex = psServerCookie->paui32SyncBlockIndex[i];
+                       IMG_UINT32 ui32Index = psServerCookie->paui32Index[i];
+                       SYNC_PRIMITIVE_BLOCK *psSyncBlock = psServerCookie->papsSyncPrimBlock[ui32BlockIndex];
+
+                       psSyncBlock->pui32LinAddr[ui32Index] = psServerCookie->paui32UpdateValue[i];
+               }
+       }
+
+       for (i=0;i<psServerCookie->ui32ServerSyncCount;i++)
+       {
+               ServerSyncCompleteOp(psServerCookie->papsServerSync[i],
+                                                        (psServerCookie->paui32ServerFenceValue[i] != psServerCookie->paui32ServerUpdateValue[i]),
+                                                        psServerCookie->paui32ServerUpdateValue[i]);
+       }
+
+       psServerCookie->bActive = IMG_FALSE;
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpCompleteKM(SERVER_OP_COOKIE *psServerCookie)
+{
+       IMG_BOOL bReady;
+
+       PVRSRVSyncPrimOpReadyKM(psServerCookie, &bReady);
+
+       /* Check the client is playing ball */
+       if (!bReady)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: sync op still not ready", __FUNCTION__));
+
+               return PVRSRV_ERROR_BAD_SYNC_STATE;
+       }
+
+       return _SyncPrimOpComplete(psServerCookie);
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpDestroyKM(SERVER_OP_COOKIE *psServerCookie)
+{
+       IMG_UINT32 i;
+
+       /* If the operation is still active then check if it's finished yet */
+       if (psServerCookie->bActive)
+       {
+               if (PVRSRVSyncPrimOpCompleteKM(psServerCookie) == PVRSRV_ERROR_BAD_SYNC_STATE)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Not ready, ask for retry", __FUNCTION__));
+                       return PVRSRV_ERROR_RETRY;
+               }
+       }
+
+       /* Drop our references on the sync blocks and server syncs*/
+       for (i = 0; i < psServerCookie->ui32SyncBlockCount; i++)
+       {
+               _SyncPrimitiveBlockUnref(psServerCookie->papsSyncPrimBlock[i]);
+       }
+
+       for (i = 0; i < psServerCookie->ui32ServerSyncCount; i++)
+       {
+               ServerSyncUnref(psServerCookie->papsServerSync[i]);
+       }
+
+       OSFreeMem(psServerCookie);
+       return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+       /*
+               We might be ask to PDump sync state outside of capture range
+               (e.g. texture uploads) so make this continuous.
+       */
+       DevmemPDumpLoadMemValue32(psSyncBlk->psMemDesc,
+                                          ui32Offset,
+                                          ui32Value,
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset)
+{
+       /*
+               We might be ask to PDump sync state outside of capture range
+               (e.g. texture uploads) so make this continuous.
+       */
+       DevmemPDumpLoadMem(psSyncBlk->psMemDesc,
+                                          ui32Offset,
+                                          sizeof(IMG_UINT32),
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset,
+                                                IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T ui32PDumpFlags)
+{
+       DevmemPDumpDevmemPol32(psSyncBlk->psMemDesc,
+                                                  ui32Offset,
+                                                  ui32Value,
+                                                  ui32Mask,
+                                                  eOperator,
+                                                  ui32PDumpFlags);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpPDumpPolKM(SERVER_OP_COOKIE *psServerCookie,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T ui32PDumpFlags)
+{
+       IMG_UINT32 i;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if (!psServerCookie->bActive)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Operation cookie not active (no take operation performed)", __FUNCTION__));
+
+               eError = PVRSRV_ERROR_BAD_SYNC_STATE;
+               goto e0;
+       }
+
+       /* PDump POL on the client syncs */
+       for (i = 0; i < psServerCookie->ui32ClientSyncCount; i++)
+       {
+               if (psServerCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK)
+               {
+                       IMG_UINT32 ui32BlockIndex = psServerCookie->paui32SyncBlockIndex[i];
+                       IMG_UINT32 ui32Index = psServerCookie->paui32Index[i];
+                       SYNC_PRIMITIVE_BLOCK *psSyncBlock = psServerCookie->papsSyncPrimBlock[ui32BlockIndex];
+
+                       PVRSRVSyncPrimPDumpPolKM(psSyncBlock,
+                                                                       ui32Index*sizeof(IMG_UINT32),
+                                                                       psServerCookie->paui32FenceValue[i],
+                                                                       0xFFFFFFFFU,
+                                                                       eOperator,
+                                                                       ui32PDumpFlags);
+               }
+       }
+
+       /* PDump POL on the server syncs */
+       for (i = 0; i < psServerCookie->ui32ServerSyncCount; i++)
+       {
+               SERVER_SYNC_PRIMITIVE *psServerSync = psServerCookie->papsServerSync[i];
+               IMG_UINT32 ui32FenceValue = psServerCookie->paui32ServerFenceValue[i];
+
+               SyncPrimPDumpPol(psServerSync->psSync,
+                                               ui32FenceValue,
+                                               0xFFFFFFFFU,
+                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                               ui32PDumpFlags);
+       }
+
+e0:
+       return eError;
+}
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset,
+                                                IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize,
+                                                IMG_UINT64 uiBufferSize)
+{
+       DevmemPDumpCBP(psSyncBlk->psMemDesc,
+                                  ui32Offset,
+                                  uiWriteOffset,
+                                  uiPacketSize,
+                                  uiBufferSize);
+       return PVRSRV_OK;
+}
+#endif
+
+/* SyncRegisterConnection */
+PVRSRV_ERROR SyncRegisterConnection(SYNC_CONNECTION_DATA **ppsSyncConnectionData)
+{
+       SYNC_CONNECTION_DATA *psSyncConnectionData;
+       PVRSRV_ERROR eError;
+
+       psSyncConnectionData = OSAllocMem(sizeof(SYNC_CONNECTION_DATA));
+       if (psSyncConnectionData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       eError = OSLockCreate(&psSyncConnectionData->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_lockcreate;
+       }
+       dllist_init(&psSyncConnectionData->sListHead);
+       psSyncConnectionData->ui32RefCount = 1;
+
+       *ppsSyncConnectionData = psSyncConnectionData;
+       return PVRSRV_OK;
+
+fail_lockcreate:
+       OSFreeMem(psSyncConnectionData);
+fail_alloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/* SyncUnregisterConnection */
+IMG_VOID SyncUnregisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData)
+{
+       _SyncConnectionUnref(psSyncConnectionData);
+}
+
+static
+IMG_BOOL _PDumpSyncBlock(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       SYNC_PRIMITIVE_BLOCK *psSyncBlock = IMG_CONTAINER_OF(psNode, SYNC_PRIMITIVE_BLOCK, sConnectionNode);
+       PVR_UNREFERENCED_PARAMETER(pvCallbackData);
+
+       DevmemPDumpLoadMem(psSyncBlock->psMemDesc,
+                                          0,
+                                          psSyncBlock->ui32BlockSize,
+                                          PDUMP_FLAGS_CONTINUOUS);
+       return IMG_TRUE;
+}
+
+IMG_VOID SyncConnectionPDumpSyncBlocks(SYNC_CONNECTION_DATA *psSyncConnectionData)
+{
+       OSLockAcquire(psSyncConnectionData->hLock);
+
+       PDUMPCOMMENT("Dump client Sync Prim state");
+       dllist_foreach_node(&psSyncConnectionData->sListHead,
+                                               _PDumpSyncBlock,
+                                               IMG_NULL);
+
+       OSLockRelease(psSyncConnectionData->hLock);
+}
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+struct SYNC_LOOKUP
+{
+       IMG_UINT32 ui32FwAddr;
+       IMG_CHAR * pszSyncInfo;
+       IMG_SIZE_T len;
+};
+
+static IMG_BOOL _SyncRecordLookup(
+       struct SYNC_RECORD * psSyncRec,
+       IMG_UINT32 ui32FwAddr,
+       IMG_CHAR * pszSyncInfo,
+       IMG_SIZE_T len
+)
+{
+       if ((psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset) == ui32FwAddr
+               && SYNC_RECORD_TYPE_UNKNOWN != psSyncRec->eRecordType
+               && psSyncRec->psServerSyncPrimBlock
+               && psSyncRec->psServerSyncPrimBlock->pui32LinAddr
+               )
+       {
+               IMG_INT iEnd;
+               IMG_UINT32 *pui32SyncAddr;
+               pui32SyncAddr = psSyncRec->psServerSyncPrimBlock->pui32LinAddr
+                       + (psSyncRec->ui32SyncOffset/sizeof(IMG_UINT32));
+               iEnd = OSSNPrintf(pszSyncInfo, len, "Cur=0x%08x %s:%05u (%s)",
+                       *pui32SyncAddr,
+                       ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"),
+                       psSyncRec->uiPID,
+                       psSyncRec->szClassName
+                       );
+               if (iEnd >= 0 && iEnd < len)
+               {
+                       pszSyncInfo[iEnd] = '\0';
+               }
+               return IMG_FALSE;
+       }
+       return IMG_TRUE;
+}
+
+static IMG_BOOL _SyncRecordNodeLookup(PDLLIST_NODE psNode, IMG_VOID *pvCallbackData)
+{
+       struct SYNC_RECORD *psSyncRec;
+       struct SYNC_LOOKUP *psLookup = (struct SYNC_LOOKUP*)pvCallbackData;
+       psSyncRec = IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode);
+       return _SyncRecordLookup(psSyncRec, psLookup->ui32FwAddr, psLookup->pszSyncInfo, psLookup->len);
+}
+
+IMG_VOID SyncRecordLookup(
+       IMG_UINT32 ui32FwAddr,
+       IMG_CHAR * pszSyncInfo,
+       IMG_SIZE_T len
+)
+{
+       struct SYNC_LOOKUP sLookup = {ui32FwAddr, pszSyncInfo, len};
+
+       if (!pszSyncInfo)
+       {
+               return;
+       }
+
+       OSLockAcquire(g_hSyncRecordListLock);
+
+       pszSyncInfo[0] = '\0';
+       dllist_foreach_node(&g_sSyncRecordList, _SyncRecordNodeLookup, &sLookup);
+
+       OSLockRelease(g_hSyncRecordListLock);
+}
+
+#define NS_IN_S (1000000000UL)
+static IMG_VOID _SyncRecordPrint(struct SYNC_RECORD * psSyncRec, IMG_UINT64 ui64TimeNow)
+{
+       SYNC_PRIMITIVE_BLOCK *psSyncBlock = psSyncRec->psServerSyncPrimBlock;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;
+
+       if (SYNC_RECORD_TYPE_UNKNOWN != psSyncRec->eRecordType)
+       {
+               IMG_UINT64 ui64DeltaS;
+               IMG_UINT32 ui32DeltaF;
+               IMG_UINT64 ui64Delta = ui64TimeNow - psSyncRec->ui64OSTime;
+               ui64DeltaS = OSDivide64(ui64Delta, NS_IN_S, &ui32DeltaF);
+
+               if (psSyncBlock && psSyncBlock->pui32LinAddr)
+               {
+                       IMG_UINT32 *pui32SyncAddr;
+                       pui32SyncAddr = psSyncBlock->pui32LinAddr
+                               + (psSyncRec->ui32SyncOffset/sizeof(IMG_UINT32));
+
+                       PVR_DUMPDEBUG_LOG(("\t%s %05u %05llu.%09u FWAddr=0x%08x Val=0x%08x (%s)",
+                               ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"),
+                               psSyncRec->uiPID,
+                               ui64DeltaS, ui32DeltaF,
+                               (psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset),
+                               *pui32SyncAddr,
+                               psSyncRec->szClassName
+                               ));
+               }
+               else
+               {
+                       PVR_DUMPDEBUG_LOG(("\t%s %05u %05llu.%09u FWAddr=0x%08x Val=<null_ptr> (%s)",
+                               ((SYNC_RECORD_TYPE_SERVER==psSyncRec->eRecordType)?"Server":"Client"),
+                               psSyncRec->uiPID,
+                               ui64DeltaS, ui32DeltaF,
+                               (psSyncRec->ui32FwBlockAddr+psSyncRec->ui32SyncOffset),
+                               psSyncRec->szClassName
+                               ));
+               }
+       }
+}
+
+static IMG_BOOL _SyncRecordNodePrint(PDLLIST_NODE psNode, IMG_VOID *pvCallbackData)
+{
+       struct SYNC_RECORD *psSyncRec;
+       psSyncRec = IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode);
+       _SyncRecordPrint(psSyncRec, *((IMG_UINT64*)pvCallbackData));
+       return IMG_TRUE;
+}
+
+static IMG_VOID _SyncRecordRequest(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel)
+{
+       IMG_UINT64 ui64TimeNowS;
+       IMG_UINT32 ui32TimeNowF;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = g_pfnDumpDebugPrintf;
+       IMG_UINT64 ui64TimeNow = OSClockns64();
+       ui64TimeNowS = OSDivide64(ui64TimeNow, NS_IN_S, &ui32TimeNowF);
+
+       PVR_UNREFERENCED_PARAMETER(hDebugRequestHandle);
+
+       if (ui32VerbLevel == DEBUG_REQUEST_VERBOSITY_HIGH)
+       {
+               IMG_UINT i;
+               OSLockAcquire(g_hSyncRecordListLock);
+
+               PVR_DUMPDEBUG_LOG(("Dumping all allocated syncs @ %05llu.%09u", ui64TimeNowS, ui32TimeNowF));
+               PVR_DUMPDEBUG_LOG(("\t%-6s %-5s %-15s %-17s %-14s (%s)",
+                                       "Type", "PID", "Time Delta (s)", "Address", "Value", "Annotation"));
+               dllist_foreach_node(&g_sSyncRecordList, _SyncRecordNodePrint, &ui64TimeNow);
+
+               PVR_DUMPDEBUG_LOG(("Dumping all recently freed syncs @ %05llu.%09u", ui64TimeNowS, ui32TimeNowF));
+               PVR_DUMPDEBUG_LOG(("\t%-6s %-5s %-15s %-17s %-14s (%s)",
+                                       "Type", "PID", "Time Delta (s)", "Address", "Value", "Annotation"));
+               for(i = DECREMENT_WITH_WRAP(g_uiFreedSyncRecordIdx, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN);
+                               i != g_uiFreedSyncRecordIdx;
+                               i = DECREMENT_WITH_WRAP(i, PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN))
+               {
+                       if (g_apsFreedSyncRecords[i])
+                       {
+                               _SyncRecordPrint(g_apsFreedSyncRecords[i], ui64TimeNow);
+                       }
+                       else
+                       {
+                               break;
+                       }
+               }
+
+               OSLockRelease(g_hSyncRecordListLock);
+       }
+}
+#undef NS_IN_S
+
+static PVRSRV_ERROR SyncRecordListInit(IMG_VOID)
+{
+       PVRSRV_ERROR eError;
+
+       eError = OSLockCreate(&g_hSyncRecordListLock, LOCK_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_lock_create;
+       }
+       dllist_init(&g_sSyncRecordList);
+
+       eError = PVRSRVRegisterDbgRequestNotify(&g_hSyncRecordNotify,
+                                                                                       _SyncRecordRequest,
+                                                                                       DEBUG_REQUEST_SERVERSYNC,
+                                                                                       IMG_NULL);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_dbg_register;
+       }
+
+       return PVRSRV_OK;
+
+fail_dbg_register:
+       OSLockDestroy(g_hSyncRecordListLock);;
+fail_lock_create:
+       return eError;
+}
+
+static IMG_BOOL _SyncRecordListDestroy(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       struct SYNC_RECORD *pSyncRec;
+
+       PVR_UNREFERENCED_PARAMETER(pvCallbackData);
+
+       pSyncRec = IMG_CONTAINER_OF(psNode, struct SYNC_RECORD, sNode);
+
+       dllist_remove_node(psNode);
+       OSFreeMem(pSyncRec);
+
+       return IMG_TRUE;
+}
+#endif /* #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
+
+PVRSRV_ERROR ServerSyncInit(IMG_VOID)
+{
+       PVRSRV_ERROR eError;
+
+       eError = OSLockCreate(&g_hListLock, LOCK_TYPE_NONE);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_lock_create;
+       }
+       dllist_init(&g_sAllServerSyncs);
+
+       eError = PVRSRVRegisterDbgRequestNotify(&g_hNotify,
+                                                                                       _ServerSyncDebugRequest,
+                                                                                       DEBUG_REQUEST_SERVERSYNC,
+                                                                                       IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_dbg_register;
+       }
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+       eError = SyncRecordListInit();
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_record_list;
+       }
+#endif
+
+       return PVRSRV_OK;
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+fail_record_list:
+       PVRSRVUnregisterDbgRequestNotify(g_hNotify);
+#endif
+fail_dbg_register:
+       OSLockDestroy(g_hListLock);;
+fail_lock_create:
+       return eError;
+}
+
+IMG_VOID ServerSyncDeinit(IMG_VOID)
+{
+       PVRSRVUnregisterDbgRequestNotify(g_hNotify);
+       OSLockDestroy(g_hListLock);
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+       {
+               IMG_INT i;
+               OSLockAcquire(g_hSyncRecordListLock);
+               dllist_foreach_node(&g_sSyncRecordList, _SyncRecordListDestroy, NULL);
+               for (i=0; i < PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN; i++)
+               {
+                       if (g_apsFreedSyncRecords[i])
+                       {
+                               OSFreeMem(g_apsFreedSyncRecords[i]);
+                               g_apsFreedSyncRecords[i] = NULL;
+                       }
+               }
+               OSLockRelease(g_hSyncRecordListLock);
+               PVRSRVUnregisterDbgRequestNotify(g_hSyncRecordNotify);
+               OSLockDestroy(g_hSyncRecordListLock);
+       }
+#endif
+}
diff --git a/drivers/gpu/rogue_m/services/server/common/tlintern.c b/drivers/gpu/rogue_m/services/server/common/tlintern.c
new file mode 100644 (file)
index 0000000..5c985e8
--- /dev/null
@@ -0,0 +1,329 @@
+/*************************************************************************/ /*!
+@File
+@Title          Transport Layer kernel side API implementation.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport Layer functions available to driver components in 
+                the driver.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+//#define PVR_DPF_FUNCTION_TRACE_ON 1
+#undef PVR_DPF_FUNCTION_TRACE_ON
+#include "pvr_debug.h"
+
+#include "allocmem.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+
+#include "pvr_tlcommon.h"
+#include "tlintern.h"
+
+/*
+ * Make functions
+ */
+PTL_STREAM_DESC
+TLMakeStreamDesc(PTL_SNODE f1, IMG_UINT32 f2, IMG_HANDLE f3)
+{
+       PTL_STREAM_DESC ps = OSAllocZMem(sizeof(TL_STREAM_DESC));
+       if (ps == IMG_NULL) 
+       {
+               return IMG_NULL;
+       }
+       ps->psNode = f1;
+       ps->ui32Flags = f2;
+       ps->hDataEvent = f3;
+       return ps;
+}
+
+PTL_SNODE
+TLMakeSNode(IMG_HANDLE f2, TL_STREAM *f3, TL_STREAM_DESC *f4)
+{
+       PTL_SNODE ps = OSAllocZMem(sizeof(TL_SNODE));
+       if (ps == IMG_NULL)
+       {
+               return IMG_NULL;
+       }
+       ps->hDataEventObj = f2;
+       ps->psStream = f3;
+       ps->psRDesc = f4;
+       f3->psNode = ps;
+       return ps;
+}
+
+/*
+ * Transport Layer Global top variables and functions
+ */
+static TL_GLOBAL_DATA  sTLGlobalData = { 0 };
+
+TL_GLOBAL_DATA *TLGGD(IMG_VOID)        // TLGetGlobalData()
+{
+       return &sTLGlobalData;
+}
+
+/* TLInit must only be called once at driver initialisation for one device.
+ * An assert is provided to check this condition on debug builds.
+ */
+PVRSRV_ERROR
+TLInit(PVRSRV_DEVICE_NODE *psDevNode)
+{
+       PVRSRV_ERROR eError;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDevNode);
+       PVR_ASSERT(sTLGlobalData.psRgxDevNode==0);
+
+       /* Store the RGX device node for later use in devmem buffer allocations */
+       sTLGlobalData.psRgxDevNode = (IMG_VOID*)psDevNode;
+
+       /* Allocate a lock for TL global data, to be used while updating the TL data.
+        * This is for making TL global data muti-thread safe */
+       eError = OSLockCreate (&sTLGlobalData.hTLGDLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+       
+       /* Allocate the event object used to signal global TL events such as
+        * new stream created */
+       eError = OSEventObjectCreate("TLGlobalEventObj", &sTLGlobalData.hTLEventObj);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+       
+       PVR_DPF_RETURN_OK;
+
+/* Don't allow the driver to start up on error */
+e1:
+       OSLockDestroy (sTLGlobalData.hTLGDLock);
+       sTLGlobalData.hTLGDLock = NULL;
+e0:
+       PVR_DPF_RETURN_RC (eError);
+}
+
+static IMG_VOID RemoveAndFreeStreamNode(PTL_SNODE psRemove)
+{
+       TL_GLOBAL_DATA*  psGD = TLGGD();
+       PTL_SNODE*               last;
+       PTL_SNODE                psn;
+       PVRSRV_ERROR     eError;
+
+       PVR_DPF_ENTERED;
+
+       // Unlink the stream node from the master list
+       PVR_ASSERT(psGD->psHead);
+       last = &psGD->psHead;
+       for (psn = psGD->psHead; psn; psn=psn->psNext)
+       {
+               if (psn == psRemove)
+               {
+                       /* Other calling code may have freed and zero'd the pointers */
+                       if (psn->psRDesc)
+                       {
+                               OSFREEMEM(psn->psRDesc);
+                       }
+                       if (psn->psStream)
+                       {
+                               OSFREEMEM(psn->psStream);
+                       }
+                       *last = psn->psNext;
+                       break;
+               }
+               last = &psn->psNext;
+       }
+
+       // Release the event list object owned by the stream node
+       if (psRemove->hDataEventObj)
+       {
+               eError = OSEventObjectDestroy(psRemove->hDataEventObj);
+               PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+
+               psRemove->hDataEventObj = NULL;
+       }
+
+       // Release the memory of the stream node
+       OSFREEMEM(psRemove);
+
+       PVR_DPF_RETURN;
+}
+
+IMG_VOID
+TLDeInit(IMG_VOID)
+{
+       PVR_DPF_ENTERED;
+
+       if (sTLGlobalData.uiClientCnt)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLDeInit transport layer but %d client streams are still connected", sTLGlobalData.uiClientCnt));
+               sTLGlobalData.uiClientCnt = 0;
+       }
+
+       /* Clean up the SNODE list */
+       if (sTLGlobalData.psHead)
+       {
+               while (sTLGlobalData.psHead)
+               {
+                       RemoveAndFreeStreamNode(sTLGlobalData.psHead);
+               }
+               /* Leave psHead NULL on loop exit */
+       }
+
+       /* Clean up the TL global event object */
+       if (sTLGlobalData.hTLEventObj)
+       {
+               OSEventObjectDestroy(sTLGlobalData.hTLEventObj);
+               sTLGlobalData.hTLEventObj = NULL;
+       }
+
+       /* Destroy the TL global data lock */
+       if (sTLGlobalData.hTLGDLock)
+       {
+               OSLockDestroy (sTLGlobalData.hTLGDLock);
+               sTLGlobalData.hTLGDLock = NULL;
+       }
+
+       sTLGlobalData.psRgxDevNode = NULL;
+
+       PVR_DPF_RETURN;
+}
+
+PVRSRV_DEVICE_NODE*
+TLGetGlobalRgxDevice(IMG_VOID)
+{
+       PVRSRV_DEVICE_NODE *p = (PVRSRV_DEVICE_NODE*)(TLGGD()->psRgxDevNode);
+       if (!p)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLGetGlobalRgxDevice() NULL node ptr, TL " \
+                               "can not be used when no RGX device has been found"));
+               PVR_ASSERT(p);
+       }
+       return p;
+}
+
+IMG_VOID TLAddStreamNode(PTL_SNODE psAdd)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psAdd);
+       psAdd->psNext = TLGGD()->psHead;
+       TLGGD()->psHead = psAdd;
+       
+       PVR_DPF_RETURN;
+}
+
+PTL_SNODE TLFindStreamNodeByName(IMG_PCHAR pszName)
+{
+       TL_GLOBAL_DATA*  psGD = TLGGD();
+       PTL_SNODE                psn;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(pszName);
+
+       for (psn = psGD->psHead; psn; psn=psn->psNext)
+       {
+               if (psn->psStream && OSStringCompare(psn->psStream->szName, pszName)==0)
+               {
+                       PVR_DPF_RETURN_VAL(psn);
+               }
+       }
+
+       PVR_DPF_RETURN_VAL(IMG_NULL);
+}
+
+PTL_SNODE TLFindStreamNodeByDesc(PTL_STREAM_DESC psRDesc)
+{
+       TL_GLOBAL_DATA*  psGD = TLGGD();
+       PTL_SNODE                psn;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psRDesc);
+
+       for (psn = psGD->psHead; psn; psn=psn->psNext)
+       {
+               if (psn->psRDesc == psRDesc)
+               {
+                       PVR_DPF_RETURN_VAL(psn);
+               }
+       }
+       PVR_DPF_RETURN_VAL(IMG_NULL);
+}
+
+IMG_BOOL TLTryRemoveStreamAndFreeStreamNode(PTL_SNODE psRemove)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psRemove);
+
+       /* If there is a client connected to this stream, defer stream's deletion */
+       if (psRemove->psRDesc != IMG_NULL)
+       {
+               PVR_DPF_RETURN_VAL (IMG_FALSE);
+       }
+
+       /* Remove stream from TL_GLOBAL_DATA's list and free stream node */     
+       psRemove->psStream = IMG_NULL;
+       RemoveAndFreeStreamNode(psRemove);
+
+       PVR_DPF_RETURN_VAL (IMG_TRUE);
+}
+
+IMG_BOOL TLRemoveDescAndTryFreeStreamNode(PTL_SNODE psRemove)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psRemove);
+
+       /* Remove stream descriptor (i.e. stream reader context) */
+       psRemove->psRDesc = IMG_NULL;
+
+       /* Do not Free Stream Node if there is a write reference (a producer context) to the stream */
+       if (0 != psRemove->uiWRefCount)
+       {
+               PVR_DPF_RETURN_VAL (IMG_FALSE);
+       }
+
+       /* Make stream pointer NULL to prevent it from being destroyed in RemoveAndFreeStreamNode
+        * Cleanup of stream should be done by the calling context */
+       psRemove->psStream = IMG_NULL;
+       RemoveAndFreeStreamNode(psRemove);
+       
+       PVR_DPF_RETURN_VAL (IMG_TRUE);
+}
+
diff --git a/drivers/gpu/rogue_m/services/server/common/tlserver.c b/drivers/gpu/rogue_m/services/server/common/tlserver.c
new file mode 100644 (file)
index 0000000..9772e3e
--- /dev/null
@@ -0,0 +1,389 @@
+/*************************************************************************/ /*!
+@File
+@Title          KM server Transport Layer implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main bridge APIs for Transport Layer client functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <stddef.h>
+
+#include "img_defs.h"
+
+//#define PVR_DPF_FUNCTION_TRACE_ON 1
+#undef PVR_DPF_FUNCTION_TRACE_ON
+#include "pvr_debug.h"
+
+#include "connection_server.h"
+#include "allocmem.h"
+
+#include "tlintern.h"
+#include "tlserver.h"
+
+#define NO_STREAM_WAIT_PERIOD 2000
+#define NO_DATA_WAIT_PERIOD   1000
+#define NO_ACQUIRE            0xffffffffU
+
+/*
+ * Transport Layer Client API Kernel-Mode bridge implementation
+ */
+PVRSRV_ERROR
+TLServerConnectKM(CONNECTION_DATA *psConnection)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+       PVR_DPF_RETURN_OK;
+}
+
+PVRSRV_ERROR
+TLServerDisconnectKM(CONNECTION_DATA *psConnection)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+
+       PVR_DPF_RETURN_OK;
+}
+
+PVRSRV_ERROR
+TLServerOpenStreamKM(IMG_PCHAR                    pszName,
+                                    IMG_UINT32                    ui32Mode,
+                                    PTL_STREAM_DESC*      ppsSD,
+                                    DEVMEM_EXPORTCOOKIE** ppsBufCookie)
+{
+       PVRSRV_ERROR    eError = PVRSRV_OK;
+       PVRSRV_ERROR    eErrorEO = PVRSRV_OK;
+       PTL_SNODE               psNode = 0;
+       TL_STREAM_DESC* psNewSD = 0;
+       IMG_HANDLE              hEvent;
+       PTL_GLOBAL_DATA psGD = TLGGD();
+
+#if defined(PVR_DPF_FUNCTION_TRACE_ON)
+    PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered (%s, %x)", __func__, __LINE__, pszName, ui32Mode));
+#endif
+
+       PVR_ASSERT(pszName);
+
+       /* Acquire TL_GLOBAL_DATA lock here, as if the following TLFindStreamNodeByName
+        * returns NON NULL PTL_SNODE, we try updating the global data client count and 
+        * PTL_SNODE's psRDesc and we want to make sure the TL_SNODE is valid (eg. has 
+        * not been deleted) while we are updating it
+        */
+       OSLockAcquire (psGD->hTLGDLock);
+
+       psNode = TLFindStreamNodeByName(pszName);
+       if ((psNode == NULL) && (ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WAIT))
+       {       /* Blocking code to wait for stream to be created if it does not exist */
+               eError = OSEventObjectOpen(psGD->hTLEventObj, &hEvent);
+               PVR_LOGG_IF_ERROR (eError, "OSEventObjectOpen", e0);
+
+               do
+               {
+                       if ((psNode = TLFindStreamNodeByName(pszName)) == NULL)
+                       {
+                               PVR_DPF((PVR_DBG_MESSAGE, "Stream %s does not exist, waiting...", pszName));
+                               
+                               /* Release TL_GLOBAL_DATA lock before sleeping */
+                               OSLockRelease (psGD->hTLGDLock);
+
+                               /* Will exit OK or with timeout, both cases safe to ignore */
+                               eErrorEO = OSEventObjectWaitTimeout(hEvent, NO_STREAM_WAIT_PERIOD);
+                               
+                               /* Acquire lock after waking up */
+                               OSLockAcquire (psGD->hTLGDLock);
+                       }
+               }
+               while ((psNode == NULL) && (eErrorEO == PVRSRV_OK));
+
+               eError = OSEventObjectClose(hEvent);
+               PVR_LOGG_IF_ERROR (eError, "OSEventObjectClose", e0);
+       }
+
+       /* Make sure we have found a stream node after wait/search */
+       if (psNode == NULL)
+       {
+               /* Did we exit the wait with timeout, inform caller */
+               if (eErrorEO == PVRSRV_ERROR_TIMEOUT)
+               {
+                       eError = eErrorEO;
+               }
+               else
+               {
+                       eError = PVRSRV_ERROR_NOT_FOUND;
+                       PVR_DPF((PVR_DBG_ERROR, "Stream does not exist"));
+               }
+               goto e0;
+       }
+
+       // Only one client/descriptor per stream supported
+       if (psNode->psRDesc != NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Can not open stream, stream already opened"));
+               eError = PVRSRV_ERROR_ALREADY_OPEN;
+               goto e0;
+       }
+
+       // Create an event handle for this client to wait on when no data in stream
+       // buffer.
+       eError = OSEventObjectOpen(psNode->hDataEventObj, &hEvent);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Not possible to open node's event object"));
+               eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;
+               goto e0;
+       }
+
+       psNewSD = TLMakeStreamDesc(psNode, ui32Mode, hEvent);
+       if (!psNewSD)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Not possible to make a new stream descriptor"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e1;
+       }
+
+       psGD->uiClientCnt++;
+       psNode->psRDesc = psNewSD;
+
+       /* Global data updated. Now release global lock */
+       OSLockRelease (psGD->hTLGDLock);
+
+       // Copy the export cookie back to the user mode API to enable access to
+       // the stream buffer from user-mode process.
+       *ppsBufCookie = TLStreamGetBufferCookie(psNode->psStream);
+
+       *ppsSD = psNewSD;
+
+       PVR_DPF((PVR_DBG_VERBOSE, 
+                        "TLServerOpenStreamKM evList=%p, evObj=%p", 
+                        psNode->hDataEventObj, 
+                        psNode->psRDesc->hDataEvent));
+
+       PVR_DPF_RETURN_OK;
+
+e1:
+       OSEventObjectClose (hEvent);
+e0:
+       OSLockRelease (psGD->hTLGDLock);
+       PVR_DPF_RETURN_RC (eError);
+}
+
+PVRSRV_ERROR
+TLServerCloseStreamKM(PTL_STREAM_DESC psSD)
+{
+       PVRSRV_ERROR    eError = PVRSRV_OK;
+       PTL_GLOBAL_DATA psGD = TLGGD();
+       PTL_SNODE               psNode = 0;
+       PTL_STREAM      psStream;
+       IMG_BOOL        bDestroyStream;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psSD);
+
+       // Sanity check, quick exit if there are no streams
+       if (psGD->psHead == NULL)
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND);
+       }
+
+       // Check stream still valid
+       psNode = TLFindStreamNodeByDesc(psSD);
+       if ((psNode == NULL) || (psNode != psSD->psNode))
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND);
+       }
+
+       /* Since the descriptor is valid, the stream should not have been made NULL */
+       PVR_ASSERT (psNode->psStream);
+
+       /* Save the stream's reference in-case its destruction is required after this
+        * client is removed */
+       psStream = psNode->psStream;
+       
+       /* Acquire TL_GLOBAL_DATA lock as the following TLRemoveDescAndTryFreeStreamNode
+        * call will update the TL_SNODE's descriptor value */
+       OSLockAcquire (psGD->hTLGDLock);
+
+       // Remove descriptor from stream object/list
+       bDestroyStream = TLRemoveDescAndTryFreeStreamNode (psNode);
+
+       // Assert the counter is sane after input data validated.
+       PVR_ASSERT(psGD->uiClientCnt > 0);
+       psGD->uiClientCnt--;
+
+       OSLockRelease (psGD->hTLGDLock);        
+       
+       /* Destroy the stream if its TL_SNODE was removed from TL_GLOBAL_DATA */
+       if (bDestroyStream)
+       {
+               TLStreamDestroy (psStream);
+               psStream = IMG_NULL;
+       }
+       
+       /* Clean up the descriptor structure */
+
+       // Close and free the event handle resource used by this descriptor
+       eError = OSEventObjectClose(psSD->hDataEvent);
+       if (eError != PVRSRV_OK)
+       {
+               // Log error but continue as it seems best
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectClose() failed error %d", eError));
+               eError = PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+       }
+
+       // Free the stream descriptor object
+       OSFREEMEM(psSD);
+
+       PVR_DPF_RETURN_RC(eError);
+}
+
+PVRSRV_ERROR
+TLServerAcquireDataKM(PTL_STREAM_DESC psSD,
+                                         IMG_UINT32*     puiReadOffset,
+                                         IMG_UINT32*     puiReadLen)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       TL_GLOBAL_DATA*         psGD = TLGGD();
+       IMG_UINT32                  uiTmpOffset = NO_ACQUIRE;
+       IMG_UINT32              uiTmpLen = 0;
+       PTL_SNODE                       psNode = 0;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psSD);
+
+       // Sanity check, quick exit if there are no streams
+       if (psGD->psHead == NULL)
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR);
+       }
+
+       // Check stream still valid
+       psNode = TLFindStreamNodeByDesc(psSD);
+       if ((psNode == NULL) || (psNode != psSD->psNode))
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND);
+       }
+
+       /* If we are here, the stream will never be made NULL until this context itself 
+        * calls TLRemoveDescAndTryFreeStreamNode(). This is because the producer will
+        * fail to make the stream NULL (by calling TLTryRemoveStreamAndFreeStreamNode)
+        * when a valid stream descriptor is present (i.e. a client is connected).
+        * Hence, no checks for stream being NON NULL are required after this. */
+       PVR_ASSERT (psNode->psStream);
+       
+       //PVR_DPF((PVR_DBG_VERBOSE, "TLServerAcquireDataKM evList=%p, evObj=%p", psSD->psNode->hDataEventObj, psSD->hDataEvent));
+
+       /* Check for data in the associated stream buffer, sleep/wait if none */
+       while (((uiTmpLen = TLStreamAcquireReadPos(psNode->psStream, &uiTmpOffset)) == 0) &&
+              (!(psSD->ui32Flags&PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING)) )
+       {
+               PVR_DPF((PVR_DBG_VERBOSE, "TLAcquireDataKM sleeping..."));
+
+               // Loop around if EndOfStream (nothing to read) and wait times out,
+               // exit loop if not time out but data is ready for client
+               while (TLStreamEOS(psNode->psStream))
+               {
+                       eError = OSEventObjectWaitTimeout(psSD->hDataEvent, NO_DATA_WAIT_PERIOD);
+                       if (eError != PVRSRV_OK)
+                       {
+                               /* Return timeout or other error condition to the caller who
+                                * can choose to call again if desired. We don't block
+                                * Indefinitely as we want the user mode application to have a
+                                * chance to break out and end if it needs to, so we return the
+                                * time out error code. */
+                               PVR_DPF_RETURN_RC(eError);
+                       }
+               }
+       }
+
+       /* Data available now if we reach here in blocking more or we take the
+        * values as is in non-blocking mode which might be all zeros. */
+       *puiReadOffset = uiTmpOffset;
+       *puiReadLen = uiTmpLen;
+
+       PVR_DPF((PVR_DBG_VERBOSE, "TLAcquireDataKM return offset=%d, len=%d bytes", *puiReadOffset, *puiReadLen));
+
+       PVR_DPF_RETURN_OK;
+}
+
+PVRSRV_ERROR
+TLServerReleaseDataKM(PTL_STREAM_DESC psSD,
+                                         IMG_UINT32      uiReadOffset,
+                                         IMG_UINT32      uiReadLen)
+{
+       TL_GLOBAL_DATA*         psGD = TLGGD();
+       PTL_SNODE                       psNode = 0;
+
+       PVR_DPF_ENTERED;
+
+       /* Unreferenced in release builds */
+       PVR_UNREFERENCED_PARAMETER(uiReadOffset);
+
+       PVR_ASSERT(psSD);
+
+       // Sanity check, quick exit if there are no streams
+       if (psGD->psHead == NULL)
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_ERROR);
+       }
+
+       // Check stream still valid
+       psNode = TLFindStreamNodeByDesc(psSD);
+       if ((psNode == NULL) || (psNode != psSD->psNode))
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_HANDLE_NOT_FOUND);
+       }
+
+       /* Since we have a valid stream descriptor, the stream should not have been
+        * made NULL by any producer context. */
+       PVR_ASSERT (psNode->psStream);
+
+       PVR_DPF((PVR_DBG_VERBOSE, "TLReleaseDataKM uiReadOffset=%d, uiReadLen=%d", uiReadOffset, uiReadLen));
+
+       // Move read position on to free up space in stream buffer
+       TLStreamAdvanceReadPos(psNode->psStream, uiReadLen);
+
+       PVR_DPF_RETURN_OK;
+}
+
+/*****************************************************************************
+ End of file (tlserver.c)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/server/common/tlstream.c b/drivers/gpu/rogue_m/services/server/common/tlstream.c
new file mode 100644 (file)
index 0000000..1a59a9d
--- /dev/null
@@ -0,0 +1,930 @@
+/*************************************************************************/ /*!
+@File
+@Title          Transport Layer kernel side API implementation.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport Layer API implementation.
+                These functions are provided to driver components.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+//#define PVR_DPF_FUNCTION_TRACE_ON 1
+#undef PVR_DPF_FUNCTION_TRACE_ON
+#include "pvr_debug.h"
+
+#include "allocmem.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+
+#include "pvr_tlcommon.h"
+#include "tlintern.h"
+#include "tlstream.h"
+
+/* To debug buffer utilisation enable this macro here and
+ * define PVRSRV_NEED_PVR_TRACE in the server pvr_debug.c and in tutils.c
+ * before the inclusion of pvr_debug.h. Issue pvrtutils 6 on target to see
+ * stream buffer utilisation. */
+//#define TL_BUFFER_UTILIZATION 1
+
+#define EVENT_OBJECT_TIMEOUT_MS 1000
+
+/* Given the state of the buffer it returns a number of bytes that the client
+ * can use for a successful allocation. */
+static INLINE IMG_UINT32 suggestAllocSize(IMG_UINT32 ui32LRead,
+                                                                               IMG_UINT32 ui32LWrite, 
+                                                                               IMG_UINT32 ui32CBSize,
+                                                               IMG_UINT32 ui32ReqSizeMin)
+{
+       IMG_UINT32 ui32AvSpace = 0;
+       
+       /* This could be written in fewer lines using the ? operator but it  
+               would not be kind to potential readers of this source at all. */ 
+       if ( ui32LRead > ui32LWrite )                          /* Buffer WRAPPED */
+       {
+               if ( (ui32LRead - ui32LWrite) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE) )
+               {
+                       ui32AvSpace =  ui32LRead - ui32LWrite - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE;
+               }
+       }
+       else                                                  /* Normal, no wrap */
+       {
+               if ( (ui32CBSize - ui32LWrite) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE) )
+               {
+                       ui32AvSpace =  ui32CBSize - ui32LWrite - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE;
+               }
+               else if ( (ui32LRead - 0) > (sizeof(PVRSRVTL_PACKETHDR) + ui32ReqSizeMin + (IMG_INT) BUFFER_RESERVED_SPACE) )
+               {
+                       ui32AvSpace =  ui32LRead - sizeof(PVRSRVTL_PACKETHDR) - (IMG_INT) BUFFER_RESERVED_SPACE;
+               }
+       }
+    /* The max size of a TL packet currently is UINT16. adjust accordingly */
+       return MIN(ui32AvSpace, IMG_UINT16_MAX);
+}
+
+/* Returns bytes left in the buffer. Negative if there is not any.
+ * two 4b aligned values are reserved, one for the write failed buffer flag
+ * and one to be able to distinguish the buffer full state to the buffer
+ * empty state.
+ * Always returns free space -8 even when the "write failed" packet may be
+ * already in the stream before this write. */
+static INLINE IMG_INT
+cbSpaceLeft(IMG_UINT32 ui32Read, IMG_UINT32 ui32Write, IMG_UINT32 ui32size)
+{
+       /* We need to reserve 4b (one packet) in the buffer to be able to tell empty 
+        * buffers from full buffers and one more for packet write fail packet */
+       if ( ui32Read > ui32Write )
+       {
+               return (IMG_INT) ui32Read - (IMG_INT)ui32Write - (IMG_INT) BUFFER_RESERVED_SPACE;
+       }
+       else
+       {
+               return (IMG_INT)ui32size - ((IMG_INT)ui32Write - (IMG_INT)ui32Read) - (IMG_INT) BUFFER_RESERVED_SPACE;
+       }
+}   
+
+/******************************************************************************* 
+ * TL Server public API implementation.
+ ******************************************************************************/
+PVRSRV_ERROR
+TLStreamCreate(IMG_HANDLE *phStream,
+                          IMG_CHAR *szStreamName,
+                          IMG_UINT32 ui32Size,
+                          IMG_UINT32 ui32StreamFlags,
+               TL_STREAM_SOURCECB pfProducerCB,
+               IMG_PVOID pvProducerUD)
+{
+       PTL_STREAM     psTmp;
+       PVRSRV_ERROR   eError;
+       IMG_HANDLE     hEventList;
+       PTL_SNODE      psn = 0;
+       IMG_CHAR       pszBufferLabel[PRVSRVTL_MAX_STREAM_NAME_SIZE+20];
+
+       DEVMEM_FLAGS_T uiMemFlags =  PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                                PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | 
+                                                                PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                                PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT | /* CPU only */
+                                                                PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PVR_DPF_ENTERED;
+       /* Sanity checks:  */
+       /* non NULL handler required */
+       if ( NULL == phStream ) 
+       { 
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+       if (OSStringLength(szStreamName) >= PRVSRVTL_MAX_STREAM_NAME_SIZE) 
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+
+       /* Acquire TL_GLOBAL_DATA lock here because, if the following TLFindStreamNodeByName()
+        * returns NULL, a new TL_SNODE will be added to TL_GLOBAL_DATA's TL_SNODE list */
+       OSLockAcquire (TLGGD()->hTLGDLock);
+       
+       /* Check if there already exists a stream with this name. */
+       psn = TLFindStreamNodeByName( szStreamName );
+       if ( IMG_NULL != psn )
+       {
+               eError = PVRSRV_ERROR_ALREADY_EXISTS;
+               goto e0;
+       }
+       
+       /* Allocate stream structure container (stream struct) for the new stream */
+       psTmp = OSAllocZMem(sizeof(TL_STREAM)) ;
+       if ( NULL == psTmp ) 
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       OSStringCopy(psTmp->szName, szStreamName);
+
+       if ( ui32StreamFlags & TL_FLAG_FORCE_FLUSH )
+       {
+               psTmp->bWaitForEmptyOnDestroy = IMG_TRUE;
+       }
+
+       psTmp->bNoSignalOnCommit = (ui32StreamFlags&TL_FLAG_NO_SIGNAL_ON_COMMIT) ?  IMG_TRUE : IMG_FALSE;
+
+       if ( ui32StreamFlags & TL_FLAG_DROP_DATA ) 
+       {
+               if ( ui32StreamFlags & TL_FLAG_BLOCKING_RESERVE ) 
+               {
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+                       goto e1;
+               }
+               psTmp->bDrop = IMG_TRUE;
+       }
+       else if ( ui32StreamFlags & TL_FLAG_BLOCKING_RESERVE ) 
+    {  /* Additional synchronization object required for this kind of stream */
+        psTmp->bBlock = IMG_TRUE;
+
+               eError = OSEventObjectCreate(NULL, &psTmp->hProducerEventObj);
+               if (eError != PVRSRV_OK)
+               {
+                       goto e1;
+               }
+               /* Create an event handle for this kind of stream */
+               eError = OSEventObjectOpen(psTmp->hProducerEventObj, &psTmp->hProducerEvent);
+               if (eError != PVRSRV_OK)
+               {
+                       goto e2;
+               }
+    }
+
+       /* Remember producer supplied CB and data for later */
+       psTmp->pfProducerCallback = (IMG_VOID(*)(IMG_VOID))pfProducerCB;
+       psTmp->pvProducerUserData = pvProducerUD;
+
+       /* Round the requested bytes to a multiple of array elements' size, eg round 3 to 4 */
+       psTmp->ui32Size = PVRSRVTL_ALIGN(ui32Size);
+       psTmp->ui32Read = 0;
+       psTmp->ui32Write = 0;
+       psTmp->ui32Pending = NOTHING_PENDING;
+
+       OSSNPrintf(pszBufferLabel, sizeof(pszBufferLabel), "TLStreamBuf-%s", szStreamName);
+
+       /* Allocate memory for the circular buffer and export it to user space. */
+       eError = DevmemAllocateExportable( IMG_NULL,
+                                                                          (IMG_HANDLE) TLGetGlobalRgxDevice(),
+                                                                          (IMG_DEVMEM_SIZE_T)psTmp->ui32Size,
+                                                                          (IMG_DEVMEM_ALIGN_T) OSGetPageSize(),
+                                                                          uiMemFlags | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
+                                                                          pszBufferLabel,
+                                                                          &psTmp->psStreamMemDesc);
+       PVR_LOGG_IF_ERROR(eError, "DevmemAllocateExportable", e3);
+
+       eError = DevmemAcquireCpuVirtAddr( psTmp->psStreamMemDesc, (IMG_VOID**) &psTmp->pbyBuffer );
+       PVR_LOGG_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", e4);
+
+       eError = DevmemExport(psTmp->psStreamMemDesc, &(psTmp->sExportCookie));
+       PVR_LOGG_IF_ERROR(eError, "DevmemExport", e5);
+
+       /* Synchronization object to synchronize with user side data transfers. */
+       eError = OSEventObjectCreate(psTmp->szName, &hEventList);
+       if (eError != PVRSRV_OK)
+       {
+               goto e6;
+       }
+
+       eError = OSLockCreate (&psTmp->hStreamLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto e7;
+       }
+
+       /* Now remember the stream in the global TL structures */
+       psn = TLMakeSNode(hEventList, (TL_STREAM *)psTmp, 0);
+       if (psn == NULL)
+       {
+               eError=PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e8;
+       }
+
+       /* Stream node created, now reset the write reference count to 1
+        * (i.e. this context's reference) */
+       psn->uiWRefCount = 1;
+
+       TLAddStreamNode(psn);
+
+       /* Release TL_GLOBAL_DATA lock as the new TL_SNODE is now added to the list */
+       OSLockRelease (TLGGD()->hTLGDLock);
+
+       /* Best effort signal, client wait timeout will ultimately let it find the
+        * new stream if this fails, acceptable to avoid cleanup as it is tricky
+        * at this point */
+       (void) OSEventObjectSignal(TLGGD()->hTLEventObj);
+
+       /* Pass the newly created stream handle back to caller */
+       *phStream = (IMG_HANDLE)psTmp;
+       PVR_DPF_RETURN_OK;
+
+e8:
+       OSLockDestroy(psTmp->hStreamLock);
+e7:
+       OSEventObjectDestroy(hEventList);
+e6:
+       DevmemUnexport(psTmp->psStreamMemDesc, &(psTmp->sExportCookie));
+e5:
+       DevmemReleaseCpuVirtAddr( psTmp->psStreamMemDesc );
+e4:
+       DevmemFree(psTmp->psStreamMemDesc);
+e3:
+       OSEventObjectClose(psTmp->hProducerEvent);
+e2:
+       OSEventObjectDestroy(psTmp->hProducerEventObj);
+e1:
+       OSFREEMEM(psTmp);
+e0:
+       OSLockRelease (TLGGD()->hTLGDLock);
+
+       PVR_DPF_RETURN_RC(eError);
+}
+
+PVRSRV_ERROR
+TLStreamOpen(IMG_HANDLE *phStream,
+             IMG_CHAR   *szStreamName)
+{
+       PTL_SNODE  psTmpSNode;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == phStream || IMG_NULL == szStreamName )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+
+       /* Acquire the TL_GLOBAL_DATA lock first to ensure,
+        * the TL_STREAM while returned and being modified,
+        * is not deleted by some other context */
+       OSLockAcquire (TLGGD()->hTLGDLock);
+       
+       /* Search for a stream node with a matching stream name */
+       psTmpSNode = TLFindStreamNodeByName(szStreamName);
+
+       if ( IMG_NULL == psTmpSNode )
+       {
+               OSLockRelease (TLGGD()->hTLGDLock);
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_FOUND);
+       }
+
+       /* The TL_SNODE->uiWRefCount governs the presence of this node in the
+        * TL_GLOBAL_DATA list i.e. when uiWRefCount falls to zero we try removing
+        * this node from the TL_GLOBAL_DATA list. Hence, is protected using the
+        * TL_GLOBAL_DATA lock and not TL_STREAM lock */
+       psTmpSNode->uiWRefCount++;
+       
+       OSLockRelease (TLGGD()->hTLGDLock);
+
+       /* Return the stream handle to the caller */
+       *phStream = (IMG_HANDLE)psTmpSNode->psStream;
+
+       PVR_DPF_RETURN_VAL(PVRSRV_OK);
+}
+
+IMG_VOID 
+TLStreamClose(IMG_HANDLE hStream)
+{
+       PTL_STREAM      psTmp;
+       IMG_BOOL        bDestroyStream;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == hStream )
+       {
+               PVR_DPF((PVR_DBG_WARNING,
+                                "TLStreamClose failed as NULL stream handler passed, nothing done.\n"));
+               PVR_DPF_RETURN;
+       }
+
+       psTmp = (PTL_STREAM)hStream;
+
+       /* Acquire TL_GLOBAL_DATA lock for updating the reference count as this will be required 
+        * in-case this TL_STREAM node is to be deleted */
+       OSLockAcquire (TLGGD()->hTLGDLock);
+       
+       /* Decrement write reference counter of the stream */
+       psTmp->psNode->uiWRefCount--;
+
+       if ( 0 != psTmp->psNode->uiWRefCount )
+       {       /* The stream is still being used in other context(s) do not destroy anything */
+               OSLockRelease (TLGGD()->hTLGDLock);
+               PVR_DPF_RETURN;
+       }
+       else
+       {
+               /* Now we try removing this TL_STREAM from TL_GLOBAL_DATA */
+
+               if ( psTmp->bWaitForEmptyOnDestroy == IMG_TRUE )
+               {
+                       /* We won't require the TL_STREAM lock to be acquired here for accessing its read
+                        * and write offsets. REASON: We are here because there is no producer context
+                        * referencing this TL_STREAM, hence its ui32Write offset won't be changed now.
+                        * Also, the updation of ui32Read offset is not protected by locks */
+                       while (psTmp->ui32Read != psTmp->ui32Write)
+                       {
+                               /* Release lock before sleeping */
+                               OSLockRelease (TLGGD()->hTLGDLock);
+                               
+                               OSEventObjectWaitTimeout(psTmp->hProducerEvent, EVENT_OBJECT_TIMEOUT_MS);
+                               
+                               OSLockAcquire (TLGGD()->hTLGDLock);
+
+                               /* Ensure destruction of stream is still required */
+                               if (0 != psTmp->psNode->uiWRefCount)
+                               {
+                                       OSLockRelease (TLGGD()->hTLGDLock);
+                                       PVR_DPF_RETURN;
+                               }
+                       }
+               }
+
+               /* Try removing the stream from TL_GLOBAL_DATA */
+               bDestroyStream = TLTryRemoveStreamAndFreeStreamNode (psTmp->psNode);
+               
+               OSLockRelease (TLGGD()->hTLGDLock);
+               
+               if (bDestroyStream)
+               {
+                       /* Destroy the stream if it was removed from TL_GLOBAL_DATA */
+                       TLStreamDestroy (psTmp);
+                       psTmp = IMG_NULL;
+               }
+               PVR_DPF_RETURN;
+       }
+}
+
+static PVRSRV_ERROR
+DoTLStreamReserve(IMG_HANDLE hStream,
+                               IMG_UINT8 **ppui8Data, 
+                               IMG_UINT32 ui32ReqSize,
+                IMG_UINT32 ui32ReqSizeMin,
+                               PVRSRVTL_PACKETTYPE ePacketType,
+                               IMG_UINT32* pui32AvSpace)
+{
+       PTL_STREAM psTmp;
+       IMG_UINT32 *pui32Buf, ui32LRead, ui32LWrite, ui32LPending, lReqSizeAligned, lReqSizeActual;
+       IMG_INT pad, iFreeSpace;
+
+       PVR_DPF_ENTERED;
+       if (pui32AvSpace) *pui32AvSpace = 0;
+
+       if (( IMG_NULL == hStream ))
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+       psTmp = (PTL_STREAM)hStream;
+
+       /* Assert used as the packet type parameter is currently only provided
+        * by the TL APIs, not the calling client */
+       PVR_ASSERT((PVRSRVTL_PACKETTYPE_UNDEF < ePacketType) && (PVRSRVTL_PACKETTYPE_LAST >= ePacketType));
+
+       /* The buffer is only used in "rounded" (aligned) chunks */
+       lReqSizeAligned = PVRSRVTL_ALIGN(ui32ReqSize);
+
+       /* Lock the stream before reading it's pending value, because if pending is set
+        * to NOTHING_PENDING, we update the pending value such that subsequent calls to
+        * this function from other context(s) fail with PVRSRV_ERROR_NOT_READY */
+       OSLockAcquire (psTmp->hStreamLock);
+
+       /* Get a local copy of the stream buffer parameters */
+       ui32LRead  = psTmp->ui32Read ;
+       ui32LWrite = psTmp->ui32Write ;
+       ui32LPending = psTmp->ui32Pending ;
+
+       /*  Multiple pending reserves are not supported. */
+       if ( NOTHING_PENDING != ui32LPending )
+       {
+               OSLockRelease (psTmp->hStreamLock);
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_READY);
+       }
+
+       if ( IMG_UINT16_MAX < lReqSizeAligned )
+       {
+               psTmp->ui32Pending = NOTHING_PENDING;
+               if (pui32AvSpace)
+               {
+                       *pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin);
+               }
+               OSLockRelease (psTmp->hStreamLock);
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_FULL);
+       }
+
+       /* Prevent other threads from entering this region before we are done updating
+        * the pending value and write offset (incase of padding). This is not exactly 
+        * a lock but a signal for other contexts that there is a TLStreamCommit operation
+        * pending on this stream */
+       psTmp->ui32Pending = 0;
+
+       OSLockRelease (psTmp->hStreamLock);
+
+       /* If there is enough contiguous space following the current Write
+        * position then no padding is required */
+       if (  psTmp->ui32Size
+               < ui32LWrite + lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) )
+       {
+               pad = psTmp->ui32Size - ui32LWrite;
+       }
+       else
+       {
+               pad = 0 ;
+       }
+
+       lReqSizeActual = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) + pad ;
+       /* If this is a blocking reserve and there is not enough space then wait. */
+       if( psTmp->bBlock )
+       {
+               if( psTmp->ui32Size < lReqSizeActual )
+               {
+                       /* Acquire stream lock for updating pending value */
+                       OSLockAcquire (psTmp->hStreamLock);
+                       psTmp->ui32Pending = NOTHING_PENDING;
+                       OSLockRelease (psTmp->hStreamLock);
+                       
+                       PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
+               }
+               while ( ( cbSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size)
+                        <(IMG_INT) lReqSizeActual ) )
+               {
+                       OSEventObjectWait(psTmp->hProducerEvent);
+                       // update local copies.
+                       ui32LRead  = psTmp->ui32Read ;
+                       ui32LWrite = psTmp->ui32Write ;
+               }
+       }
+
+       iFreeSpace = cbSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size);
+       
+       /* The easy case: buffer has enough space to hold the requested packet (data + header) */
+       if (  iFreeSpace >=(IMG_INT) lReqSizeActual )
+       {
+               if ( pad ) 
+               { 
+                       /* Inserting padding packet. */
+                       pui32Buf = (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite];
+                       *pui32Buf = PVRSRVTL_SET_PACKET_PADDING(pad-sizeof(PVRSRVTL_PACKETHDR)) ;
+
+                       /* CAUTION: the used pad value should always result in a properly 
+                        *          aligned ui32LWrite pointer, which in this case is 0 */
+                       ui32LWrite = (ui32LWrite + pad) % psTmp->ui32Size;
+                       /* Detect unaligned pad value */
+                       PVR_ASSERT( ui32LWrite == 0);
+               }
+               /* Insert size-stamped packet header */
+               pui32Buf = (IMG_UINT32*) &psTmp->pbyBuffer[ui32LWrite];
+
+               *pui32Buf = PVRSRVTL_SET_PACKET_HDR(ui32ReqSize, ePacketType);
+
+               /* return the next position in the buffer to the user */
+               *ppui8Data =  &psTmp->pbyBuffer[ ui32LWrite+sizeof(PVRSRVTL_PACKETHDR) ] ;
+
+               /* update pending offset: size stamp + data  */
+               ui32LPending = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) ;
+       }
+       /* The not so easy case: not enough space, decide how to handle data */
+       else
+       {
+
+#if defined(DEBUG)
+               /* Sanity check that the user is not trying to add more data than the
+                * buffer size. Conditionally compile it out to ensure this check has
+                * no impact to release performance */
+               if ( lReqSizeAligned+sizeof(PVRSRVTL_PACKETHDR) > psTmp->ui32Size )
+               {
+                       OSLockAcquire (psTmp->hStreamLock);
+                       psTmp->ui32Pending = NOTHING_PENDING;
+                       OSLockRelease (psTmp->hStreamLock);
+                       PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
+               }
+#endif
+
+               /* No data overwriting, insert write_failed flag and return */
+               if (psTmp->bDrop) 
+               {
+                       /* Caller should not try to use ppui8Data,
+                        * NULLify to give user a chance of avoiding memory corruption */
+                       ppui8Data = IMG_NULL;
+
+                       /* This flag should not be inserted two consecutive times, so 
+                        * check the last ui32 in case it was a packet drop packet. */
+                       pui32Buf =  ui32LWrite 
+                                         ? 
+                                           (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite - sizeof(PVRSRVTL_PACKETHDR)]
+                                          : // Previous four bytes are not guaranteed to be a packet header...
+                                           (IMG_UINT32*)&psTmp->pbyBuffer[psTmp->ui32Size - PVRSRVTL_PACKET_ALIGNMENT];
+
+                       if ( PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED
+                                != 
+                                GET_PACKET_TYPE( (PVRSRVTL_PACKETHDR*)pui32Buf ) )
+                       {
+                               /* Insert size-stamped packet header */
+                               pui32Buf = (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite];
+                               *pui32Buf = PVRSRVTL_SET_PACKET_WRITE_FAILED ;
+                               ui32LWrite += sizeof(PVRSRVTL_PACKETHDR);
+                               ui32LWrite %= psTmp->ui32Size;
+                               iFreeSpace -= sizeof(PVRSRVTL_PACKETHDR);
+                       }
+
+                       OSLockAcquire (psTmp->hStreamLock);
+                       psTmp->ui32Write = ui32LWrite;
+                       psTmp->ui32Pending = NOTHING_PENDING;
+                       OSLockRelease (psTmp->hStreamLock);
+                       
+                       if (pui32AvSpace)
+                       {
+                               *pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin);
+                       }
+                       PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_FULL);
+               } 
+       }
+
+       /* Acquire stream lock for updating stream parameters */
+       OSLockAcquire (psTmp->hStreamLock);
+       psTmp->ui32Write = ui32LWrite ;
+       psTmp->ui32Pending = ui32LPending ;
+       OSLockRelease (psTmp->hStreamLock);
+
+       PVR_DPF_RETURN_OK;
+}
+
+PVRSRV_ERROR
+TLStreamReserve(IMG_HANDLE hStream,
+                               IMG_UINT8 **ppui8Data,
+                               IMG_UINT32 ui32Size)
+{
+       return DoTLStreamReserve(hStream, ppui8Data, ui32Size, ui32Size, PVRSRVTL_PACKETTYPE_DATA, NULL);
+}
+
+PVRSRV_ERROR
+TLStreamReserve2(IMG_HANDLE hStream,
+                IMG_UINT8  **ppui8Data,
+                IMG_UINT32 ui32Size,
+                IMG_UINT32 ui32SizeMin,
+                IMG_UINT32* pui32Available)
+{
+       return DoTLStreamReserve(hStream, ppui8Data, ui32Size, ui32SizeMin, PVRSRVTL_PACKETTYPE_DATA, pui32Available);
+}
+
+PVRSRV_ERROR
+TLStreamCommit(IMG_HANDLE hStream, IMG_UINT32 ui32ReqSize)
+{
+       PTL_STREAM psTmp;
+       IMG_UINT32 ui32LRead, ui32OldWrite, ui32LWrite, ui32LPending;
+       PVRSRV_ERROR eError;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == hStream )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+       psTmp = (PTL_STREAM)hStream;
+
+       /* Get a local copy of the stream buffer parameters */
+       ui32LRead = psTmp->ui32Read ;
+       ui32LWrite = psTmp->ui32Write ;
+       ui32LPending = psTmp->ui32Pending ;
+
+       ui32OldWrite = ui32LWrite;
+
+       // Space in buffer is aligned
+       ui32ReqSize = PVRSRVTL_ALIGN(ui32ReqSize);
+
+       /* Sanity check. ReqSize + packet header size. */
+       if ( ui32LPending != ui32ReqSize + sizeof(PVRSRVTL_PACKETHDR) )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
+       }
+
+       /* Update pointer to written data. */
+       ui32LWrite = (ui32LWrite + ui32LPending) % psTmp->ui32Size;
+
+       /* and reset LPending to 0 since data are now submitted  */
+       ui32LPending = NOTHING_PENDING;
+
+       /* Calculate high water mark for debug purposes */
+#if defined(TL_BUFFER_UTILIZATION)
+       {
+               IMG_UINT32 tmp = 0;
+               if (ui32LWrite > ui32LRead)
+               {
+                       tmp = (ui32LWrite-ui32LRead);
+               }
+               else if (ui32LWrite < ui32LRead)
+               {
+                       tmp = (psTmp->ui32Size-ui32LRead+ui32LWrite);
+               } /* else equal, ignore */
+
+               if (tmp > psTmp->ui32BufferUt)
+               {
+                       psTmp->ui32BufferUt = tmp;
+               }
+       }
+#endif
+
+       /* Acquire stream lock to ensure other context(s) (if any)
+        * wait on the lock (in DoTLStreamReserve) for consistent values
+        * of write offset and pending value */
+       OSLockAcquire (psTmp->hStreamLock);
+
+       /* Update stream buffer parameters to match local copies */
+       psTmp->ui32Write = ui32LWrite ;
+       psTmp->ui32Pending = ui32LPending ;
+
+       OSLockRelease (psTmp->hStreamLock);
+
+       /* If  we have transitioned from an empty buffer to a non-empty buffer,
+        * signal any consumers that may be waiting */
+       if (ui32OldWrite == ui32LRead && !psTmp->bNoSignalOnCommit)
+       {
+               /* Signal consumers that may be waiting */
+               eError = OSEventObjectSignal(psTmp->psNode->hDataEventObj);
+               if ( eError != PVRSRV_OK)
+               {
+                       PVR_DPF_RETURN_RC(eError);
+               }
+       }
+       
+       PVR_DPF_RETURN_OK;
+}
+
+PVRSRV_ERROR
+TLStreamWrite(IMG_HANDLE hStream, IMG_UINT8 *pui8Src, IMG_UINT32 ui32Size)
+{
+       IMG_BYTE *pbyDest = IMG_NULL;
+       PVRSRV_ERROR eError;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == hStream )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+
+       eError = TLStreamReserve(hStream, &pbyDest, ui32Size);
+       if ( PVRSRV_OK != eError ) 
+       {       
+               PVR_DPF_RETURN_RC(eError);
+       }
+       else
+       {
+               PVR_ASSERT ( pbyDest != NULL );
+               OSMemCopy((IMG_VOID*)pbyDest, (IMG_VOID*)pui8Src, ui32Size);
+               eError = TLStreamCommit(hStream, ui32Size);
+               if ( PVRSRV_OK != eError ) 
+               {       
+                       PVR_DPF_RETURN_RC(eError);
+               }
+       }
+       PVR_DPF_RETURN_OK;
+}
+
+IMG_VOID TLStreamInfo(PTL_STREAM_INFO psInfo)
+{
+       IMG_DEVMEM_SIZE_T actual_req_size;
+       IMG_DEVMEM_ALIGN_T align = 4; /* Low dummy value so the real value can be obtained */
+
+       actual_req_size = 2; 
+       DevmemExportalignAdjustSizeAndAlign(IMG_NULL, &actual_req_size, &align);
+
+       psInfo->headerSize = sizeof(PVRSRVTL_PACKETHDR);
+       psInfo->minReservationSize = sizeof(IMG_UINT32);
+       psInfo->pageSize = (IMG_UINT32)(actual_req_size);
+       psInfo->pageAlign = (IMG_UINT32)(align);
+}
+
+PVRSRV_ERROR
+TLStreamMarkEOS(IMG_HANDLE psStream)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT8* pData;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == psStream )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+
+       eError = DoTLStreamReserve(psStream, &pData, 0, 0, PVRSRVTL_PACKETTYPE_MARKER_EOS, NULL);
+       if ( PVRSRV_OK !=  eError )
+       {
+               PVR_DPF_RETURN_RC(eError);
+       }
+
+       PVR_DPF_RETURN_RC(TLStreamCommit(psStream, 0));
+}
+
+PVRSRV_ERROR
+TLStreamSync(IMG_HANDLE psStream)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PTL_STREAM   psTmp;
+
+       PVR_DPF_ENTERED;
+
+       if ( IMG_NULL == psStream )
+       {
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
+       }
+       psTmp = (PTL_STREAM)psStream;
+       
+       /* Signal clients only when data is available to read */
+       if (psTmp->ui32Read != psTmp->ui32Write)
+       {
+               eError = OSEventObjectSignal(psTmp->psNode->hDataEventObj);
+       }
+
+       PVR_DPF_RETURN_RC(eError);
+}
+
+/*
+ * Internal stream APIs to server part of Transport Layer, declared in
+ * header tlintern.h. Direct pointers to stream objects are used here as
+ * these functions are internal.
+ */
+IMG_UINT32
+TLStreamAcquireReadPos(PTL_STREAM psStream, IMG_UINT32* puiReadOffset)
+{
+       IMG_UINT32 uiReadLen = 0;
+       IMG_UINT32 ui32LRead, ui32LWrite;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psStream);
+       PVR_ASSERT(puiReadOffset);
+
+       /* Grab a local copy */
+       ui32LRead = psStream->ui32Read;
+       ui32LWrite = psStream->ui32Write;
+
+       /* No data available and CB defined - try and get data */
+       if ((ui32LRead == ui32LWrite) && psStream->pfProducerCallback)
+       {
+               PVRSRV_ERROR eRc;
+               IMG_UINT32   ui32Resp = 0;
+
+               eRc = ((TL_STREAM_SOURCECB)psStream->pfProducerCallback)(psStream, TL_SOURCECB_OP_CLIENT_EOS,
+                               &ui32Resp, psStream->pvProducerUserData);
+               PVR_LOG_IF_ERROR(eRc, "TLStream->pfProducerCallback");
+
+               ui32LWrite = psStream->ui32Write;
+       }
+
+       /* No data available... */
+       if (ui32LRead == ui32LWrite)
+       {
+               PVR_DPF_RETURN_VAL(0);
+       }
+
+       /* Data is available to read... */
+       *puiReadOffset = ui32LRead;
+
+       /*PVR_DPF((PVR_DBG_VERBOSE,
+        *              "TLStreamAcquireReadPos Start before: Write:%d, Read:%d, size:%d",
+        *              ui32LWrite, ui32LRead, psStream->ui32Size));
+        */
+
+       if ( ui32LRead > ui32LWrite )
+       {       /* CB has wrapped around. 
+                * Return the first contiguous piece of memory, ie [ReadLen,EndOfBuffer]
+                * and let a subsequent AcquireReadPos read the rest of the Buffer */
+               /*PVR_DPF((PVR_DBG_VERBOSE, "TLStreamAcquireReadPos buffer has wrapped"));*/
+               uiReadLen = psStream->ui32Size - ui32LRead;
+       }
+       else
+       {       // CB has not wrapped
+               uiReadLen = ui32LWrite - ui32LRead;
+       }
+
+       PVR_DPF_RETURN_VAL(uiReadLen);
+}
+
+IMG_VOID
+TLStreamAdvanceReadPos(PTL_STREAM psStream, IMG_UINT32 uiReadLen)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psStream);
+
+       /* Update the read offset by the length provided in a circular manner.
+        * Assuming the updation to be atomic hence, avoiding use of locks */
+       psStream->ui32Read = (psStream->ui32Read + uiReadLen) % psStream->ui32Size;
+
+       /* If this is a blocking reserve stream, 
+        * notify reserves that may be pending */
+       if(psStream->bBlock)
+       {
+               PVRSRV_ERROR eError;
+               eError = OSEventObjectSignal(psStream->hProducerEventObj);
+               if ( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_WARNING,
+                                        "Error in TLStreamAdvanceReadPos: OSEventObjectSignal returned:%u",
+                                        eError));
+               }
+       }
+
+       PVR_DPF((PVR_DBG_VERBOSE,
+                        "TLStreamAdvanceReadPos Read now at: %d",
+                       psStream->ui32Read));
+       PVR_DPF_RETURN;
+}
+
+IMG_VOID
+TLStreamDestroy (PTL_STREAM psStream)
+{
+       PVR_ASSERT (psStream);
+       
+       OSLockDestroy (psStream->hStreamLock);
+
+       /* If block-while-reserve stream, the stream's hProducerEvent and hProducerEventObj
+        * need to be cleaned as well */
+       if ( IMG_TRUE == psStream->bBlock ) 
+       {
+               OSEventObjectClose(psStream->hProducerEvent);
+               OSEventObjectDestroy(psStream->hProducerEventObj);
+       }
+
+       DevmemUnexport(psStream->psStreamMemDesc, &psStream->sExportCookie);
+       DevmemReleaseCpuVirtAddr(psStream->psStreamMemDesc);
+       DevmemFree(psStream->psStreamMemDesc);
+       OSFREEMEM(psStream);
+}
+
+DEVMEM_EXPORTCOOKIE*
+TLStreamGetBufferCookie(PTL_STREAM psStream)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psStream);
+
+       PVR_DPF_RETURN_VAL(&psStream->sExportCookie);
+}
+
+IMG_BOOL
+TLStreamEOS(PTL_STREAM psStream)
+{
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psStream);
+
+       /* If both pointers are equal then the buffer is empty */
+       PVR_DPF_RETURN_VAL( psStream->ui32Read == psStream->ui32Write );
+}
+
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.c b/drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.c
new file mode 100644 (file)
index 0000000..973b9bc
--- /dev/null
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debugging and miscellaneous functions server implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Kernel services functions for debugging and other
+                miscellaneous functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv.h"
+#include "pvr_debug.h"
+#include "debugmisc_server.h"
+#include "rgxfwutils.h"
+#include "rgxta3d.h"
+#include "pdump_km.h"
+#include "mmu_common.h"
+#include "devicemem_server.h"
+#include "osfunc.h"
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDebugMiscSLCSetBypassStateKM(
+       PVRSRV_DEVICE_NODE *psDeviceNode,
+       IMG_UINT32  uiFlags,
+       IMG_BOOL bSetBypassed)
+{
+       RGXFWIF_KCCB_CMD  sSLCBPCtlCmd;
+       PVRSRV_ERROR  eError = PVRSRV_OK;
+
+       sSLCBPCtlCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCBPCTL;
+       sSLCBPCtlCmd.uCmdData.sSLCBPCtlData.bSetBypassed = bSetBypassed;
+       sSLCBPCtlCmd.uCmdData.sSLCBPCtlData.uiFlags = uiFlags;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                                   RGXFWIF_DM_GP,
+                                   &sSLCBPCtlCmd,
+                                   sizeof(sSLCBPCtlCmd),
+                                   IMG_TRUE);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscSLCSetEnableStateKM: RGXScheduleCommandfailed. Error:%u", eError));
+       }
+       else
+       {
+               /* Wait for the SLC flush to complete */
+               eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVDebugMiscSLCSetEnableStateKM: Waiting for value aborted with error (%u)", eError));
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetFWLogKM(
+       PVRSRV_DEVICE_NODE *psDeviceNode,
+       IMG_UINT32  ui32RGXFWLogType)
+{
+       PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
+
+       /* check log type is valid */
+       if (ui32RGXFWLogType & ~RGXFWIF_LOG_TYPE_MASK)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* set the new log type */
+       psDevInfo->psRGXFWIfTraceBuf->ui32LogType = ui32RGXFWLogType;
+
+       return PVRSRV_OK;
+
+}
+
+static IMG_BOOL
+_RGXDumpFreeListPageList(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       RGX_FREELIST *psFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode);
+
+       RGXDumpFreeListPageList(psFreeList);
+
+       return IMG_TRUE;
+}
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscDumpFreelistPageListKM(
+       PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
+
+       if (dllist_is_empty(&psDevInfo->sFreeListHead))
+       {
+               return PVRSRV_OK;
+       }
+
+       PVR_LOG(("---------------[ Begin Freelist Page List Dump ]------------------"));
+
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       dllist_foreach_node(&psDevInfo->sFreeListHead, _RGXDumpFreeListPageList, IMG_NULL);
+       OSLockRelease(psDevInfo->hLockFreeList);
+
+       PVR_LOG(("----------------[ End Freelist Page List Dump ]-------------------"));
+
+       return PVRSRV_OK;
+
+}
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.h b/drivers/gpu/rogue_m/services/server/devices/rgx/debugmisc_server.h
new file mode 100644 (file)
index 0000000..aa2caa1
--- /dev/null
@@ -0,0 +1,75 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debugging and miscellaneous functions server interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Kernel services functions for debugging and other
+                miscellaneous functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if ! defined(DEBUGMISC_SERVER_H)
+#define DEBUGMISC_SERVER_H
+
+#include <img_defs.h>
+#include <pvrsrv_error.h>
+#include <device.h>
+#include <pmr.h>
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDebugMiscSLCSetBypassStateKM(
+       PVRSRV_DEVICE_NODE *psDeviceNode,
+       IMG_UINT32  uiFlags,
+       IMG_BOOL  bSetBypassed);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDebugMiscInitFWImageKM(
+       PMR *psFWImgDestPMR,
+       PMR *psFWImgSrcPMR,
+       IMG_UINT64 ui64FWImgLen,
+       PMR *psFWImgSigPMR,
+       IMG_UINT64 ui64FWSigLen);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetFWLogKM(
+       PVRSRV_DEVICE_NODE *psDeviceNode,
+       IMG_UINT32  ui32RGXFWLogType);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscDumpFreelistPageListKM(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.c
new file mode 100644 (file)
index 0000000..b4e3d7a
--- /dev/null
@@ -0,0 +1,269 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Breakpoint routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX Breakpoint routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "rgxbreakpoint.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgxmem.h"
+#include "device.h"
+#include "sync_internal.h"
+#include "pdump_km.h"
+#include "pvrsrv.h"
+
+PVRSRV_ERROR PVRSRVRGXSetBreakpointKM(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData,
+                                       RGXFWIF_DM              eFWDataMaster,
+                                       IMG_UINT32              ui32BPAddr,
+                                       IMG_UINT32              ui32HandlerAddr,
+                                       IMG_UINT32              ui32DataMaster)
+{
+       DEVMEM_MEMDESC          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sBPCmd;
+       
+       if (psDeviceNode->psDevConfig->bBPSet == IMG_TRUE)
+               return PVRSRV_ERROR_BP_ALREADY_SET;
+       
+       sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP;
+       sBPCmd.uCmdData.sBPData.ui32BPAddr = ui32BPAddr;
+       sBPCmd.uCmdData.sBPData.ui32HandlerAddr = ui32HandlerAddr;
+       sBPCmd.uCmdData.sBPData.ui32BPDM = ui32DataMaster;
+       sBPCmd.uCmdData.sBPData.bEnable = IMG_TRUE;
+       sBPCmd.uCmdData.sBPData.ui32Flags = RGXFWIF_BPDATA_FLAGS_WRITE;
+
+       RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, 
+                               psFWMemContextMemDesc, 
+                               0 , 
+                               RFW_FWADDR_NOREF_FLAG);
+               
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               eFWDataMaster,
+                               &sBPCmd,
+                               sizeof(sBPCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetBreakpointKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, eFWDataMaster, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXSetBreakpointKM: Wait for completion aborted with error (%u)", eError));
+               return eError;
+       }
+
+       psDeviceNode->psDevConfig->eBPDM = eFWDataMaster;
+       psDeviceNode->psDevConfig->bBPSet = IMG_TRUE;
+       
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXClearBreakpointKM(PVRSRV_DEVICE_NODE     *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData)
+{
+       DEVMEM_MEMDESC          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sBPCmd;
+       RGXFWIF_DM                      eDataMaster = psDeviceNode->psDevConfig->eBPDM;
+       
+       sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP;
+       sBPCmd.uCmdData.sBPData.ui32BPAddr = 0;
+       sBPCmd.uCmdData.sBPData.ui32HandlerAddr = 0;
+       sBPCmd.uCmdData.sBPData.bEnable = IMG_FALSE;
+       sBPCmd.uCmdData.sBPData.ui32Flags = RGXFWIF_BPDATA_FLAGS_WRITE | RGXFWIF_BPDATA_FLAGS_CTL;
+       
+       RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, 
+                               psFWMemContextMemDesc, 
+                               0 , 
+                               RFW_FWADDR_NOREF_FLAG);
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               eDataMaster,
+                               &sBPCmd,
+                               sizeof(sBPCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXClearBreakpointKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, eDataMaster, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXClearBreakpointKM: Wait for completion aborted with error (%u)", eError));
+               return eError;
+       }
+
+       psDeviceNode->psDevConfig->bBPSet = IMG_FALSE;
+       
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXEnableBreakpointKM(PVRSRV_DEVICE_NODE    *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData)
+{
+       DEVMEM_MEMDESC          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sBPCmd;
+       RGXFWIF_DM                      eDataMaster = psDeviceNode->psDevConfig->eBPDM;
+       
+       if (psDeviceNode->psDevConfig->bBPSet == IMG_FALSE)
+               return PVRSRV_ERROR_BP_NOT_SET;
+       
+       sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP;
+       sBPCmd.uCmdData.sBPData.bEnable = IMG_TRUE;
+       sBPCmd.uCmdData.sBPData.ui32Flags = RGXFWIF_BPDATA_FLAGS_CTL;
+       
+       RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, 
+                               psFWMemContextMemDesc, 
+                               0 , 
+                               RFW_FWADDR_NOREF_FLAG);
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               eDataMaster,
+                               &sBPCmd,
+                               sizeof(sBPCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXEnableBreakpointKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, eDataMaster, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXEnableBreakpointKM: Wait for completion aborted with error (%u)", eError));
+               return eError;
+       }
+       
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXDisableBreakpointKM(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData)
+{
+       DEVMEM_MEMDESC          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sBPCmd;
+       RGXFWIF_DM                      eDataMaster = psDeviceNode->psDevConfig->eBPDM;
+       
+       if (psDeviceNode->psDevConfig->bBPSet == IMG_FALSE)
+               return PVRSRV_ERROR_BP_NOT_SET;
+       
+       sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP;
+       sBPCmd.uCmdData.sBPData.bEnable = IMG_FALSE;
+       sBPCmd.uCmdData.sBPData.ui32Flags = RGXFWIF_BPDATA_FLAGS_CTL;
+       
+       RGXSetFirmwareAddress(&sBPCmd.uCmdData.sBPData.psFWMemContext, 
+                               psFWMemContextMemDesc, 
+                               0 , 
+                               RFW_FWADDR_NOREF_FLAG);
+       
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               eDataMaster,
+                               &sBPCmd,
+                               sizeof(sBPCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXDisableBreakpointKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, eDataMaster, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXDisableBreakpointKM: Wait for completion aborted with error (%u)", eError));
+               return eError;
+       }
+                               
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXOverallocateBPRegistersKM(PVRSRV_DEVICE_NODE     *psDeviceNode,
+                                       IMG_UINT32              ui32TempRegs,
+                                       IMG_UINT32              ui32SharedRegs)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sBPCmd;
+       
+       sBPCmd.eCmdType = RGXFWIF_KCCB_CMD_BP;
+       sBPCmd.uCmdData.sBPData.ui32Flags = RGXFWIF_BPDATA_FLAGS_REGS;
+       sBPCmd.uCmdData.sBPData.ui32TempRegs = ui32TempRegs;
+       sBPCmd.uCmdData.sBPData.ui32SharedRegs = ui32SharedRegs;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sBPCmd,
+                               sizeof(sBPCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXOverallocateBPRegistersKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXOverallocateBPRegistersKM: Wait for completion aborted with error (%u)", eError));
+               return eError;
+       }
+
+       return eError;
+}
+
+
+/******************************************************************************
+ End of file (rgxbreakpoint.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxbreakpoint.h
new file mode 100644 (file)
index 0000000..44792d6
--- /dev/null
@@ -0,0 +1,136 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX breakpoint functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX breakpoint functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXBREAKPOINT_H__)
+#define __RGXBREAKPOINT_H__
+
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_km.h"
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXSetBreakpointKM
+
+ @Description
+       Server-side implementation of RGXSetBreakpoint
+
+ @Input psDeviceNode - RGX Device node
+ @Input eDataMaster - Data Master to schedule command for
+ @Input hMemCtxPrivData - memory context private data
+ @Input ui32BPAddr - Address of breakpoint
+ @Input ui32HandlerAddr - Address of breakpoint handler
+ @Input ui32BPCtl - Breakpoint controls
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXSetBreakpointKM(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData,
+                                       RGXFWIF_DM              eFWDataMaster,
+                                       IMG_UINT32              ui32BPAddr,
+                                       IMG_UINT32              ui32HandlerAddr,
+                                       IMG_UINT32              ui32DataMaster);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXClearBreakpointKM
+
+ @Description
+       Server-side implementation of RGXClearBreakpoint
+
+ @Input psDeviceNode - RGX Device node
+ @Input hMemCtxPrivData - memory context private data
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXClearBreakpointKM(PVRSRV_DEVICE_NODE     *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXEnableBreakpointKM
+
+ @Description
+       Server-side implementation of RGXEnableBreakpoint
+
+ @Input psDeviceNode - RGX Device node
+ @Input hMemCtxPrivData - memory context private data
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXEnableBreakpointKM(PVRSRV_DEVICE_NODE    *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXDisableBreakpointKM
+
+ @Description
+       Server-side implementation of RGXDisableBreakpoint
+
+ @Input psDeviceNode - RGX Device node
+ @Input hMemCtxPrivData - memory context private data
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXDisableBreakpointKM(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                       IMG_HANDLE              hMemCtxPrivData);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXOverallocateBPRegistersKM
+
+ @Description
+       Server-side implementation of RGXOverallocateBPRegisters
+
+ @Input psDeviceNode - RGX Device node
+ @Input ui32TempRegs - Number of temporary registers to overallocate
+ @Input ui32SharedRegs - Number of shared registers to overallocate
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/                                        
+PVRSRV_ERROR PVRSRVRGXOverallocateBPRegistersKM(PVRSRV_DEVICE_NODE     *psDeviceNode,
+                                       IMG_UINT32              ui32TempRegs,
+                                       IMG_UINT32              ui32SharedRegs);
+#endif /* __RGXBREAKPOINT_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.c
new file mode 100644 (file)
index 0000000..bc1ba9c
--- /dev/null
@@ -0,0 +1,1660 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX CCB routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX CCB routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvr_debug.h"
+#include "rgxdevice.h"
+#include "pdump_km.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "rgxfwutils.h"
+#include "osfunc.h"
+#include "rgxccb.h"
+#include "rgx_memallocflags.h"
+#include "devicemem_pdump.h"
+#include "pvr_debug.h"
+#include "dllist.h"
+#include "rgx_fwif_shared.h"
+#include "rgxtimerquery.h"
+#if defined(LINUX)
+#include "trace_events.h"
+#endif
+
+/*
+ *  Defines the number of fence updates to record so that future fences in the CCB
+ *  can be checked to see if they are already known to be satisfied. The value has
+ *  implications for memory and host CPU usage and so should be tuned by using
+ *  firmware performance measurements to trade these off against performance gains.
+ *
+ *  Must be a power of 2!
+ */
+#define RGX_CCCB_FENCE_UPDATE_LIST_SIZE  (64)
+
+
+struct _RGX_CLIENT_CCB_ {
+       volatile RGXFWIF_CCCB_CTL       *psClientCCBCtrl;                       /*!< CPU mapping of the CCB control structure used by the fw */
+       IMG_UINT8                                       *pui8ClientCCB;                         /*!< CPU mapping of the CCB */
+       DEVMEM_MEMDESC                          *psClientCCBMemDesc;            /*!< MemDesc for the CCB */
+       DEVMEM_MEMDESC                          *psClientCCBCtrlMemDesc;                /*!< MemDesc for the CCB control */
+       IMG_UINT32                                      ui32HostWriteOffset;            /*!< CCB write offset from the driver side */
+       IMG_UINT32                                      ui32LastPDumpWriteOffset;                       /*!< CCB write offset from the last time we submitted a command in capture range */
+       IMG_UINT32                                      ui32LastROff;                           /*!< Last CCB Read offset to help detect any CCB wedge */
+       IMG_UINT32                                      ui32LastWOff;                           /*!< Last CCB Write offset to help detect any CCB wedge */
+       IMG_UINT32                                      ui32ByteCount;                          /*!< Count of the number of bytes written to CCCB */
+       IMG_UINT32                                      ui32LastByteCount;                      /*!< Last value of ui32ByteCount to help detect any CCB wedge */
+       IMG_UINT32                                      ui32Size;                                       /*!< Size of the CCB */
+       DLLIST_NODE                                     sNode;                                          /*!< Node used to store this CCB on the per connection list */
+       PDUMP_CONNECTION_DATA           *psPDumpConnectionData;         /*!< Pointer to the per connection data in which we reside */
+       IMG_PVOID                                       hTransition;                            /*!< Handle for Transition callback */
+       IMG_CHAR                                        szName[MAX_CLIENT_CCB_NAME];/*!< Name of this client CCB */
+       RGX_SERVER_COMMON_CONTEXT   *psServerCommonContext;     /*!< Parent server common context that this CCB belongs to */
+#if defined REDUNDANT_SYNCS_DEBUG
+       IMG_UINT32                                      ui32UpdateWriteIndex;           /*!< Next position to overwrite in Fence Update List */
+       RGXFWIF_UFO                                     asFenceUpdateList[RGX_CCCB_FENCE_UPDATE_LIST_SIZE];  /*!< Cache of recent updates written in this CCB */
+#endif
+};
+
+static PVRSRV_ERROR _RGXCCBPDumpTransition(IMG_PVOID *pvData, IMG_BOOL bInto, IMG_BOOL bContinuous)
+{
+       RGX_CLIENT_CCB *psClientCCB = (RGX_CLIENT_CCB *) pvData;
+       
+       IMG_UINT32 ui32PDumpFlags = bContinuous ? PDUMP_FLAGS_CONTINUOUS:0;
+
+       /*
+               We're about to Transition into capture range and we've submitted
+               new commands since the last time we entered capture range so drain
+               the CCB as required
+       */
+       if (bInto)
+       {
+               volatile RGXFWIF_CCCB_CTL *psCCBCtl = psClientCCB->psClientCCBCtrl;
+               PVRSRV_ERROR eError;
+
+               /*
+                       Wait for the FW to catch up (retry will get pushed back out services
+                       client where we wait on the event object and try again later)
+               */
+               if (psClientCCB->psClientCCBCtrl->ui32ReadOffset != psClientCCB->ui32HostWriteOffset)
+               {
+                       return PVRSRV_ERROR_RETRY;
+               }
+
+               /*
+                       We drain whenever capture range is entered. Even if no commands
+                       have been issued while where out of capture range we have to wait for
+                       operations that we might have issued in the last capture range
+                       to finish so the sync prim update that will happen after all the
+                       PDumpTransition callbacks have been called doesn't clobber syncs
+                       which the FW is currently working on.
+                       Although this is suboptimal, while out of capture range for every
+                       persistent operation we serialise the PDump script processing and
+                       the FW, there is no easy solution.
+                       Not all modules that work on syncs register a PDumpTransition and
+                       thus we have no way of knowing if we can skip drain and the sync
+                       prim dump or not.
+               */
+               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags,
+                                                         "cCCB(%s@%p): Draining rgxfw_roff == woff (%d)",
+                                                         psClientCCB->szName,
+                                                         psClientCCB,
+                                                         psClientCCB->ui32LastPDumpWriteOffset);
+
+               eError = DevmemPDumpDevmemPol32(psClientCCB->psClientCCBCtrlMemDesc,
+                                                                               offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset),
+                                                                               psClientCCB->ui32LastPDumpWriteOffset,
+                                                                               0xffffffff,
+                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                               ui32PDumpFlags);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "_RGXCCBPDumpTransition: problem pdumping POL for cCCBCtl (%d)", eError));
+               }
+               PVR_ASSERT(eError == PVRSRV_OK);
+
+               /*
+                       If new command(s) have been written out of capture range then we
+                       need to fast forward past uncaptured operations.
+               */
+               if (psClientCCB->ui32LastPDumpWriteOffset != psClientCCB->ui32HostWriteOffset)
+               {
+                       /*
+                               There are commands that where not captured so after the
+                               simulation drain (above) we also need to fast-forward pass
+                               those commands so the FW can start with the 1st command
+                               which is in the new capture range
+                        */
+                       psCCBCtl->ui32ReadOffset = psClientCCB->ui32HostWriteOffset;
+                       psCCBCtl->ui32DepOffset = psClientCCB->ui32HostWriteOffset;
+                       psCCBCtl->ui32WriteOffset = psClientCCB->ui32HostWriteOffset;
+       
+                       PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags,
+                                                                 "cCCB(%s@%p): Fast-forward from %d to %d",
+                                                                 psClientCCB->szName,
+                                                                 psClientCCB,
+                                                                 psClientCCB->ui32LastPDumpWriteOffset,
+                                                                 psClientCCB->ui32HostWriteOffset);
+       
+                       DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc,
+                                                          0,
+                                                          sizeof(RGXFWIF_CCCB_CTL),
+                                                          ui32PDumpFlags);
+                                                          
+                       /*
+                               Although we've entered capture range we might not do any work
+                               on this CCB so update the ui32LastPDumpWriteOffset to reflect
+                               where we got to for next so we start the drain from where we
+                               got to last time
+                       */
+                       psClientCCB->ui32LastPDumpWriteOffset = psClientCCB->ui32HostWriteOffset;
+               }
+       }
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RGXCreateCCB(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                 IMG_UINT32                    ui32CCBSizeLog2,
+                                                 CONNECTION_DATA               *psConnectionData,
+                                                 const IMG_CHAR                *pszName,
+                                                 RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
+                                                 RGX_CLIENT_CCB                **ppsClientCCB,
+                                                 DEVMEM_MEMDESC                **ppsClientCCBMemDesc,
+                                                 DEVMEM_MEMDESC                **ppsClientCCBCtrlMemDesc)
+{
+       PVRSRV_ERROR    eError;
+       DEVMEM_FLAGS_T  uiClientCCBMemAllocFlags, uiClientCCBCtlMemAllocFlags;
+       IMG_UINT32              ui32AllocSize = (1U << ui32CCBSizeLog2);
+       RGX_CLIENT_CCB  *psClientCCB;
+
+       psClientCCB = OSAllocMem(sizeof(*psClientCCB));
+       if (psClientCCB == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+       psClientCCB->psServerCommonContext = psServerCommonContext;
+
+       uiClientCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                   PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE;
+
+       uiClientCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                               /* FIXME: Client CCB Ctl should be read-only for the CPU 
+                                                                       (it is not because for now we initialize it from the host) */
+                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | 
+                                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE;
+
+       PDUMPCOMMENT("Allocate RGXFW cCCB");
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               ui32AllocSize,
+                                                                               uiClientCCBMemAllocFlags,
+                                                                               "FirmwareClientCCB",
+                                                                               &psClientCCB->psClientCCBMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to allocate RGX client CCB (%s)",
+                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_alloc_ccb;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBMemDesc,
+                                                                         (IMG_VOID **) &psClientCCB->pui8ClientCCB);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to map RGX client CCB (%s)",
+                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_map_ccb;
+       }
+
+       PDUMPCOMMENT("Allocate RGXFW cCCB control");
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               sizeof(RGXFWIF_CCCB_CTL),
+                                                                               uiClientCCBCtlMemAllocFlags,
+                                                                               "FirmwareClientCCBControl",
+                                                                               &psClientCCB->psClientCCBCtrlMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to allocate RGX client CCB control (%s)",
+                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_alloc_ccbctrl;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc,
+                                                                         (IMG_VOID **) &psClientCCB->psClientCCBCtrl);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to map RGX client CCB (%s)",
+                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_map_ccbctrl;
+       }
+
+       psClientCCB->psClientCCBCtrl->ui32WriteOffset = 0;
+       psClientCCB->psClientCCBCtrl->ui32ReadOffset = 0;
+       psClientCCB->psClientCCBCtrl->ui32DepOffset = 0;
+       psClientCCB->psClientCCBCtrl->ui32WrapMask = ui32AllocSize - 1;
+       OSSNPrintf(psClientCCB->szName, MAX_CLIENT_CCB_NAME, "%s-P%lu-T%lu-%s",
+                                                                       pszName,
+                                                                       (unsigned long) OSGetCurrentProcessID(),
+                                                                       (unsigned long) OSGetCurrentThreadID(),
+                                                                       OSGetCurrentProcessName());
+
+       PDUMPCOMMENT("cCCB control");
+       DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc,
+                                          0,
+                                          sizeof(RGXFWIF_CCCB_CTL),
+                                          PDUMP_FLAGS_CONTINUOUS);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       psClientCCB->ui32HostWriteOffset = 0;
+       psClientCCB->ui32LastPDumpWriteOffset = 0;
+       psClientCCB->ui32Size = ui32AllocSize;
+       psClientCCB->ui32LastROff = ui32AllocSize - 1;
+       psClientCCB->ui32ByteCount = 0;
+       psClientCCB->ui32LastByteCount = 0;
+
+#if defined REDUNDANT_SYNCS_DEBUG
+       psClientCCB->ui32UpdateWriteIndex = 0;
+       OSMemSet(psClientCCB->asFenceUpdateList, 0, sizeof(psClientCCB->asFenceUpdateList));
+#endif
+
+       eError = PDumpRegisterTransitionCallback(psConnectionData->psPDumpConnectionData,
+                                                                                         _RGXCCBPDumpTransition,
+                                                                                         psClientCCB,
+                                                                                         &psClientCCB->hTransition);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_pdumpreg;
+       }
+
+       /*
+        * Note:
+        * Save the PDump specific structure, which is ref counted unlike
+        * the connection data, to ensure it's not freed too early
+        */
+       psClientCCB->psPDumpConnectionData = psConnectionData->psPDumpConnectionData;
+       PDUMPCOMMENT("New RGXFW cCCB(%s@%p) created",
+                                psClientCCB->szName,
+                                psClientCCB);
+
+       *ppsClientCCB = psClientCCB;
+       *ppsClientCCBMemDesc = psClientCCB->psClientCCBMemDesc;
+       *ppsClientCCBCtrlMemDesc = psClientCCB->psClientCCBCtrlMemDesc;
+       return PVRSRV_OK;
+
+fail_pdumpreg:
+       DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc);
+fail_map_ccbctrl:
+       DevmemFwFree(psClientCCB->psClientCCBCtrlMemDesc);
+fail_alloc_ccbctrl:
+       DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc);
+fail_map_ccb:
+       DevmemFwFree(psClientCCB->psClientCCBMemDesc);
+fail_alloc_ccb:
+       OSFreeMem(psClientCCB);
+fail_alloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+IMG_VOID RGXDestroyCCB(RGX_CLIENT_CCB *psClientCCB)
+{
+       PDumpUnregisterTransitionCallback(psClientCCB->hTransition);
+       DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc);
+       DevmemFwFree(psClientCCB->psClientCCBCtrlMemDesc);
+       DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc);
+       DevmemFwFree(psClientCCB->psClientCCBMemDesc);
+       OSFreeMem(psClientCCB);
+}
+
+
+static PVRSRV_ERROR _RGXAcquireCCB(RGX_CLIENT_CCB      *psClientCCB,
+                                                                  IMG_UINT32           ui32CmdSize,
+                                                                  IMG_PVOID            *ppvBufferSpace)
+{
+       IMG_UINT32 ui32FreeSpace;
+
+#if defined(PDUMP)
+       /* Wait for sufficient CCB space to become available */
+       PDUMPCOMMENTWITHFLAGS(0, "Wait for %u bytes to become available according cCCB Ctl (woff=%x) for %s",
+                                                       ui32CmdSize, psClientCCB->ui32HostWriteOffset,
+                                                       psClientCCB->szName);
+       DevmemPDumpCBP(psClientCCB->psClientCCBCtrlMemDesc,
+                      offsetof(RGXFWIF_CCCB_CTL, ui32ReadOffset),
+                      psClientCCB->ui32HostWriteOffset,
+                      ui32CmdSize,
+                      psClientCCB->ui32Size);
+#endif
+
+       ui32FreeSpace = GET_CCB_SPACE(psClientCCB->ui32HostWriteOffset,
+                                                                 psClientCCB->psClientCCBCtrl->ui32ReadOffset,
+                                                                 psClientCCB->ui32Size);
+
+       /* Don't allow all the space to be used */
+       if (ui32FreeSpace > ui32CmdSize)
+       {
+               *ppvBufferSpace = (IMG_PVOID) (psClientCCB->pui8ClientCCB +
+                                                                          psClientCCB->ui32HostWriteOffset);
+               return PVRSRV_OK;
+       }
+
+       return PVRSRV_ERROR_RETRY;
+}
+
+/******************************************************************************
+ FUNCTION      : RGXAcquireCCB
+
+ PURPOSE       : Obtains access to write some commands to a CCB
+
+ PARAMETERS    : psClientCCB           - The client CCB
+                         ui32CmdSize           - How much space is required
+                         ppvBufferSpace        - Pointer to space in the buffer
+                         bPDumpContinuous  - Should this be PDump continuous?
+
+ RETURNS       : PVRSRV_ERROR
+******************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR RGXAcquireCCB(RGX_CLIENT_CCB *psClientCCB,
+                                                                               IMG_UINT32              ui32CmdSize,
+                                                                               IMG_PVOID               *ppvBufferSpace,
+                                                                               IMG_BOOL                bPDumpContinuous)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32      ui32PDumpFlags  = bPDumpContinuous ? PDUMP_FLAGS_CONTINUOUS : 0;
+       IMG_BOOL        bInCaptureRange;
+       IMG_BOOL        bPdumpEnabled;
+
+       PDumpIsCaptureFrameKM(&bInCaptureRange);
+       bPdumpEnabled = (bInCaptureRange || bPDumpContinuous);
+
+       /*
+               PDumpSetFrame will detect as we Transition into capture range for
+               frame based data but if we are PDumping continuous data then we
+               need to inform the PDump layer ourselves
+       */
+       if (bPDumpContinuous && !bInCaptureRange)
+       {
+               eError = PDumpTransition(psClientCCB->psPDumpConnectionData, IMG_TRUE, IMG_TRUE);
+               if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+       /* Check that the CCB can hold this command + padding */
+       if ((ui32CmdSize + PADDING_COMMAND_SIZE + 1) > psClientCCB->ui32Size)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Command size (%d bytes) too big for CCB (%d bytes)\n",
+                                                               ui32CmdSize, psClientCCB->ui32Size));
+               return PVRSRV_ERROR_CMD_TOO_BIG;
+       }
+
+       /*
+               Check we don't overflow the end of the buffer and make sure we have
+               enough for the padding command.
+       */
+       if ((psClientCCB->ui32HostWriteOffset + ui32CmdSize + PADDING_COMMAND_SIZE) >
+               psClientCCB->ui32Size)
+       {
+               RGXFWIF_CCB_CMD_HEADER *psHeader;
+               IMG_VOID *pvHeader;
+               PVRSRV_ERROR eError;
+               IMG_UINT32 ui32Remain = psClientCCB->ui32Size - psClientCCB->ui32HostWriteOffset;
+
+               /* We're at the end of the buffer without enough contiguous space */
+               eError = _RGXAcquireCCB(psClientCCB,
+                                                               ui32Remain,
+                                                               &pvHeader);
+               if (eError != PVRSRV_OK)
+               {
+                       /*
+                               It's possible no commands have been processed in which case as we
+                               can fail the padding allocation due to that fact we never allow
+                               the client CCB to be full
+                       */
+                       return eError;
+               }
+               psHeader = pvHeader;
+               psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PADDING;
+               psHeader->ui32CmdSize = ui32Remain - sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "cCCB(%p): Padding cmd %d", psClientCCB, psHeader->ui32CmdSize);
+               if (bPdumpEnabled)
+               {
+                       DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc,
+                                                          psClientCCB->ui32HostWriteOffset,
+                                                          ui32Remain,
+                                                          ui32PDumpFlags);
+               }
+                               
+               UPDATE_CCB_OFFSET(psClientCCB->ui32HostWriteOffset,
+                                                 ui32Remain,
+                                                 psClientCCB->ui32Size);
+               psClientCCB->ui32ByteCount += ui32Remain;
+       }
+
+       return _RGXAcquireCCB(psClientCCB,
+                                                 ui32CmdSize,
+                                                 ppvBufferSpace);
+}
+
+/******************************************************************************
+ FUNCTION      : RGXReleaseCCB
+
+ PURPOSE       : Release a CCB that we have been writing to.
+
+ PARAMETERS    : psDevData                     - device data
+                         psCCB                         - the CCB
+
+ RETURNS       : None
+******************************************************************************/
+IMG_INTERNAL IMG_VOID RGXReleaseCCB(RGX_CLIENT_CCB *psClientCCB,
+                                                                       IMG_UINT32              ui32CmdSize,
+                                                                       IMG_BOOL                bPDumpContinuous)
+{
+       IMG_UINT32      ui32PDumpFlags  = bPDumpContinuous ? PDUMP_FLAGS_CONTINUOUS : 0;
+       IMG_BOOL        bInCaptureRange;
+       IMG_BOOL        bPdumpEnabled;
+
+       PDumpIsCaptureFrameKM(&bInCaptureRange);
+       bPdumpEnabled = (bInCaptureRange || bPDumpContinuous);
+
+       /* Dump the CCB data */
+       if (bPdumpEnabled)
+       {
+               DevmemPDumpLoadMem(psClientCCB->psClientCCBMemDesc,
+                                                  psClientCCB->ui32HostWriteOffset,
+                                                  ui32CmdSize,
+                                                  ui32PDumpFlags);
+       }
+       
+       /*
+        *  Check if there have been any fences written that will already be
+        *  satistified by a previously written update in this CCB.
+        */
+#if defined REDUNDANT_SYNCS_DEBUG
+       {
+               IMG_UINT8  *pui8BufferStart = (IMG_PVOID)((IMG_UINTPTR_T)psClientCCB->pui8ClientCCB + psClientCCB->ui32HostWriteOffset);
+               IMG_UINT8  *pui8BufferEnd   = (IMG_PVOID)((IMG_UINTPTR_T)psClientCCB->pui8ClientCCB + psClientCCB->ui32HostWriteOffset + ui32CmdSize);
+
+               /* Walk through the commands in this section of CCB being released... */
+               while (pui8BufferStart < pui8BufferEnd)
+               {
+                       RGXFWIF_CCB_CMD_HEADER  *psCmdHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8BufferStart;
+
+                       if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_UPDATE) /* don't check for unfenced update. Following comment explain why */
+                       {
+                               /* If an UPDATE then record the value incase a later fence depends on it. */
+                               IMG_UINT32  ui32NumUpdates = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO);
+                               IMG_UINT32  i;
+
+                               for (i = 0;  i < ui32NumUpdates;  i++)
+                               {
+                                       RGXFWIF_UFO  *psUFOPtr = ((RGXFWIF_UFO*)(pui8BufferStart + sizeof(RGXFWIF_CCB_CMD_HEADER))) + i;
+                                       
+                                       psClientCCB->asFenceUpdateList[psClientCCB->ui32UpdateWriteIndex++] = *psUFOPtr;
+                                       psClientCCB->ui32UpdateWriteIndex &= (RGX_CCCB_FENCE_UPDATE_LIST_SIZE-1);
+                               }
+                       }
+                       else if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE)
+                       {
+                               IMG_UINT32  ui32NumFences = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO);
+                               IMG_UINT32  i;
+                               
+                               for (i = 0;  i < ui32NumFences;  i++)
+                               {
+                                       RGXFWIF_UFO  *psUFOPtr = ((RGXFWIF_UFO*)(pui8BufferStart + sizeof(RGXFWIF_CCB_CMD_HEADER))) + i;
+                                       IMG_UINT32  ui32UpdateIndex;
+
+                                       /* Check recently queued updates to see if this fence will be satisfied by the time it is checked. */
+                                       for (ui32UpdateIndex = 0;  ui32UpdateIndex < RGX_CCCB_FENCE_UPDATE_LIST_SIZE;  ui32UpdateIndex++)
+                                       {
+                                               RGXFWIF_UFO  *psUpdatePtr = &psClientCCB->asFenceUpdateList[ui32UpdateIndex];
+                                                       
+                                               if (psUFOPtr->puiAddrUFO.ui32Addr == psUpdatePtr->puiAddrUFO.ui32Addr  &&
+                                                       psUFOPtr->ui32Value == psUpdatePtr->ui32Value)
+                                               {
+                                                       PVR_DPF((PVR_DBG_WARNING, "Redundant fence found in cCCB(%p) - 0x%x -> 0x%x",
+                                                                       psClientCCB, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value));
+                                                       //psUFOPtr->puiAddrUFO.ui32Addr = 0;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       else if (psCmdHeader->eCmdType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR)
+                       {
+                               IMG_UINT32  ui32NumFences = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO);
+                               IMG_UINT32  i;
+                               
+                               for (i = 0;  i < ui32NumFences;  i++)
+                               {
+                                       RGXFWIF_UFO  *psUFOPtr = ((RGXFWIF_UFO*)(pui8BufferStart + sizeof(RGXFWIF_CCB_CMD_HEADER))) + i;
+                                       IMG_UINT32  ui32UpdateIndex;
+                                                       
+                                       /* Check recently queued updates to see if this fence will be satisfied by the time it is checked. */
+                                       for (ui32UpdateIndex = 0;  ui32UpdateIndex < RGX_CCCB_FENCE_UPDATE_LIST_SIZE;  ui32UpdateIndex++)
+                                       {
+                                               RGXFWIF_UFO  *psUpdatePtr = &psClientCCB->asFenceUpdateList[ui32UpdateIndex];
+                                               
+                                               /*
+                                                *  The PR-fence will be met if the update value is >= the required fence value. E.g.
+                                                *  the difference between the update value and fence value is positive.
+                                                */
+                                               if (psUFOPtr->puiAddrUFO.ui32Addr == psUpdatePtr->puiAddrUFO.ui32Addr  &&
+                                                       ((psUpdatePtr->ui32Value - psUFOPtr->ui32Value) & (1U << 31)) == 0)
+                                               {
+                                                       PVR_DPF((PVR_DBG_WARNING, "Redundant PR fence found in cCCB(%p) - 0x%x -> 0x%x",
+                                                                       psClientCCB, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value));
+                                                       //psUFOPtr->puiAddrUFO.ui32Addr = 0;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       /* Move to the next command in this section of CCB being released... */
+                       pui8BufferStart += sizeof(RGXFWIF_CCB_CMD_HEADER) + psCmdHeader->ui32CmdSize;
+               }
+       }
+#endif /* REDUNDANT_SYNCS_DEBUG */
+
+       /*
+        * Update the CCB write offset.
+        */
+       UPDATE_CCB_OFFSET(psClientCCB->ui32HostWriteOffset,
+                                         ui32CmdSize,
+                                         psClientCCB->ui32Size);
+       psClientCCB->ui32ByteCount += ui32CmdSize;
+
+       /*
+               PDumpSetFrame will detect as we Transition out of capture range for
+               frame based data but if we are PDumping continuous data then we
+               need to inform the PDump layer ourselves
+       */
+       if (bPDumpContinuous && !bInCaptureRange)
+       {
+               PVRSRV_ERROR eError;
+
+               /* Only Transitioning into capture range can cause an error */
+               eError = PDumpTransition(psClientCCB->psPDumpConnectionData, IMG_FALSE, IMG_TRUE);
+               PVR_ASSERT(eError == PVRSRV_OK);
+       }
+
+       if (bPdumpEnabled)
+       {
+               /* Update the PDump write offset to show we PDumped this command */
+               psClientCCB->ui32LastPDumpWriteOffset = psClientCCB->ui32HostWriteOffset;
+       }
+
+#if defined(NO_HARDWARE)
+       /*
+               The firmware is not running, it cannot update these; we do here instead.
+       */
+       psClientCCB->psClientCCBCtrl->ui32ReadOffset = psClientCCB->ui32HostWriteOffset;
+       psClientCCB->psClientCCBCtrl->ui32DepOffset = psClientCCB->ui32HostWriteOffset;
+#endif
+}
+
+IMG_UINT32 RGXGetHostWriteOffsetCCB(RGX_CLIENT_CCB *psClientCCB)
+{
+       return psClientCCB->ui32HostWriteOffset;
+}
+
+#define SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL PVR_DBG_ERROR
+#define CHECK_COMMAND(cmd, fenceupdate) \
+                               case RGXFWIF_CCB_CMD_TYPE_##cmd: \
+                                               PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, #cmd " command (%d bytes)", psHeader->ui32CmdSize)); \
+                                               bFenceUpdate = fenceupdate; \
+                                               break
+
+static IMG_VOID _RGXClientCCBDumpCommands(RGX_CLIENT_CCB *psClientCCB,
+                                                                                 IMG_UINT32 ui32Offset,
+                                                                                 IMG_UINT32 ui32ByteCount)
+{
+#if defined(SUPPORT_DUMP_CLIENT_CCB_COMMANDS)
+       IMG_UINT8 *pui8Ptr = psClientCCB->pui8ClientCCB + ui32Offset;
+       IMG_UINT32 ui32ConsumeSize = ui32ByteCount;
+
+       while (ui32ConsumeSize)
+       {
+               RGXFWIF_CCB_CMD_HEADER *psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8Ptr;
+               IMG_BOOL bFenceUpdate = IMG_FALSE;
+
+               PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "@offset 0x%08x", pui8Ptr - psClientCCB->pui8ClientCCB));
+               switch(psHeader->eCmdType)
+               {
+                       CHECK_COMMAND(TA, IMG_FALSE);
+                       CHECK_COMMAND(3D, IMG_FALSE);
+                       CHECK_COMMAND(CDM, IMG_FALSE);
+                       CHECK_COMMAND(TQ_3D, IMG_FALSE);
+                       CHECK_COMMAND(TQ_2D, IMG_FALSE);
+                       CHECK_COMMAND(3D_PR, IMG_FALSE);
+                       CHECK_COMMAND(NULL, IMG_FALSE);
+                       CHECK_COMMAND(SHG, IMG_FALSE);
+                       CHECK_COMMAND(RTU, IMG_FALSE);
+                       CHECK_COMMAND(RTU_FC, IMG_FALSE);
+                       CHECK_COMMAND(PRE_TIMESTAMP, IMG_FALSE);
+                       CHECK_COMMAND(POST_TIMESTAMP, IMG_FALSE);
+                       CHECK_COMMAND(FENCE, IMG_TRUE);
+                       CHECK_COMMAND(UPDATE, IMG_TRUE);
+                       CHECK_COMMAND(UNFENCED_UPDATE, IMG_FALSE);
+                       CHECK_COMMAND(RMW_UPDATE, IMG_TRUE);
+                       CHECK_COMMAND(FENCE_PR, IMG_TRUE);
+                       CHECK_COMMAND(UNFENCED_RMW_UPDATE, IMG_FALSE);
+                       CHECK_COMMAND(PADDING, IMG_FALSE);
+                       default:
+                               PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "Unknown command!"));
+                               break;
+               }
+               pui8Ptr += sizeof(*psHeader);
+               if (bFenceUpdate)
+               {
+                       IMG_UINT32 j;
+                       RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *) pui8Ptr;
+                       for (j=0;j<psHeader->ui32CmdSize/sizeof(RGXFWIF_UFO);j++)
+                       {
+                               PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "Addr = 0x%08x, value = 0x%08x",
+                                                       psUFOPtr[j].puiAddrUFO.ui32Addr, psUFOPtr[j].ui32Value));
+                       }
+               }
+               else
+               {
+                       IMG_UINT32 *pui32Ptr = (IMG_UINT32 *) pui8Ptr;
+                       IMG_UINT32 ui32Remain = psHeader->ui32CmdSize/sizeof(IMG_UINT32);
+                       while(ui32Remain)
+                       {
+                               if (ui32Remain >= 4)
+                               {
+                                       PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "0x%08x 0x%08x 0x%08x 0x%08x",
+                                                       pui32Ptr[0], pui32Ptr[1], pui32Ptr[2], pui32Ptr[3]));
+                                       pui32Ptr += 4;
+                                       ui32Remain -= 4;
+                               }
+                               if (ui32Remain == 3)
+                               {
+                                       PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "0x%08x 0x%08x 0x%08x",
+                                                       pui32Ptr[0], pui32Ptr[1], pui32Ptr[2]));
+                                       pui32Ptr += 3;
+                                       ui32Remain -= 3;
+                               }
+                               if (ui32Remain == 2)
+                               {
+                                       PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "0x%08x 0x%08x",
+                                                       pui32Ptr[0], pui32Ptr[1]));
+                                       pui32Ptr += 2;
+                                       ui32Remain -= 2;
+                               }
+                               if (ui32Remain == 1)
+                               {
+                                       PVR_DPF((SUPPORT_DUMP_CLIENT_CCB_COMMANDS_DBG_LEVEL, "0x%08x",
+                                                       pui32Ptr[0]));
+                                       pui32Ptr += 1;
+                                       ui32Remain -= 1;
+                               }
+                       }
+               }
+               pui8Ptr += psHeader->ui32CmdSize;
+               ui32ConsumeSize -= sizeof(*psHeader) + psHeader->ui32CmdSize;
+       }
+#else
+       PVR_UNREFERENCED_PARAMETER(psClientCCB);
+       PVR_UNREFERENCED_PARAMETER(ui32Offset);
+       PVR_UNREFERENCED_PARAMETER(ui32ByteCount);
+#endif
+}
+
+/*
+       Workout how much space this command will require
+*/
+PVRSRV_ERROR RGXCmdHelperInitCmdCCB(RGX_CLIENT_CCB                     *psClientCCB,
+                                    IMG_UINT32                         ui32ClientFenceCount,
+                                    PRGXFWIF_UFO_ADDR          *pauiFenceUFOAddress,
+                                    IMG_UINT32                         *paui32FenceValue,
+                                    IMG_UINT32                         ui32ClientUpdateCount,
+                                    PRGXFWIF_UFO_ADDR          *pauiUpdateUFOAddress,
+                                    IMG_UINT32                         *paui32UpdateValue,
+                                    IMG_UINT32                         ui32ServerSyncCount,
+                                    IMG_UINT32                         *paui32ServerSyncFlags,
+                                    SERVER_SYNC_PRIMITIVE      **papsServerSyncs,
+                                    IMG_UINT32                         ui32CmdSize,
+                                    IMG_PBYTE                          pui8DMCmd,
+                                    RGXFWIF_DEV_VIRTADDR       * ppPreTimestamp,
+                                    RGXFWIF_DEV_VIRTADDR       * ppPostTimestamp,
+                                    PRGXFWIF_UFO_ADDR       * ppRMWUFOAddr,
+                                    RGXFWIF_CCB_CMD_TYPE       eType,
+                                    IMG_BOOL                           bPDumpContinuous,
+                                    IMG_CHAR                           *pszCommandName,
+                                    RGX_CCB_CMD_HELPER_DATA    *psCmdHelperData)
+{
+       IMG_UINT32 ui32FenceCount;
+       IMG_UINT32 ui32UpdateCount;
+       IMG_UINT32 i;
+
+       /* Save the data we require in the submit call */
+       psCmdHelperData->psClientCCB = psClientCCB;
+       psCmdHelperData->bPDumpContinuous = bPDumpContinuous;
+       psCmdHelperData->pszCommandName = pszCommandName;
+
+       /* Client sync data */
+       psCmdHelperData->ui32ClientFenceCount = ui32ClientFenceCount;
+       psCmdHelperData->pauiFenceUFOAddress = pauiFenceUFOAddress;
+       psCmdHelperData->paui32FenceValue = paui32FenceValue;
+       psCmdHelperData->ui32ClientUpdateCount = ui32ClientUpdateCount;
+       psCmdHelperData->pauiUpdateUFOAddress = pauiUpdateUFOAddress;
+       psCmdHelperData->paui32UpdateValue = paui32UpdateValue;
+
+       /* Server sync data */
+       psCmdHelperData->ui32ServerSyncCount = ui32ServerSyncCount;
+       psCmdHelperData->paui32ServerSyncFlags = paui32ServerSyncFlags;
+       psCmdHelperData->papsServerSyncs = papsServerSyncs;
+
+       /* Command data */
+       psCmdHelperData->ui32CmdSize = ui32CmdSize;
+       psCmdHelperData->pui8DMCmd = pui8DMCmd;
+       psCmdHelperData->eType = eType;
+
+       PDUMPCOMMENTWITHFLAGS((bPDumpContinuous) ? PDUMP_FLAGS_CONTINUOUS : 0,
+                       "%s Command Server Init on FWCtx %08x", pszCommandName,
+                       FWCommonContextGetFWAddress(psClientCCB->psServerCommonContext).ui32Addr);
+
+       /* Init the generated data members */
+       psCmdHelperData->ui32ServerFenceCount = 0;
+       psCmdHelperData->ui32ServerUpdateCount = 0;
+       psCmdHelperData->ui32ServerUnfencedUpdateCount = 0;
+       psCmdHelperData->ui32PreTimeStampCmdSize = 0;
+       psCmdHelperData->ui32PostTimeStampCmdSize = 0;
+       psCmdHelperData->ui32RMWUFOCmdSize = 0;
+
+
+       if (ppPreTimestamp && (ppPreTimestamp->ui32Addr != 0))
+       {
+
+               psCmdHelperData->pPreTimestamp           = * ppPreTimestamp;
+               psCmdHelperData->ui32PreTimeStampCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER)
+                       + ((sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN  - 1));
+       }
+
+       if (ppPostTimestamp && (ppPostTimestamp->ui32Addr != 0))
+       {
+               psCmdHelperData->pPostTimestamp           = * ppPostTimestamp;
+               psCmdHelperData->ui32PostTimeStampCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER)
+                       + ((sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN  - 1));
+       }
+
+       if (ppRMWUFOAddr && (ppRMWUFOAddr->ui32Addr != 0))
+       {
+               psCmdHelperData->pRMWUFOAddr       = * ppRMWUFOAddr;
+               psCmdHelperData->ui32RMWUFOCmdSize = sizeof(RGXFWIF_CCB_CMD_HEADER) + sizeof(RGXFWIF_UFO);
+       }
+
+
+       /* Workout how many fences and updates this command will have */
+       for (i = 0; i < ui32ServerSyncCount; i++)
+       {
+               if (paui32ServerSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK)
+               {
+                       /* Server syncs must fence */
+                       psCmdHelperData->ui32ServerFenceCount++;
+               }
+
+               /* If it is an update */
+               if (paui32ServerSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
+               {
+                       /* is it a fenced update or a progresse update (a.k.a unfenced update) ?*/
+                       if ((paui32ServerSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE) == PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE)
+                       {
+                               /* it is a progress update */
+                               psCmdHelperData->ui32ServerUnfencedUpdateCount++;
+                       }
+                       else
+                       {
+                               /* it is a fenced update */
+                               psCmdHelperData->ui32ServerUpdateCount++;
+                       }
+               }
+       }
+
+
+       /* Total fence command size (header plus command data) */
+       ui32FenceCount = ui32ClientFenceCount + psCmdHelperData->ui32ServerFenceCount;
+       if (ui32FenceCount)
+       {
+               psCmdHelperData->ui32FenceCmdSize = RGX_CCB_FWALLOC_ALIGN((ui32FenceCount * sizeof(RGXFWIF_UFO)) +
+                                                                                                                                 sizeof(RGXFWIF_CCB_CMD_HEADER));
+       }
+       else
+       {
+               psCmdHelperData->ui32FenceCmdSize = 0;
+       }
+
+       /* Total DM command size (header plus command data) */
+       psCmdHelperData->ui32DMCmdSize = RGX_CCB_FWALLOC_ALIGN(ui32CmdSize +
+                                                                                                                  sizeof(RGXFWIF_CCB_CMD_HEADER));
+
+       /* Total update command size (header plus command data) */
+       ui32UpdateCount = ui32ClientUpdateCount + psCmdHelperData->ui32ServerUpdateCount;
+       if (ui32UpdateCount)
+       {
+               psCmdHelperData->ui32UpdateCmdSize = RGX_CCB_FWALLOC_ALIGN((ui32UpdateCount * sizeof(RGXFWIF_UFO)) +
+                                                                                                                                  sizeof(RGXFWIF_CCB_CMD_HEADER));
+       }
+       else
+       {
+               psCmdHelperData->ui32UpdateCmdSize = 0;
+       }
+
+       /* Total unfenced update commad size (header plus command data) */ 
+       if (psCmdHelperData->ui32ServerUnfencedUpdateCount != 0)
+       {
+               psCmdHelperData->ui32UnfencedUpdateCmdSize = RGX_CCB_FWALLOC_ALIGN((psCmdHelperData->ui32ServerUnfencedUpdateCount * sizeof(RGXFWIF_UFO)) +
+                                                                                                                                                  sizeof(RGXFWIF_CCB_CMD_HEADER));
+       }
+       else
+       {
+               psCmdHelperData->ui32UnfencedUpdateCmdSize = 0;
+       }
+
+       return PVRSRV_OK;
+}
+
+
+/*
+       Reserve space in the CCB and fill in the command and client sync data
+*/
+PVRSRV_ERROR RGXCmdHelperAcquireCmdCCB(IMG_UINT32 ui32CmdCount,
+                                                                          RGX_CCB_CMD_HELPER_DATA *asCmdHelperData,
+                                                                          IMG_BOOL *pbKickRequired)
+{
+       IMG_UINT32 ui32BeforeWOff = asCmdHelperData[0].psClientCCB->ui32HostWriteOffset;
+       IMG_UINT32 ui32AllocSize = 0;
+       IMG_UINT32 i;
+       IMG_UINT8 *pui8StartPtr;
+       PVRSRV_ERROR eError;
+
+       *pbKickRequired = IMG_FALSE;
+
+       /*
+               Workout how much space we need for all the command(s)
+       */
+       ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData);
+
+
+       for (i = 0; i < ui32CmdCount; i++)
+       {
+               if (asCmdHelperData[0].bPDumpContinuous != asCmdHelperData[i].bPDumpContinuous)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: PDump continuous is not consistent (%s != %s) for command %d",
+                                        __FUNCTION__,
+                                        asCmdHelperData[0].bPDumpContinuous?"IMG_TRUE":"IMG_FALSE",
+                                        asCmdHelperData[i].bPDumpContinuous?"IMG_TRUE":"IMG_FALSE",
+                                        ui32CmdCount));
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+               }
+       }
+
+       /*
+               Acquire space in the CCB for all the command(s).
+       */
+       eError = RGXAcquireCCB(asCmdHelperData[0].psClientCCB,
+                                                  ui32AllocSize,
+                                                  (IMG_PVOID *)&pui8StartPtr,
+                                                  asCmdHelperData[0].bPDumpContinuous);        
+       if (eError != PVRSRV_OK)
+       {
+               /* Failed so bail out and allow the client side to retry */
+               if (asCmdHelperData[0].psClientCCB->ui32HostWriteOffset != ui32BeforeWOff)
+               {
+                       *pbKickRequired = IMG_TRUE;
+               }
+               return eError;
+       }
+
+
+
+       /*
+               For each command fill in the fence, DM, and update command
+
+               Note:
+               We only fill in the client fences here, the server fences (and updates)
+               will be filled in together at the end. This is because we might fail the
+               kernel CCB alloc and would then have to rollback the server syncs if
+               we took the operation here
+       */
+       for (i = 0; i < ui32CmdCount; i++)
+       {
+               RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = & asCmdHelperData[i];
+               IMG_UINT8 *pui8CmdPtr;
+               IMG_UINT8 *pui8ServerFenceStart = 0;
+               IMG_UINT8 *pui8ServerUpdateStart = 0;
+#if defined(PDUMP)
+               IMG_UINT32 ui32CtxAddr = FWCommonContextGetFWAddress(asCmdHelperData->psClientCCB->psServerCommonContext).ui32Addr;
+               IMG_UINT32 ui32CcbWoff = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(asCmdHelperData->psClientCCB->psServerCommonContext));
+#endif
+
+               if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0)
+               {
+                       PDUMPCOMMENT("Start of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes",
+                                       psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff);
+               }
+
+
+
+               /*
+                       Create the fence command.
+               */
+               if (psCmdHelperData->ui32FenceCmdSize)
+               {
+                       RGXFWIF_CCB_CMD_HEADER *psHeader;
+                       IMG_UINT k;
+
+                       /* Fences are at the start of the command */
+                       pui8CmdPtr = pui8StartPtr;
+
+                       psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
+                       psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_FENCE;
+                       psHeader->ui32CmdSize = psCmdHelperData->ui32FenceCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER);
+                       pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+                       /* Fill in the client fences */
+                       for (k = 0; k < psCmdHelperData->ui32ClientFenceCount; k++)
+                       {
+                               RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *) pui8CmdPtr;
+       
+                               psUFOPtr->puiAddrUFO = psCmdHelperData->pauiFenceUFOAddress[k];
+                               psUFOPtr->ui32Value = psCmdHelperData->paui32FenceValue[k];
+                               pui8CmdPtr += sizeof(RGXFWIF_UFO);
+
+#if defined SYNC_COMMAND_DEBUG
+                               PVR_DPF((PVR_DBG_ERROR, "%s client sync fence - 0x%x -> 0x%x",
+                                               psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value));
+#endif
+                               PDUMPCOMMENT(".. %s client sync fence - 0x%x -> 0x%x",
+                                               psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value);
+
+
+                       }
+                       pui8ServerFenceStart = pui8CmdPtr;
+               }
+
+               /* jump over the Server fences */
+               pui8CmdPtr = pui8StartPtr + psCmdHelperData->ui32FenceCmdSize;
+
+
+               /*
+                 Create the pre DM timestamp commands. Pre and Post timestamp commands are supposed to
+                 sandwich the DM cmd. The padding code with the CCB wrap upsets the FW if we don't have
+                 the task type bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types.
+               */
+               if (psCmdHelperData->ui32PreTimeStampCmdSize != 0)
+               {
+                       RGXWriteTimestampCommand(& pui8CmdPtr,
+                                                RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP,
+                                                psCmdHelperData->pPreTimestamp);
+               }
+
+               /*
+                       Create the DM command
+               */
+               if (psCmdHelperData->ui32DMCmdSize)
+               {
+                       RGXFWIF_CCB_CMD_HEADER *psHeader;
+
+                       psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
+                       psHeader->eCmdType = psCmdHelperData->eType;
+                       psHeader->ui32CmdSize = psCmdHelperData->ui32DMCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+
+
+                       pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+
+                       OSMemCopy(pui8CmdPtr, psCmdHelperData->pui8DMCmd, psCmdHelperData->ui32CmdSize);
+                       pui8CmdPtr += psCmdHelperData->ui32CmdSize;
+               }
+
+
+
+               if (psCmdHelperData->ui32PostTimeStampCmdSize != 0)
+               {
+                       RGXWriteTimestampCommand(& pui8CmdPtr,
+                                                RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP,
+                                                psCmdHelperData->pPostTimestamp);
+               }
+
+
+               if (psCmdHelperData->ui32RMWUFOCmdSize != 0)
+               {
+                       RGXFWIF_CCB_CMD_HEADER * psHeader;
+                       RGXFWIF_UFO            * psUFO;
+
+                       psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
+                       psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE;
+                       psHeader->ui32CmdSize = psCmdHelperData->ui32RMWUFOCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER);
+                       pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+                       psUFO = (RGXFWIF_UFO *) pui8CmdPtr;
+                       psUFO->puiAddrUFO = psCmdHelperData->pRMWUFOAddr;
+                       
+                       pui8CmdPtr += sizeof(RGXFWIF_UFO);
+               }
+       
+
+               /*
+                       Create the update command.
+                       
+                       Note:
+                       We only fill in the client updates here, the server updates (and fences)
+                       will be filled in together at the end
+               */
+               if (psCmdHelperData->ui32UpdateCmdSize)
+               {
+                       RGXFWIF_CCB_CMD_HEADER *psHeader;
+                       IMG_UINT k;
+
+                       psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
+                       psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_UPDATE;
+                       psHeader->ui32CmdSize = psCmdHelperData->ui32UpdateCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER);
+                       pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+                       /* Fill in the client updates */
+                       for (k = 0; k < psCmdHelperData->ui32ClientUpdateCount; k++)
+                       {
+                               RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *) pui8CmdPtr;
+       
+                               psUFOPtr->puiAddrUFO = psCmdHelperData->pauiUpdateUFOAddress[k];
+                               psUFOPtr->ui32Value = psCmdHelperData->paui32UpdateValue[k];
+                               pui8CmdPtr += sizeof(RGXFWIF_UFO);
+
+#if defined SYNC_COMMAND_DEBUG
+                               PVR_DPF((PVR_DBG_ERROR, "%s client sync update - 0x%x -> 0x%x",
+                                               psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value));
+#endif
+                               PDUMPCOMMENT(".. %s client sync update - 0x%x -> 0x%x",
+                                               psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value);
+
+                       }
+                       pui8ServerUpdateStart = pui8CmdPtr;
+               }
+       
+               /* Save the server sync fence & update offsets for submit time */
+               psCmdHelperData->pui8ServerFenceStart  = pui8ServerFenceStart;
+               psCmdHelperData->pui8ServerUpdateStart = pui8ServerUpdateStart;
+
+               /* jump over the fenced update */
+               if (psCmdHelperData->ui32UnfencedUpdateCmdSize != 0)
+               {
+                       RGXFWIF_CCB_CMD_HEADER * const psHeader = (RGXFWIF_CCB_CMD_HEADER * ) psCmdHelperData->pui8ServerUpdateStart + psCmdHelperData->ui32UpdateCmdSize;
+                       /* set up the header for unfenced updates,  */
+                       PVR_ASSERT(psHeader); /* Could be zero if ui32UpdateCmdSize is 0 which is never expected */
+                       psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE;
+                       psHeader->ui32CmdSize = psCmdHelperData->ui32UnfencedUpdateCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER);
+               
+                       /* jump over the header */
+                       psCmdHelperData->pui8ServerUnfencedUpdateStart = ((IMG_UINT8*) psHeader) + sizeof(RGXFWIF_CCB_CMD_HEADER);
+               }
+               else
+               {
+                       psCmdHelperData->pui8ServerUnfencedUpdateStart = IMG_NULL;
+               }
+               
+               /* Save start for sanity checking at submit time */
+               psCmdHelperData->pui8StartPtr = pui8StartPtr;
+
+               /* Set the start pointer for the next iteration around the loop */
+               pui8StartPtr +=
+                       psCmdHelperData->ui32FenceCmdSize         +
+                       psCmdHelperData->ui32PreTimeStampCmdSize  +
+                       psCmdHelperData->ui32DMCmdSize            +
+                       psCmdHelperData->ui32PostTimeStampCmdSize +
+                       psCmdHelperData->ui32RMWUFOCmdSize        + 
+                       psCmdHelperData->ui32UpdateCmdSize        +
+                       psCmdHelperData->ui32UnfencedUpdateCmdSize;
+
+               if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0)
+               {
+                       PDUMPCOMMENT("End of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes",
+                                       psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff);
+               }
+               else
+               {
+                       PDUMPCOMMENT("No %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes",
+                                       psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff);
+               }
+       }
+
+       *pbKickRequired = IMG_TRUE;
+       return PVRSRV_OK;
+}
+
+/*
+       Fill in the server syncs data and release the CCB space
+*/
+IMG_VOID RGXCmdHelperReleaseCmdCCB(IMG_UINT32 ui32CmdCount,
+                                                                  RGX_CCB_CMD_HELPER_DATA *asCmdHelperData,
+                                                                  const IMG_CHAR *pcszDMName,
+                                                                  IMG_UINT32 ui32CtxAddr)
+{
+       IMG_UINT32 ui32AllocSize = 0;
+       IMG_UINT32 i;
+
+       /*
+               Workout how much space we need for all the command(s)
+       */
+       ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData);
+
+   /*
+               For each command fill in the server sync info
+       */
+       for (i=0;i<ui32CmdCount;i++)
+       {
+               RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = &asCmdHelperData[i];
+               IMG_UINT8 *pui8ServerFenceStart = psCmdHelperData->pui8ServerFenceStart;
+               IMG_UINT8 *pui8ServerUpdateStart = psCmdHelperData->pui8ServerUpdateStart;
+               IMG_UINT8 *pui8ServerUnfencedUpdateStart = psCmdHelperData->pui8ServerUnfencedUpdateStart;              
+               IMG_UINT32 j;
+
+               /* Now fill in the server fence and updates together */
+               for (j = 0; j < psCmdHelperData->ui32ServerSyncCount; j++)
+               {
+                       RGXFWIF_UFO *psUFOPtr;
+                       IMG_UINT32 ui32UpdateValue;
+                       IMG_UINT32 ui32FenceValue;
+                       PVRSRV_ERROR eError;
+                       IMG_BOOL bFence = ((psCmdHelperData->paui32ServerSyncFlags[j] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK)!=0)?IMG_TRUE:IMG_FALSE;
+                       IMG_BOOL bUpdate = ((psCmdHelperData->paui32ServerSyncFlags[j] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)!=0)?IMG_TRUE:IMG_FALSE;
+                       const IMG_BOOL bUnfencedUpdate = ((psCmdHelperData->paui32ServerSyncFlags[j] & PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE) == PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE)
+                               ? IMG_TRUE
+                               : IMG_FALSE;
+
+                       eError = PVRSRVServerSyncQueueHWOpKM(psCmdHelperData->papsServerSyncs[j],
+                                                                                                bUpdate,
+                                                                                                &ui32FenceValue,
+                                                                                                &ui32UpdateValue);
+                       /* This function can't fail */
+                       PVR_ASSERT(eError == PVRSRV_OK);
+       
+                       /*
+                               As server syncs always fence (we have a check in RGXCmcdHelperInitCmdCCB
+                               which ensures the client is playing ball) the filling in of the fence
+                               is unconditional.
+                       */
+                       if (bFence)
+                       {
+                               PVR_ASSERT(pui8ServerFenceStart != 0);
+
+                               psUFOPtr = (RGXFWIF_UFO *) pui8ServerFenceStart;
+                               psUFOPtr->puiAddrUFO.ui32Addr = ServerSyncGetFWAddr(psCmdHelperData->papsServerSyncs[j]);
+                               psUFOPtr->ui32Value = ui32FenceValue;
+                               pui8ServerFenceStart += sizeof(RGXFWIF_UFO);
+
+#if defined(LINUX)
+                               trace_rogue_fence_checks(psCmdHelperData->pszCommandName,
+                                                                                pcszDMName,
+                                                                                ui32CtxAddr,
+                                                                                psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize,
+                                                                                1,
+                                                                                &psUFOPtr->puiAddrUFO,
+                                                                                &psUFOPtr->ui32Value);
+#endif
+                       }
+       
+                       /* If there is an update then fill that in as well */
+                       if (bUpdate)
+                       {
+                               if (bUnfencedUpdate)
+                               {
+                                       PVR_ASSERT(pui8ServerUnfencedUpdateStart != 0);
+
+                                       psUFOPtr = (RGXFWIF_UFO *) pui8ServerUnfencedUpdateStart;
+                                       psUFOPtr->puiAddrUFO.ui32Addr = ServerSyncGetFWAddr(psCmdHelperData->papsServerSyncs[j]);
+                                       psUFOPtr->ui32Value = ui32UpdateValue;
+                                       pui8ServerUnfencedUpdateStart += sizeof(RGXFWIF_UFO);
+                               }
+                               else
+                               {
+                                       /* fenced update */
+                                       PVR_ASSERT(pui8ServerUpdateStart != 0);
+
+                                       psUFOPtr = (RGXFWIF_UFO *) pui8ServerUpdateStart;
+                                       psUFOPtr->puiAddrUFO.ui32Addr = ServerSyncGetFWAddr(psCmdHelperData->papsServerSyncs[j]);
+                                       psUFOPtr->ui32Value = ui32UpdateValue;
+                                       pui8ServerUpdateStart += sizeof(RGXFWIF_UFO);
+                               }
+#if defined(LINUX)
+                               trace_rogue_fence_updates(psCmdHelperData->pszCommandName,
+                                                                                 pcszDMName,
+                                                                                 ui32CtxAddr,
+                                                                                 psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize,
+                                                                                 1,
+                                                                                 &psUFOPtr->puiAddrUFO,
+                                                                                 &psUFOPtr->ui32Value);
+#endif
+                               
+#if defined(NO_HARDWARE)
+                               /*
+                                 There is no FW so the host has to do any Sync updates
+                                 (client sync updates are done in the client
+                               */
+                               PVRSRVServerSyncPrimSetKM(psCmdHelperData->papsServerSyncs[j], ui32UpdateValue);
+#endif
+                       }
+               }
+
+#if defined(LINUX)
+               trace_rogue_fence_checks(psCmdHelperData->pszCommandName,
+                                                                pcszDMName,
+                                                                ui32CtxAddr,
+                                                                psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize,
+                                                                psCmdHelperData->ui32ClientFenceCount,
+                                                                psCmdHelperData->pauiFenceUFOAddress,
+                                                                psCmdHelperData->paui32FenceValue);
+               trace_rogue_fence_updates(psCmdHelperData->pszCommandName,
+                                                                 pcszDMName,
+                                                                 ui32CtxAddr,
+                                                                 psCmdHelperData->psClientCCB->ui32HostWriteOffset + ui32AllocSize,
+                                                                 psCmdHelperData->ui32ClientUpdateCount,
+                                                                 psCmdHelperData->pauiUpdateUFOAddress,
+                                                                 psCmdHelperData->paui32UpdateValue);
+#endif
+
+               if (psCmdHelperData->ui32ServerSyncCount)
+               {
+                       /*
+                               Do some sanity checks to ensure we did the point math right
+                       */
+                       if (pui8ServerFenceStart != 0)
+                       {
+                               PVR_ASSERT(pui8ServerFenceStart ==
+                                                  (psCmdHelperData->pui8StartPtr +
+                                                  psCmdHelperData->ui32FenceCmdSize));
+                       }
+
+                       if (pui8ServerUpdateStart != 0)
+                       {
+                               PVR_ASSERT(pui8ServerUpdateStart ==
+                                          psCmdHelperData->pui8StartPtr             +
+                                          psCmdHelperData->ui32FenceCmdSize         +
+                                          psCmdHelperData->ui32PreTimeStampCmdSize  +
+                                          psCmdHelperData->ui32DMCmdSize            +
+                                          psCmdHelperData->ui32RMWUFOCmdSize        +
+                                          psCmdHelperData->ui32PostTimeStampCmdSize +
+                                          psCmdHelperData->ui32UpdateCmdSize);
+                       }
+
+                       if (pui8ServerUnfencedUpdateStart != 0)
+                       {
+                               PVR_ASSERT(pui8ServerUnfencedUpdateStart ==
+                                          psCmdHelperData->pui8StartPtr             +
+                                          psCmdHelperData->ui32FenceCmdSize         +
+                                          psCmdHelperData->ui32PreTimeStampCmdSize  +
+                                          psCmdHelperData->ui32DMCmdSize            +
+                                          psCmdHelperData->ui32RMWUFOCmdSize        +
+                                          psCmdHelperData->ui32PostTimeStampCmdSize +
+                                          psCmdHelperData->ui32UpdateCmdSize        +
+                                          psCmdHelperData->ui32UnfencedUpdateCmdSize);
+                       }                       
+               }
+       
+               /*
+                       All the commands have been filled in so release the CCB space.
+                       The FW still won't run this command until we kick it
+               */
+               PDUMPCOMMENTWITHFLAGS((psCmdHelperData->bPDumpContinuous) ? PDUMP_FLAGS_CONTINUOUS : 0,
+                               "%s Command Server Release on FWCtx %08x",
+                               psCmdHelperData->pszCommandName, ui32CtxAddr);
+       }
+
+       _RGXClientCCBDumpCommands(asCmdHelperData[0].psClientCCB,
+                                                         asCmdHelperData[0].psClientCCB->ui32HostWriteOffset,
+                                                         ui32AllocSize);
+
+       RGXReleaseCCB(asCmdHelperData[0].psClientCCB, 
+                                 ui32AllocSize,
+                                 asCmdHelperData[0].bPDumpContinuous);
+}
+
+
+IMG_UINT32 RGXCmdHelperGetCommandSize(IMG_UINT32              ui32CmdCount,
+                                      RGX_CCB_CMD_HELPER_DATA *asCmdHelperData)
+{
+       IMG_UINT32 ui32AllocSize = 0;
+       IMG_UINT32 i;
+
+       /*
+               Workout how much space we need for all the command(s)
+       */
+       for (i = 0; i < ui32CmdCount; i++)
+       {
+               ui32AllocSize +=
+                       asCmdHelperData[i].ui32FenceCmdSize          +
+                       asCmdHelperData[i].ui32DMCmdSize             +
+                       asCmdHelperData[i].ui32UpdateCmdSize         +
+                       asCmdHelperData[i].ui32UnfencedUpdateCmdSize +                  
+                       asCmdHelperData[i].ui32PreTimeStampCmdSize   +
+                       asCmdHelperData[i].ui32PostTimeStampCmdSize  +
+                       asCmdHelperData[i].ui32RMWUFOCmdSize;
+       }
+
+       return ui32AllocSize;
+}
+
+
+static IMG_PCCHAR _CCBCmdTypename(RGXFWIF_CCB_CMD_TYPE cmdType)
+{
+       static const IMG_CHAR* aCCBCmdName[20] = { "TA", "3D", "CDM", "TQ_3D", "TQ_2D",
+                                                  "3D_PR", "NULL", "SHG", "RTU", "RTU_FC",
+                                                  "PRE_TIMESTAMP",
+                                                  "FENCE", "UPDATE", "RMW_UPDATE",
+                                                  "FENCE_PR", "PRIORITY",
+                                                  "POST_TIMESTAMP", "UNFENCED_UPDATE",
+                                                  "UNFENCED_RMW_UPDATE", "PADDING"};
+       IMG_UINT32      cmdStrIdx = 19;
+
+       PVR_ASSERT( (cmdType == RGXFWIF_CCB_CMD_TYPE_TA)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_3D)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_CDM)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_TQ_3D)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_TQ_2D)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_3D_PR)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_NULL)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_SHG)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_RTU)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_RTU_FC)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_FENCE)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_UPDATE)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_PRIORITY)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE)
+                   || (cmdType == RGXFWIF_CCB_CMD_TYPE_PADDING));
+
+       if( cmdType !=  RGXFWIF_CCB_CMD_TYPE_PADDING)
+       {
+               cmdStrIdx = ((IMG_UINT32)cmdType & ~RGX_CCB_TYPE_TASK) - (RGXFWIF_CCB_CMD_TYPE_TA & ~RGX_CCB_TYPE_TASK);
+       }
+
+       return aCCBCmdName[cmdStrIdx];
+}
+
+PVRSRV_ERROR CheckForStalledCCB(RGX_CLIENT_CCB  *psCurrentClientCCB)
+{
+       volatile RGXFWIF_CCCB_CTL       *psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl;
+       IMG_UINT32                                      ui32SampledRdOff = psClientCCBCtrl->ui32ReadOffset;
+       IMG_UINT32                                      ui32SampledWrOff = psCurrentClientCCB->ui32HostWriteOffset;
+       PVRSRV_ERROR                            eError = PVRSRV_OK;
+
+       if (ui32SampledRdOff > psClientCCBCtrl->ui32WrapMask  ||
+               ui32SampledWrOff > psClientCCBCtrl->ui32WrapMask)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "CheckForStalledCCB: CCCB has invalid offset (ROFF=%d WOFF=%d)",
+                               ui32SampledRdOff, ui32SampledWrOff));
+               return  PVRSRV_ERROR_INVALID_OFFSET;
+       }
+
+       if (ui32SampledRdOff != ui32SampledWrOff &&
+                               psCurrentClientCCB->ui32LastROff != psCurrentClientCCB->ui32LastWOff &&
+                               ui32SampledRdOff == psCurrentClientCCB->ui32LastROff &&
+                               (psCurrentClientCCB->ui32ByteCount - psCurrentClientCCB->ui32LastByteCount) < psCurrentClientCCB->ui32Size)
+       {
+               //RGXFWIF_DEV_VIRTADDR v = {0};
+               //DumpStalledCCBCommand(v,psCurrentClientCCB,IMG_NULL);
+
+               /* Don't log this by default unless debugging since a higher up
+                * function will log the stalled condition. Helps avoid double
+                *  messages in the log.
+                */
+               PVR_DPF((PVR_DBG_MESSAGE, "CheckForStalledCCB: CCCB has not progressed (ROFF=%d WOFF=%d)",
+                               ui32SampledRdOff, ui32SampledWrOff));
+               eError =  PVRSRV_ERROR_CCCB_STALLED;
+       }
+
+       psCurrentClientCCB->ui32LastROff = ui32SampledRdOff;
+       psCurrentClientCCB->ui32LastWOff = ui32SampledWrOff;
+       psCurrentClientCCB->ui32LastByteCount = psCurrentClientCCB->ui32ByteCount;
+
+       return eError;
+}
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
+IMG_VOID DumpCCB(
+       PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext,
+       RGX_CLIENT_CCB  *psCurrentClientCCB,
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf
+)
+{
+       volatile RGXFWIF_CCCB_CTL *psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl;
+       IMG_UINT8 *pui8ClientCCBBuff = psCurrentClientCCB->pui8ClientCCB;
+       IMG_UINT32 ui32Offset = psClientCCBCtrl->ui32ReadOffset;
+       IMG_UINT32 ui32DepOffset = psClientCCBCtrl->ui32DepOffset;
+       IMG_UINT32 ui32EndOffset = psCurrentClientCCB->ui32HostWriteOffset;
+       IMG_UINT32 ui32WrapMask = psClientCCBCtrl->ui32WrapMask;
+       IMG_CHAR * pszState = "Ready";
+
+       PVR_DUMPDEBUG_LOG(("FWCtx 0x%08X (%s)", sFWCommonContext.ui32Addr,
+               (IMG_PCHAR)&psCurrentClientCCB->szName));
+       if (ui32Offset == ui32EndOffset)
+       {
+               PVR_DUMPDEBUG_LOG(("  `--<Empty>"));
+       }
+
+       while (ui32Offset != ui32EndOffset)
+       {
+               RGXFWIF_CCB_CMD_HEADER *psCmdHeader = (RGXFWIF_CCB_CMD_HEADER*)(pui8ClientCCBBuff + ui32Offset);
+               IMG_UINT32 ui32NextOffset = (ui32Offset + psCmdHeader->ui32CmdSize + sizeof(RGXFWIF_CCB_CMD_HEADER)) & ui32WrapMask;
+               IMG_BOOL bLastCommand = (ui32NextOffset == ui32EndOffset)? IMG_TRUE: IMG_FALSE;
+               IMG_BOOL bLastUFO;
+               #define CCB_SYNC_INFO_LEN 80
+               IMG_CHAR pszSyncInfo[CCB_SYNC_INFO_LEN];
+               IMG_UINT32 ui32NoOfUpdates, i;
+               RGXFWIF_UFO *psUFOPtr;
+
+               ui32NoOfUpdates = psCmdHeader->ui32CmdSize / sizeof(RGXFWIF_UFO);
+               psUFOPtr = (RGXFWIF_UFO*)(pui8ClientCCBBuff + ui32Offset + sizeof(RGXFWIF_CCB_CMD_HEADER));
+               pszSyncInfo[0] = '\0';
+
+               if (ui32Offset == ui32DepOffset)
+               {
+                       pszState = "Waiting";
+               }
+
+               PVR_DUMPDEBUG_LOG(("  %s--%s %s @ %u",
+                       bLastCommand? "`": "|",
+                       pszState, _CCBCmdTypename(psCmdHeader->eCmdType),
+                       ui32Offset
+                       ));
+
+               /* switch on type and write checks and updates */
+               switch (psCmdHeader->eCmdType)
+               {
+                       case RGXFWIF_CCB_CMD_TYPE_UPDATE:
+                       case RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE:
+                       case RGXFWIF_CCB_CMD_TYPE_FENCE:
+                       case RGXFWIF_CCB_CMD_TYPE_FENCE_PR:
+                       {
+                               for (i = 0; i < ui32NoOfUpdates; i++, psUFOPtr++)
+                               {
+                                       bLastUFO = (ui32NoOfUpdates-1 == i)? IMG_TRUE: IMG_FALSE;
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+                                       SyncRecordLookup(psUFOPtr->puiAddrUFO.ui32Addr, pszSyncInfo, CCB_SYNC_INFO_LEN);
+#endif
+                                       PVR_DUMPDEBUG_LOG(("  %s  %s--Addr:0x%08x Val=0x%08x %s",
+                                               bLastCommand? " ": "|",
+                                               bLastUFO? "`": "|",
+                                               psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value,
+                                               pszSyncInfo
+                                               ));
+                               }
+                               break;
+                       }
+
+                       case RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE:
+                       case RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE:
+                       {
+                               for (i = 0; i < ui32NoOfUpdates; i++, psUFOPtr++)
+                               {
+                                       bLastUFO = (ui32NoOfUpdates-1 == i)? IMG_TRUE: IMG_FALSE;
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+                                       SyncRecordLookup(psUFOPtr->puiAddrUFO.ui32Addr, pszSyncInfo, CCB_SYNC_INFO_LEN);
+#endif
+                                       PVR_DUMPDEBUG_LOG(("  %s  %s--Addr:0x%08x Val++ %s",
+                                               bLastCommand? " ": "|",
+                                               bLastUFO? "`": "|",
+                                               psUFOPtr->puiAddrUFO.ui32Addr,
+                                               pszSyncInfo
+                                               ));
+                               }
+                               break;
+                       }
+
+                       default:
+                               break;
+               }
+               ui32Offset = ui32NextOffset;
+       }
+
+}
+#endif /* defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP) */
+
+IMG_VOID DumpStalledCCBCommand(PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext,
+                                                          RGX_CLIENT_CCB  *psCurrentClientCCB,
+                                                          DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       volatile RGXFWIF_CCCB_CTL         *psClientCCBCtrl = psCurrentClientCCB->psClientCCBCtrl;
+       IMG_UINT8                                         *pui8ClientCCBBuff = psCurrentClientCCB->pui8ClientCCB;
+       volatile IMG_UINT8                        *pui8Ptr;
+       IMG_UINT32                                        ui32SampledRdOff = psClientCCBCtrl->ui32ReadOffset;
+       IMG_UINT32                                        ui32SampledDepOff = psClientCCBCtrl->ui32DepOffset;
+       IMG_UINT32                                        ui32SampledWrOff = psCurrentClientCCB->ui32HostWriteOffset;
+
+       pui8Ptr = pui8ClientCCBBuff + ui32SampledRdOff;
+
+       if ((ui32SampledRdOff == ui32SampledDepOff) &&
+               (ui32SampledRdOff != ui32SampledWrOff))
+       {
+               volatile RGXFWIF_CCB_CMD_HEADER *psCommandHeader = (RGXFWIF_CCB_CMD_HEADER *)(pui8ClientCCBBuff + ui32SampledRdOff);
+               RGXFWIF_CCB_CMD_TYPE    eCommandType = psCommandHeader->eCmdType;
+               volatile IMG_UINT8                              *pui8Ptr = (IMG_UINT8 *)psCommandHeader;
+
+               /* CCB is stalled on a fence... */
+               if ((eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE) || (eCommandType == RGXFWIF_CCB_CMD_TYPE_FENCE_PR))
+               {
+                       RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *)(pui8Ptr + sizeof(*psCommandHeader));
+                       IMG_UINT32 jj;
+
+                       /* Display details of the fence object on which the context is pending */
+                       PVR_DUMPDEBUG_LOG(("FWCtx 0x%08X @ %d (%s) pending on %s:",
+                                                          sFWCommonContext.ui32Addr,
+                                                          ui32SampledRdOff,
+                                                          (IMG_PCHAR)&psCurrentClientCCB->szName,
+                                                          _CCBCmdTypename(eCommandType)));
+                       for (jj=0; jj<psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO); jj++)
+                       {
+#if !defined(SUPPORT_EXTRA_METASP_DEBUG)
+                               PVR_DUMPDEBUG_LOG(("  Addr:0x%08x  Value=0x%08x",psUFOPtr[jj].puiAddrUFO.ui32Addr, psUFOPtr[jj].ui32Value));
+#else
+                               PVR_DUMPDEBUG_LOG(("  Addr:0x%08x Value(Host)=0x%08x Value(FW)=0x%08x",
+                                                  psUFOPtr[jj].puiAddrUFO.ui32Addr,
+                                                  psUFOPtr[jj].ui32Value,
+                                                  RGXReadWithSP(psUFOPtr[jj].puiAddrUFO.ui32Addr)));
+#endif
+                       }
+
+                       /* Advance psCommandHeader past the FENCE to the next command header (this will be the TA/3D command that is fenced) */
+                       pui8Ptr = (IMG_UINT8 *)psUFOPtr + psCommandHeader->ui32CmdSize;
+                       psCommandHeader = (RGXFWIF_CCB_CMD_HEADER *)pui8Ptr;
+                       if( (IMG_UINTPTR_T)psCommandHeader != ((IMG_UINTPTR_T)pui8ClientCCBBuff + ui32SampledWrOff))
+                       {
+                               PVR_DUMPDEBUG_LOG((" FWCtx 0x%08X fenced command is of type %s",sFWCommonContext.ui32Addr, _CCBCmdTypename(psCommandHeader->eCmdType)));
+                               /* Advance psCommandHeader past the TA/3D to the next command header (this will possibly be an UPDATE) */
+                               pui8Ptr += sizeof(*psCommandHeader) + psCommandHeader->ui32CmdSize;
+                               psCommandHeader = (RGXFWIF_CCB_CMD_HEADER *)pui8Ptr;
+                               /* If the next command is an update, display details of that so we can see what would then become unblocked */
+                               if( (IMG_UINTPTR_T)psCommandHeader != ((IMG_UINTPTR_T)pui8ClientCCBBuff + ui32SampledWrOff))
+                               {
+                                       eCommandType = psCommandHeader->eCmdType;
+
+                                       if (eCommandType == RGXFWIF_CCB_CMD_TYPE_UPDATE)
+                                       {
+                                               psUFOPtr = (RGXFWIF_UFO *)((IMG_UINT8 *)psCommandHeader + sizeof(*psCommandHeader));
+                                               PVR_DUMPDEBUG_LOG((" preventing %s:",_CCBCmdTypename(eCommandType)));
+                                               for (jj=0; jj<psCommandHeader->ui32CmdSize/sizeof(RGXFWIF_UFO); jj++)
+                                               {
+#if !defined(SUPPORT_EXTRA_METASP_DEBUG)
+                                                       PVR_DUMPDEBUG_LOG(("  Addr:0x%08x  Value=0x%08x",psUFOPtr[jj].puiAddrUFO.ui32Addr, psUFOPtr[jj].ui32Value));
+#else
+                                                       PVR_DUMPDEBUG_LOG(("  Addr:0x%08x Value(Host)=0x%08x Value(FW)=0x%08x",
+                                                                          psUFOPtr[jj].puiAddrUFO.ui32Addr,
+                                                                          psUFOPtr[jj].ui32Value,
+                                                                          RGXReadWithSP(psUFOPtr[jj].puiAddrUFO.ui32Addr)));
+#endif
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       PVR_DUMPDEBUG_LOG((" FWCtx 0x%08X has no further commands",sFWCommonContext.ui32Addr));
+                               }
+                       }
+                       else
+                       {
+                               PVR_DUMPDEBUG_LOG((" FWCtx 0x%08X has no further commands",sFWCommonContext.ui32Addr));
+                       }
+               }
+       }
+}
+
+/******************************************************************************
+ End of file (rgxccb.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxccb.h
new file mode 100644 (file)
index 0000000..353d247
--- /dev/null
@@ -0,0 +1,170 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Circular Command Buffer functionality.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX Circular Command Buffer functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXCCB_H__)
+#define __RGXCCB_H__
+
+#include "devicemem.h"
+#include "device.h"
+#include "rgxdevice.h"
+#include "sync_server.h"
+#include "connection_server.h"
+#include "rgx_fwif_shared.h"
+#include "rgxdebug.h"
+
+#define MAX_CLIENT_CCB_NAME    30
+
+typedef struct _RGX_CLIENT_CCB_ RGX_CLIENT_CCB;
+
+/*
+       This structure is declared here as it's allocated on the heap by
+       the callers
+*/
+
+typedef struct _RGX_CCB_CMD_HELPER_DATA_ {
+       /* Data setup at command init time */
+       RGX_CLIENT_CCB                  *psClientCCB;
+       IMG_CHAR                                *pszCommandName;
+       IMG_BOOL                                bPDumpContinuous;
+       
+       IMG_UINT32                              ui32ClientFenceCount;
+       PRGXFWIF_UFO_ADDR               *pauiFenceUFOAddress;
+       IMG_UINT32                              *paui32FenceValue;
+       IMG_UINT32                              ui32ClientUpdateCount;
+       PRGXFWIF_UFO_ADDR               *pauiUpdateUFOAddress;
+       IMG_UINT32                              *paui32UpdateValue;
+
+       IMG_UINT32                              ui32ServerSyncCount;
+       IMG_UINT32                              *paui32ServerSyncFlags;
+       SERVER_SYNC_PRIMITIVE   **papsServerSyncs;
+
+       RGXFWIF_CCB_CMD_TYPE    eType;
+       IMG_UINT32                              ui32CmdSize;
+       IMG_UINT8                               *pui8DMCmd;
+       IMG_UINT32                              ui32FenceCmdSize;
+       IMG_UINT32                              ui32DMCmdSize;
+       IMG_UINT32                              ui32UpdateCmdSize;
+       IMG_UINT32                              ui32UnfencedUpdateCmdSize;
+
+       /* timestamp commands */
+       RGXFWIF_DEV_VIRTADDR    pPreTimestamp;
+       IMG_UINT32              ui32PreTimeStampCmdSize;
+       RGXFWIF_DEV_VIRTADDR    pPostTimestamp;
+       IMG_UINT32              ui32PostTimeStampCmdSize;
+       PRGXFWIF_UFO_ADDR       pRMWUFOAddr;
+       IMG_UINT32              ui32RMWUFOCmdSize;
+
+       /* Data setup at command acquire time */
+       IMG_UINT8                               *pui8StartPtr;
+       IMG_UINT8                               *pui8ServerUpdateStart;
+       IMG_UINT8                               *pui8ServerUnfencedUpdateStart;
+       IMG_UINT8                               *pui8ServerFenceStart;
+       IMG_UINT32                              ui32ServerFenceCount;
+       IMG_UINT32                              ui32ServerUpdateCount;
+       IMG_UINT32                              ui32ServerUnfencedUpdateCount;
+
+} RGX_CCB_CMD_HELPER_DATA;
+
+#define PADDING_COMMAND_SIZE   (sizeof(RGXFWIF_CCB_CMD_HEADER))
+
+PVRSRV_ERROR RGXCreateCCB(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                 IMG_UINT32                    ui32CCBSizeLog2,
+                                                 CONNECTION_DATA               *psConnectionData,
+                                                 const IMG_CHAR                *pszName,
+                                                 RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
+                                                 RGX_CLIENT_CCB                **ppsClientCCB,
+                                                 DEVMEM_MEMDESC                **ppsClientCCBMemDesc,
+                                                 DEVMEM_MEMDESC                **ppsClientCCBCtlMemDesc);
+
+IMG_VOID RGXDestroyCCB(RGX_CLIENT_CCB *psClientCCB);
+
+PVRSRV_ERROR RGXAcquireCCB(RGX_CLIENT_CCB *psClientCCB,
+                                                                               IMG_UINT32              ui32CmdSize,
+                                                                               IMG_PVOID               *ppvBufferSpace,
+                                                                               IMG_BOOL                bPDumpContinuous);
+
+IMG_INTERNAL IMG_VOID RGXReleaseCCB(RGX_CLIENT_CCB *psClientCCB,
+                                                                       IMG_UINT32              ui32CmdSize,
+                                                                       IMG_BOOL                bPDumpContinuous);
+
+IMG_UINT32 RGXGetHostWriteOffsetCCB(RGX_CLIENT_CCB *psClientCCB);
+
+PVRSRV_ERROR RGXCmdHelperInitCmdCCB(RGX_CLIENT_CCB          *psClientCCB,
+                                    IMG_UINT32              ui32ClientFenceCount,
+                                    PRGXFWIF_UFO_ADDR       *pauiFenceUFOAddress,
+                                    IMG_UINT32              *paui32FenceValue,
+                                    IMG_UINT32              ui32ClientUpdateCount,
+                                    PRGXFWIF_UFO_ADDR       *pauiUpdateUFOAddress,
+                                    IMG_UINT32              *paui32UpdateValue,
+                                    IMG_UINT32              ui32ServerSyncCount,
+                                    IMG_UINT32              *paui32ServerSyncFlags,
+                                    SERVER_SYNC_PRIMITIVE   **pasServerSyncs,
+                                    IMG_UINT32              ui32CmdSize,
+                                    IMG_UINT8               *pui8DMCmd,
+                                    RGXFWIF_DEV_VIRTADDR    *ppPreTimestamp,
+                                    RGXFWIF_DEV_VIRTADDR    *ppPostTimestamp,
+                                    RGXFWIF_DEV_VIRTADDR    *ppRMWUFOAddr,
+                                    RGXFWIF_CCB_CMD_TYPE    eType,
+                                    IMG_BOOL                bPDumpContinuous,
+                                    IMG_CHAR                *pszCommandName,
+                                    RGX_CCB_CMD_HELPER_DATA *psCmdHelperData);
+
+PVRSRV_ERROR RGXCmdHelperAcquireCmdCCB(IMG_UINT32 ui32CmdCount,
+                                                                          RGX_CCB_CMD_HELPER_DATA *asCmdHelperData,
+                                                                          IMG_BOOL *pbKickRequired);
+
+IMG_VOID RGXCmdHelperReleaseCmdCCB(IMG_UINT32 ui32CmdCount,
+                                                                  RGX_CCB_CMD_HELPER_DATA *asCmdHelperData,
+                                                                  const IMG_CHAR *pcszDMName,
+                                                                  IMG_UINT32 ui32CtxAddr);
+
+IMG_UINT32 RGXCmdHelperGetCommandSize(IMG_UINT32 ui32CmdCount,
+                                                                  RGX_CCB_CMD_HELPER_DATA *asCmdHelperData);
+
+IMG_VOID DumpStalledCCBCommand(PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, RGX_CLIENT_CCB  *psCurrentClientCCB, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
+IMG_VOID DumpCCB(PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext, RGX_CLIENT_CCB  *psCurrentClientCCB, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+#endif
+
+PVRSRV_ERROR CheckForStalledCCB(RGX_CLIENT_CCB  *psCurrentClientCCB);
+#endif /* __RGXCCB_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.c
new file mode 100644 (file)
index 0000000..18bf859
--- /dev/null
@@ -0,0 +1,590 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Compute routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX Compute routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "srvkm.h"
+#include "pdump_km.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgxcompute.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "osfunc.h"
+#include "rgxccb.h"
+#include "rgxhwperf.h"
+#include "rgxtimerquery.h"
+
+#include "sync_server.h"
+#include "sync_internal.h"
+#include "rgx_memallocflags.h"
+#include "rgxsync.h"
+
+struct _RGX_SERVER_COMPUTE_CONTEXT_ {
+       PVRSRV_DEVICE_NODE                      *psDeviceNode;
+       RGX_SERVER_COMMON_CONTEXT       *psServerCommonContext;
+       DEVMEM_MEMDESC                          *psFWFrameworkMemDesc;
+       DEVMEM_MEMDESC                          *psFWComputeContextStateMemDesc;
+       PVRSRV_CLIENT_SYNC_PRIM         *psSync;
+       DLLIST_NODE                                     sListNode;
+       SYNC_ADDR_LIST                          sSyncAddrListFence;
+       SYNC_ADDR_LIST                          sSyncAddrListUpdate;
+};
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA                   *psConnection,
+                                                                                        PVRSRV_DEVICE_NODE                     *psDeviceNode,
+                                                                                        IMG_UINT32                                     ui32Priority,
+                                                                                        IMG_DEV_VIRTADDR                       sMCUFenceAddr,
+                                                                                        IMG_UINT32                                     ui32FrameworkCommandSize,
+                                                                                        IMG_PBYTE                                      pbyFrameworkCommand,
+                                                                                        IMG_HANDLE                                     hMemCtxPrivData,
+                                                                                        RGX_SERVER_COMPUTE_CONTEXT     **ppsComputeContext)
+{
+       PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+       DEVMEM_MEMDESC                          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       RGX_SERVER_COMPUTE_CONTEXT      *psComputeContext;
+       RGX_COMMON_CONTEXT_INFO         sInfo;
+       PVRSRV_ERROR                            eError = PVRSRV_OK;
+
+       /* Prepare cleanup struct */
+       *ppsComputeContext = IMG_NULL;
+       psComputeContext = OSAllocMem(sizeof(*psComputeContext));
+       if (psComputeContext == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psComputeContext, 0, sizeof(*psComputeContext));
+
+       psComputeContext->psDeviceNode = psDeviceNode;
+
+       /* Allocate cleanup sync */
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psComputeContext->psSync,
+                                                  "compute cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto fail_syncalloc;
+       }
+
+       /*
+               Allocate device memory for the firmware GPU context suspend state.
+               Note: the FW reads/writes the state to memory by accessing the GPU register interface.
+       */
+       PDUMPCOMMENT("Allocate RGX firmware compute context suspend state");
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         sizeof(RGXFWIF_COMPUTECTX_STATE),
+                                                         RGX_FWCOMCTX_ALLOCFLAGS,
+                                                         "ComputeContextState",
+                                                         &psComputeContext->psFWComputeContextStateMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU context suspend state (%u)",
+                               eError));
+               goto fail_contextsuspendalloc;
+       }
+
+       /* 
+        * Create the FW framework buffer
+        */
+       eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode,
+                                                                               &psComputeContext->psFWFrameworkMemDesc,
+                                                                               ui32FrameworkCommandSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU framework state (%u)",
+                               eError));
+               goto fail_frameworkcreate;
+       }
+
+       /* Copy the Framework client data into the framework buffer */
+       eError = PVRSRVRGXFrameworkCopyCommand(psComputeContext->psFWFrameworkMemDesc,
+                                                                                  pbyFrameworkCommand,
+                                                                                  ui32FrameworkCommandSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to populate the framework buffer (%u)",
+                               eError));
+               goto fail_frameworkcopy;
+       }
+       
+       sInfo.psFWFrameworkMemDesc = psComputeContext->psFWFrameworkMemDesc;
+       sInfo.psMCUFenceAddr = &sMCUFenceAddr;
+
+       eError = FWCommonContextAllocate(psConnection,
+                                                                        psDeviceNode,
+                                                                        "CDM",
+                                                                        IMG_NULL,
+                                                                        0,
+                                                                        psFWMemContextMemDesc,
+                                                                        psComputeContext->psFWComputeContextStateMemDesc,
+                                                                        RGX_CCB_SIZE_LOG2,
+                                                                        ui32Priority,
+                                                                        &sInfo,
+                                                                        &psComputeContext->psServerCommonContext);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_contextalloc;
+       }
+
+       SyncAddrListInit(&psComputeContext->sSyncAddrListFence);
+       SyncAddrListInit(&psComputeContext->sSyncAddrListUpdate);
+
+       {
+               PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+
+               OSWRLockAcquireWrite(psDevInfo->hComputeCtxListLock);
+               dllist_add_to_tail(&(psDevInfo->sComputeCtxtListHead), &(psComputeContext->sListNode));
+               OSWRLockReleaseWrite(psDevInfo->hComputeCtxListLock);
+       }
+
+       *ppsComputeContext = psComputeContext;
+       return PVRSRV_OK;
+
+fail_contextalloc:
+fail_frameworkcopy:
+       DevmemFwFree(psComputeContext->psFWFrameworkMemDesc);
+fail_frameworkcreate:
+       DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc);
+fail_contextsuspendalloc:
+       SyncPrimFree(psComputeContext->psSync);
+fail_syncalloc:
+       OSFreeMem(psComputeContext);
+       return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext)
+{
+       PVRSRV_ERROR                            eError = PVRSRV_OK;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psComputeContext->psDeviceNode->pvDevice;
+
+       /* Check if the FW has finished with this resource ... */
+       eError = RGXFWRequestCommonContextCleanUp(psComputeContext->psDeviceNode,
+                                                                                         FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext),
+                                                                                         psComputeContext->psSync,
+                                                                                         RGXFWIF_DM_CDM);
+
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+       else if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
+                               __FUNCTION__,
+                               PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+
+       /* ... it has so we can free its resources */
+
+       OSWRLockAcquireWrite(psDevInfo->hComputeCtxListLock);
+       dllist_remove_node(&(psComputeContext->sListNode));
+       OSWRLockReleaseWrite(psDevInfo->hComputeCtxListLock);
+
+       FWCommonContextFree(psComputeContext->psServerCommonContext);
+       DevmemFwFree(psComputeContext->psFWFrameworkMemDesc);
+       DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc);
+       SyncPrimFree(psComputeContext->psSync);
+
+       SyncAddrListDeinit(&psComputeContext->sSyncAddrListFence);
+       SyncAddrListDeinit(&psComputeContext->sSyncAddrListUpdate);
+
+       OSFreeMem(psComputeContext);
+
+       return PVRSRV_OK;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT     *psComputeContext,
+                                                               IMG_UINT32                                      ui32ClientFenceCount,
+                                                               SYNC_PRIMITIVE_BLOCK                    **pauiClientFenceUFOSyncPrimBlock,
+                                                               IMG_UINT32                                      *paui32ClientFenceSyncOffset,
+                                                               IMG_UINT32                                      *paui32ClientFenceValue,
+                                                               IMG_UINT32                                      ui32ClientUpdateCount,
+                                                               SYNC_PRIMITIVE_BLOCK                    **pauiClientUpdateUFOSyncPrimBlock,
+                                                               IMG_UINT32                                      *paui32ClientUpdateSyncOffset,
+                                                               IMG_UINT32                                      *paui32ClientUpdateValue,
+                                                               IMG_UINT32                                      ui32ServerSyncPrims,
+                                                               IMG_UINT32                                      *paui32ServerSyncFlags,
+                                                               SERVER_SYNC_PRIMITIVE           **pasServerSyncs,
+                                                               IMG_UINT32                                      ui32CmdSize,
+                                                               IMG_PBYTE                                       pui8DMCmd,
+                                                               IMG_BOOL                                        bPDumpContinuous,
+                                                           IMG_UINT32                                  ui32ExtJobRef,
+                                                               IMG_UINT32                                      ui32IntJobRef)
+{
+       RGXFWIF_KCCB_CMD                sCmpKCCBCmd;
+       RGX_CCB_CMD_HELPER_DATA asCmdHelperData[1];
+       IMG_BOOL                                bKickRequired;
+       PVRSRV_ERROR                    eError;
+       PVRSRV_ERROR                    eError2;
+       IMG_UINT32                              i;
+
+       RGXFWIF_DEV_VIRTADDR    pPreTimestamp;
+       RGXFWIF_DEV_VIRTADDR    pPostTimestamp;
+       PRGXFWIF_UFO_ADDR               pRMWUFOAddr;
+
+       eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListFence,
+                                                                       ui32ClientFenceCount,
+                                                                       pauiClientFenceUFOSyncPrimBlock,
+                                                                       paui32ClientFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListUpdate,
+                                                                       ui32ClientUpdateCount,
+                                                                       pauiClientUpdateUFOSyncPrimBlock,
+                                                                       paui32ClientUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+
+       /* Sanity check the server fences */
+       for (i=0;i<ui32ServerSyncPrims;i++)
+       {
+               if (!(paui32ServerSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Server fence (on CDM) must fence", __FUNCTION__));
+                       return PVRSRV_ERROR_INVALID_SYNC_PRIM_OP;
+               }
+       }
+
+       RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psComputeContext->psDeviceNode->pvDevice,
+                                 & pPreTimestamp,
+                                 & pPostTimestamp,
+                                 & pRMWUFOAddr);
+
+       eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(psComputeContext->psServerCommonContext),
+                                       ui32ClientFenceCount,
+                                       psComputeContext->sSyncAddrListFence.pasFWAddrs,
+                                       paui32ClientFenceValue,
+                                       ui32ClientUpdateCount,
+                                       psComputeContext->sSyncAddrListUpdate.pasFWAddrs,
+                                       paui32ClientUpdateValue,
+                                       ui32ServerSyncPrims,
+                                       paui32ServerSyncFlags,
+                                       pasServerSyncs,
+                                       ui32CmdSize,
+                                       pui8DMCmd,
+                                       & pPreTimestamp,
+                                       & pPostTimestamp,
+                                       & pRMWUFOAddr,
+                                       RGXFWIF_CCB_CMD_TYPE_CDM,
+                                       bPDumpContinuous,
+                                       "Compute",
+                                       asCmdHelperData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_cmdinit;
+       }
+
+       eError = RGXCmdHelperAcquireCmdCCB(IMG_ARR_NUM_ELEMS(asCmdHelperData), 
+                                          asCmdHelperData, &bKickRequired);
+       if ((eError != PVRSRV_OK) && (!bKickRequired))
+       {
+               /*
+                       Only bail if no new data was submitted into the client CCB, we might
+                       have already submitted a padding packet which we should flush through
+                       the FW.
+               */
+               PVR_DPF((PVR_DBG_ERROR, "RGXKickCDM: Failed to create client CCB command"));
+               goto fail_cmdaquire;
+       }
+
+
+       /*
+               We should reserved space in the kernel CCB here and fill in the command
+               directly.
+               This is so if there isn't space in the kernel CCB we can return with
+               retry back to services client before we take any operations
+       */
+
+       /*
+               We might only be kicking for flush out a padding packet so only submit
+               the command if the create was successful
+       */
+       if (eError == PVRSRV_OK)
+       {
+               /*
+                       All the required resources are ready at this point, we can't fail so
+                       take the required server sync operations and commit all the resources
+               */
+               RGXCmdHelperReleaseCmdCCB(1, asCmdHelperData, "CDM", FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext).ui32Addr);
+       }
+
+       /* Construct the kernel compute CCB command. */
+       sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+       sCmpKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext);
+       sCmpKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psComputeContext->psServerCommonContext));
+       sCmpKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+
+       /*
+        * Submit the compute command to the firmware.
+        */
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError2 = RGXScheduleCommand(psComputeContext->psDeviceNode->pvDevice,
+                                                                       RGXFWIF_DM_CDM,
+                                                                       &sCmpKCCBCmd,
+                                                                       sizeof(sCmpKCCBCmd),
+                                                                       bPDumpContinuous);
+               if (eError2 != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+       
+       if (eError2 != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXKickCDMKM failed to schedule kernel CCB command. (0x%x)", eError));
+       }
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+       else
+       {
+               RGXHWPerfFTraceGPUEnqueueEvent(psComputeContext->psDeviceNode->pvDevice,
+                               ui32ExtJobRef, ui32IntJobRef, "CDM");
+       }
+#endif
+       /*
+        * Now check eError (which may have returned an error from our earlier call
+        * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first
+        * so we check it now...
+        */
+       if (eError != PVRSRV_OK )
+       {
+               goto fail_cmdaquire;
+       }
+
+       return PVRSRV_OK;
+
+fail_cmdaquire:
+fail_cmdinit:
+err_populate_sync_addr_list:
+       return eError;
+}
+
+IMG_EXPORT PVRSRV_ERROR PVRSRVRGXFlushComputeDataKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext)
+{
+       RGXFWIF_KCCB_CMD sFlushCmd;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+#if defined(PDUMP)
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Submit Compute flush");
+#endif
+       sFlushCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL;
+       sFlushCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_FALSE;
+       sFlushCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_TRUE;
+       sFlushCmd.uCmdData.sSLCFlushInvalData.eDM = RGXFWIF_DM_CDM;
+       sFlushCmd.uCmdData.sSLCFlushInvalData.psContext = FWCommonContextGetFWAddress(psComputeContext->psServerCommonContext);
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError = RGXScheduleCommand(psComputeContext->psDeviceNode->pvDevice,
+                                                                       RGXFWIF_DM_GP,
+                                                                       &sFlushCmd,
+                                                                       sizeof(sFlushCmd),
+                                                                       IMG_TRUE);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFlushComputeDataKM: Failed to schedule SLC flush command with error (%u)", eError));
+       }
+       else
+       {
+               /* Wait for the SLC flush to complete */
+               eError = RGXWaitForFWOp(psComputeContext->psDeviceNode->pvDevice,
+                                                               RGXFWIF_DM_GP,
+                                                               psComputeContext->psSync,
+                                                               IMG_TRUE);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFlushComputeDataKM: Compute flush aborted with error (%u)", eError));
+               }
+       }
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXSetComputeContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                 RGX_SERVER_COMPUTE_CONTEXT *psComputeContext,
+                                                                                                 IMG_UINT32 ui32Priority)
+{
+       PVRSRV_ERROR eError;
+
+       eError = ContextSetPriority(psComputeContext->psServerCommonContext,
+                                                               psConnection,
+                                                               psComputeContext->psDeviceNode->pvDevice,
+                                                               ui32Priority,
+                                                               RGXFWIF_DM_CDM);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the compute context (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+       }
+       return eError;
+}
+
+static IMG_BOOL CheckForStalledComputeCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       RGX_SERVER_COMPUTE_CONTEXT              *psCurrentServerComputeCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_COMPUTE_CONTEXT, sListNode);
+       RGX_SERVER_COMMON_CONTEXT               *psCurrentServerComputeCommonCtx = psCurrentServerComputeCtx->psServerCommonContext;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = pvCallbackData;
+
+       DumpStalledFWCommonContext(psCurrentServerComputeCommonCtx, pfnDumpDebugPrintf);
+       return IMG_TRUE;
+}
+IMG_VOID CheckForStalledComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       OSWRLockAcquireRead(psDevInfo->hComputeCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sComputeCtxtListHead),
+                                               CheckForStalledComputeCtxtCommand, pfnDumpDebugPrintf);
+       OSWRLockReleaseRead(psDevInfo->hComputeCtxListLock);
+}
+
+static IMG_BOOL CheckForStalledClientComputeCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       PVRSRV_ERROR *peError = (PVRSRV_ERROR*)pvCallbackData;
+       RGX_SERVER_COMPUTE_CONTEXT *psCurrentServerComputeCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_COMPUTE_CONTEXT, sListNode);
+       RGX_SERVER_COMMON_CONTEXT *psCurrentServerComputeCommonCtx = psCurrentServerComputeCtx->psServerCommonContext;
+
+       if (PVRSRV_ERROR_CCCB_STALLED == CheckStalledClientCommonContext(psCurrentServerComputeCommonCtx))
+       {
+               *peError = PVRSRV_ERROR_CCCB_STALLED;
+       }
+
+       return IMG_TRUE;
+}
+IMG_BOOL CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       OSWRLockAcquireRead(psDevInfo->hComputeCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sComputeCtxtListHead), 
+                                               CheckForStalledClientComputeCtxtCommand, &eError);
+       OSWRLockReleaseRead(psDevInfo->hComputeCtxListLock);
+       return (PVRSRV_ERROR_CCCB_STALLED == eError)? IMG_TRUE: IMG_FALSE;
+}
+
+IMG_EXPORT PVRSRV_ERROR 
+PVRSRVRGXKickSyncCDMKM(RGX_SERVER_COMPUTE_CONTEXT  *psComputeContext,
+                       IMG_UINT32                  ui32ClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK          **pauiClientFenceUFOSyncPrimBlock,
+                       IMG_UINT32                  *paui32ClientFenceSyncOffset,
+                       IMG_UINT32                  *paui32ClientFenceValue,
+                       IMG_UINT32                  ui32ClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK           **pauiClientUpdateUFOSyncPrimBlock,
+                       IMG_UINT32                  *paui32ClientUpdateSyncOffset,
+                       IMG_UINT32                  *paui32ClientUpdateValue,
+                       IMG_UINT32                  ui32ServerSyncPrims,
+                       IMG_UINT32                  *paui32ServerSyncFlags,
+                       SERVER_SYNC_PRIMITIVE       **pasServerSyncs,
+                                          IMG_UINT32                              ui32NumCheckFenceFDs,
+                                          IMG_INT32                               *pai32CheckFenceFDs,
+                                          IMG_INT32                   i32UpdateFenceFD,
+                       IMG_BOOL                    bPDumpContinuous)
+{
+       PVRSRV_ERROR eError;
+
+       eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListFence,
+                                                                       ui32ClientFenceCount,
+                                                                       pauiClientFenceUFOSyncPrimBlock,
+                                                                       paui32ClientFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListUpdate,
+                                                                       ui32ClientUpdateCount,
+                                                                       pauiClientUpdateUFOSyncPrimBlock,
+                                                                       paui32ClientUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+
+       if (ui32NumCheckFenceFDs > 0 || i32UpdateFenceFD >= 0)
+       {
+               return PVRSRV_ERROR_NOT_IMPLEMENTED;
+       }
+
+       eError = RGXKickSyncKM(psComputeContext->psDeviceNode,
+                            psComputeContext->psServerCommonContext,
+                            RGXFWIF_DM_CDM,
+                                                "SyncCDM",
+                            ui32ClientFenceCount,
+                            psComputeContext->sSyncAddrListFence.pasFWAddrs,
+                            paui32ClientFenceValue,
+                            ui32ClientUpdateCount,
+                            psComputeContext->sSyncAddrListUpdate.pasFWAddrs,
+                            paui32ClientUpdateValue,
+                            ui32ServerSyncPrims,
+                            paui32ServerSyncFlags,
+                            pasServerSyncs,
+                            bPDumpContinuous);
+
+err_populate_sync_addr_list:
+       return eError;
+}
+/******************************************************************************
+ End of file (rgxcompute.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxcompute.h
new file mode 100644 (file)
index 0000000..c1e34b8
--- /dev/null
@@ -0,0 +1,183 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX compute functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX compute functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXCOMPUTE_H__)
+#define __RGXCOMPUTE_H__
+
+#include "devicemem.h"
+#include "device.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_resetframework.h"
+#include "rgxdebug.h"
+
+#include "sync_server.h"
+#include "sync_internal.h"
+#include "connection_server.h"
+
+
+typedef struct _RGX_SERVER_COMPUTE_CONTEXT_ RGX_SERVER_COMPUTE_CONTEXT;
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXCreateComputeContextKM
+
+ @Description
+       
+
+ @Input pvDeviceNode 
+ @Input psCmpCCBMemDesc - 
+ @Input psCmpCCBCtlMemDesc - 
+ @Output ppsFWComputeContextMemDesc - 
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA                   *psConnection,
+                                                                                        PVRSRV_DEVICE_NODE                     *psDeviceNode,
+                                                                                        IMG_UINT32                                     ui32Priority,
+                                                                                        IMG_DEV_VIRTADDR                       sMCUFenceAddr,
+                                                                                        IMG_UINT32                                     ui32FrameworkRegisterSize,
+                                                                                        IMG_PBYTE                                      pbyFrameworkRegisters,
+                                                                                        IMG_HANDLE                                     hMemCtxPrivData,
+                                                                                        RGX_SERVER_COMPUTE_CONTEXT     **ppsComputeContext);
+
+/*! 
+*******************************************************************************
+ @Function     PVRSRVRGXDestroyComputeContextKM
+
+ @Description
+       Server-side implementation of RGXDestroyComputeContext
+
+ @Input psCleanupData - 
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext);
+
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXKickCDMKM
+
+ @Description
+       Server-side implementation of RGXKickCDM
+
+ @Input psDeviceNode - RGX Device node
+ @Input psFWComputeContextMemDesc - Mem desc for firmware compute context
+ @Input ui32cCCBWoffUpdate - New fw Woff for the client CDM CCB
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT     *psComputeContext,
+                                                               IMG_UINT32                                      ui32ClientFenceCount,
+                                                               SYNC_PRIMITIVE_BLOCK                    **pauiClientFenceUFOSyncPrimBlock,
+                                                               IMG_UINT32                                      *paui32ClientFenceSyncOffset,
+                                                               IMG_UINT32                                      *paui32ClientFenceValue,
+                                                               IMG_UINT32                                      ui32ClientUpdateCount,
+                                                               SYNC_PRIMITIVE_BLOCK                    **pauiClientUpdateUFOSyncPrimBlock,
+                                                               IMG_UINT32                                      *paui32ClientUpdateSyncOffset,
+                                                               IMG_UINT32                                      *paui32ClientUpdateValue,
+                                                               IMG_UINT32                                      ui32ServerSyncPrims,
+                                                               IMG_UINT32                                      *paui32ServerSyncFlags,
+                                                               SERVER_SYNC_PRIMITIVE           **pasServerSyncs,
+                                                               IMG_UINT32                                      ui32CmdSize,
+                                                               IMG_PBYTE                                       pui8DMCmd,
+                                                               IMG_BOOL                                        bPDumpContinuous,
+                                                           IMG_UINT32                                  ui32ExtJobRef,
+                                                               IMG_UINT32                                      ui32IntJobRef);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXFlushComputeDataKM
+
+ @Description
+       Server-side implementation of RGXFlushComputeData
+
+ @Input psComputeContext - Compute context to flush
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXFlushComputeDataKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext);
+
+PVRSRV_ERROR PVRSRVRGXSetComputeContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                 RGX_SERVER_COMPUTE_CONTEXT *psComputeContext,
+                                                                                                 IMG_UINT32 ui32Priority);
+
+/* Debug - check if compute context is waiting on a fence */
+IMG_VOID CheckForStalledComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/* Debug/Watchdog - check if client compute contexts are stalled */
+IMG_BOOL CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXKickSyncCDMKM
+
+ @Description
+       Sending a sync kick command though this CDM context
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT PVRSRV_ERROR 
+PVRSRVRGXKickSyncCDMKM(RGX_SERVER_COMPUTE_CONTEXT  *psComputeContext,
+                       IMG_UINT32                  ui32ClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK          **pauiClientFenceUFOSyncPrimBlock,
+                       IMG_UINT32                  *paui32ClientFenceSyncOffset,
+                       IMG_UINT32                  *paui32ClientFenceValue,
+                       IMG_UINT32                  ui32ClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK           **pauiClientUpdateUFOSyncPrimBlock,
+                       IMG_UINT32                  *paui32ClientUpdateSyncOffset,
+                       IMG_UINT32                  *paui32ClientUpdateValue,
+                       IMG_UINT32                  ui32ServerSyncPrims,
+                       IMG_UINT32                  *paui32ServerSyncFlags,
+                       SERVER_SYNC_PRIMITIVE       **pasServerSyncs,
+                                          IMG_UINT32                              ui32NumCheckFenceFDs,
+                                          IMG_INT32                               *pai32CheckFenceFDs,
+                                          IMG_INT32                   i32UpdateFenceFD,
+                       IMG_BOOL                    bPDumpContinuous);
+
+#endif /* __RGXCOMPUTE_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.c
new file mode 100644 (file)
index 0000000..33912c1
--- /dev/null
@@ -0,0 +1,3113 @@
+/*************************************************************************/ /*!
+@File
+@Title          Rgx debug information
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX debugging functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+//#define PVR_DPF_FUNCTION_TRACE_ON 1
+#undef PVR_DPF_FUNCTION_TRACE_ON
+
+#include "rgxdefs_km.h"
+#include "rgxdevice.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "osfunc.h"
+
+#include "lists.h"
+
+#include "rgxdebug.h"
+#include "pvrversion.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "rgxutils.h"
+#include "tlstream.h"
+#include "rgxfwutils.h"
+#include "pvrsrv.h"
+#include "services.h"
+
+#include "devicemem_pdump.h"
+
+#include "rgx_fwif.h"
+#include "pvrsrv.h"
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+#include "rgx_fwif_sf.h"
+#include "rgxfw_log_helper.h"
+#endif
+
+#include "rgxta3d.h"
+#include "rgxcompute.h"
+#include "rgxtransfer.h"
+#if defined(RGX_FEATURE_RAY_TRACING)
+#include "rgxray.h"
+#endif
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#include "devicemem_history_server.h"
+#endif
+
+
+#define RGX_DEBUG_STR_SIZE     (150)
+
+#define RGX_CR_BIF_CAT_BASE0                              (0x1200U)
+#define RGX_CR_BIF_CAT_BASE1                              (0x1208U)
+
+#define RGX_CR_BIF_CAT_BASEN(n) \
+       RGX_CR_BIF_CAT_BASE0 + \
+       ((RGX_CR_BIF_CAT_BASE1 - RGX_CR_BIF_CAT_BASE0) * n)
+
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGXDBG_BIF_IDS \
+       X(BIF0)\
+       X(BIF1)\
+       X(TEXAS_BIF)\
+       X(DPX_BIF)
+#else
+#define RGXDBG_BIF_IDS \
+       X(BIF0)\
+       X(BIF1)\
+       X(TEXAS_BIF)
+#endif
+
+#define RGXDBG_SIDEBAND_TYPES \
+       X(META)\
+       X(TLA)\
+       X(DMA)\
+       X(VDMM)\
+       X(CDM)\
+       X(IPP)\
+       X(PM)\
+       X(TILING)\
+       X(MCU)\
+       X(PDS)\
+       X(PBE)\
+       X(VDMS)\
+       X(IPF)\
+       X(ISP)\
+       X(TPF)\
+       X(USCS)\
+       X(PPP)\
+       X(VCE)\
+       X(TPF_CPF)\
+       X(IPF_CPF)\
+       X(FBCDC)
+
+typedef enum
+{
+#define X(NAME) RGXDBG_##NAME,
+       RGXDBG_BIF_IDS
+#undef X
+} RGXDBG_BIF_ID;
+
+typedef enum
+{
+#define X(NAME) RGXDBG_##NAME,
+       RGXDBG_SIDEBAND_TYPES
+#undef X
+} RGXDBG_SIDEBAND_TYPE;
+
+
+IMG_CHAR* pszPowStateName [] = {
+#define X(NAME)        #NAME,
+       RGXFWIF_POW_STATES
+#undef X
+};
+
+IMG_CHAR* pszBIFNames [] = {
+#define X(NAME)        #NAME,
+       RGXDBG_BIF_IDS
+#undef X
+};
+
+extern IMG_UINT32 g_ui32HostSampleIRQCount;
+
+
+IMG_UINT32 RGXReadWithSP(IMG_UINT32 ui32FWAddr)
+{
+       PVRSRV_DATA        *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[0];
+       PVRSRV_RGXDEV_INFO *psDevInfo    = psDeviceNode->pvDevice;
+       IMG_UINT32         ui32Value     = 0;
+       PVRSRV_ERROR       eError;
+
+       eError = RGXReadMETAAddr(psDevInfo, ui32FWAddr, &ui32Value);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXReadWithSP error: %s", PVRSRVGetErrorStringKM(eError)));
+       }
+
+       return ui32Value;
+}
+
+
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*!
+*******************************************************************************
+
+ @Function     _RGXDecodePMPC
+
+ @Description
+
+ Return the name for the PM managed Page Catalogues
+
+ @Input ui32PC  - Page Catalogue number
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_CHAR* _RGXDecodePMPC(IMG_UINT32 ui32PC)
+{
+       IMG_CHAR* pszPMPC = " (-)";
+
+       switch (ui32PC)
+       {
+               case 0x8: pszPMPC = " (PM-VCE0)"; break;
+               case 0x9: pszPMPC = " (PM-TE0)"; break;
+               case 0xA: pszPMPC = " (PM-ZLS0)"; break;
+               case 0xB: pszPMPC = " (PM-ALIST0)"; break;
+               case 0xC: pszPMPC = " (PM-VCE1)"; break;
+               case 0xD: pszPMPC = " (PM-TE1)"; break;
+               case 0xE: pszPMPC = " (PM-ZLS1)"; break;
+               case 0xF: pszPMPC = " (PM-ALIST1)"; break;
+       }
+
+       return pszPMPC;
+}
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+/*!
+*******************************************************************************
+
+ @Function     _DPXDecodeBIFReqTags
+
+ @Description
+
+ Decode the BIF Tag ID and sideband data fields from DPX_CR_BIF_FAULT_BANK_REQ_STATUS regs
+
+ @Input eBankID                                - BIF identifier
+ @Input ui32TagID           - Tag ID value
+ @Input ui32TagSB           - Tag Sideband data
+ @Output ppszTagID          - Decoded string from the Tag ID
+ @Output ppszTagSB          - Decoded string from the Tag SB
+ @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
+ @Input ui32ScratchBufSize  - Size of the provided buffer
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _DPXDecodeBIFReqTags(RGXDBG_BIF_ID     eBankID,
+                                                                        IMG_UINT32             ui32TagID, 
+                                                                        IMG_UINT32             ui32TagSB, 
+                                                                        IMG_CHAR               **ppszTagID, 
+                                                                        IMG_CHAR               **ppszTagSB,
+                                                                        IMG_CHAR               *pszScratchBuf,
+                                                                        IMG_UINT32             ui32ScratchBufSize)
+{
+       /* default to unknown */
+       IMG_CHAR *pszTagID = "-";
+       IMG_CHAR *pszTagSB = "-";
+
+       PVR_ASSERT(eBankID == RGXDBG_DPX_BIF);
+       PVR_ASSERT(ppszTagID != IMG_NULL);
+
+       PVR_UNREFERENCED_PARAMETER(ui32TagSB);
+       PVR_UNREFERENCED_PARAMETER(pszScratchBuf);
+       PVR_UNREFERENCED_PARAMETER(ui32ScratchBufSize);
+
+       switch (ui32TagID)
+       {
+               case 0x0:
+               {
+                       pszTagID = "MMU";
+                       break;
+               }
+               case 0x1:
+               {
+                       pszTagID = "RS_READ";
+                       break;
+               }
+               case 0x2:
+               {
+                       pszTagID = "RS_WRITE";
+                       break;
+               }
+               case 0x3:
+               {
+                       pszTagID = "RQ";
+                       break;
+               }
+               case 0x4:
+               {
+                       pszTagID = "PU";
+                       break;
+               }
+       } /* switch(TagID) */
+
+       *ppszTagID = pszTagID;
+       *ppszTagSB = pszTagSB;
+}
+#endif
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDecodeBIFReqTags
+
+ @Description
+
+ Decode the BIF Tag ID and sideband data fields from BIF_FAULT_BANK_REQ_STATUS regs
+
+ @Input eBankID                                - BIF identifier
+ @Input ui32TagID           - Tag ID value
+ @Input ui32TagSB           - Tag Sideband data
+ @Output ppszTagID          - Decoded string from the Tag ID
+ @Output ppszTagSB          - Decoded string from the Tag SB
+ @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
+ @Input ui32ScratchBufSize  - Size of the provided buffer
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDecodeBIFReqTags(RGXDBG_BIF_ID     eBankID,
+                                                                        IMG_UINT32             ui32TagID, 
+                                                                        IMG_UINT32             ui32TagSB, 
+                                                                        IMG_CHAR               **ppszTagID, 
+                                                                        IMG_CHAR               **ppszTagSB,
+                                                                        IMG_CHAR               *pszScratchBuf,
+                                                                        IMG_UINT32             ui32ScratchBufSize)
+{
+       /* default to unknown */
+       IMG_CHAR *pszTagID = "-";
+       IMG_CHAR *pszTagSB = "-";
+
+       PVR_ASSERT(ppszTagID != IMG_NULL);
+       PVR_ASSERT(ppszTagSB != IMG_NULL);
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       if (eBankID == RGXDBG_DPX_BIF)
+       {
+               _DPXDecodeBIFReqTags(eBankID, ui32TagID, ui32TagSB, ppszTagID, ppszTagSB, pszScratchBuf, ui32ScratchBufSize);
+               return;
+       }
+#endif
+       
+       switch (ui32TagID)
+       {
+               case 0x0:
+               {
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       if (eBankID == RGXDBG_BIF0)
+                       {
+                               pszTagID = "VRDM";                              
+                       }
+                       else
+                       {
+                               pszTagID = "MMU";
+                               switch (ui32TagSB)
+                               {
+                                       case 0x0: pszTagSB = "Table"; break;
+                                       case 0x1: pszTagSB = "Directory"; break;
+                                       case 0x2: pszTagSB = "Catalogue"; break;
+                               }
+                       }
+#else
+                       pszTagID = "MMU";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Table"; break;
+                               case 0x1: pszTagSB = "Directory"; break;
+                               case 0x2: pszTagSB = "Catalogue"; break;
+                       }
+#endif
+                       break;
+               }
+               case 0x1:
+               {
+                       pszTagID = "TLA";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Pixel data"; break;
+                               case 0x1: pszTagSB = "Command stream data"; break;
+                               case 0x2: pszTagSB = "Fence or flush"; break;
+                       }
+                       break;
+               }
+               case 0x2:
+               {
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       if (eBankID == RGXDBG_BIF0)
+                       {
+                               pszTagID = "SHF";                               
+                       }
+                       else
+                       {
+                               pszTagID = "HOST";
+                       }
+#else
+                       pszTagID = "HOST";
+#endif
+                       break;
+               }
+               case 0x3:
+               {
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       if (eBankID == RGXDBG_BIF0)
+                       {
+                               pszTagID = "SHG";                               
+                       }
+                       else
+                       {
+                               pszTagID = "META";
+                               switch (ui32TagSB)
+                               {
+                                       case 0x0: pszTagSB = "DCache - Thread 0"; break;
+                                       case 0x1: pszTagSB = "ICache - Thread 0"; break;
+                                       case 0x2: pszTagSB = "JTag - Thread 0"; break;
+                                       case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
+                                       case 0x4: pszTagSB = "DCache - Thread "; break;
+                                       case 0x5: pszTagSB = "ICache - Thread 1"; break;
+                                       case 0x6: pszTagSB = "JTag - Thread 1"; break;
+                                       case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
+                               }
+                       }
+#else
+                       pszTagID = "META";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "DCache - Thread 0"; break;
+                               case 0x1: pszTagSB = "ICache - Thread 0"; break;
+                               case 0x2: pszTagSB = "JTag - Thread 0"; break;
+                               case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
+                               case 0x4: pszTagSB = "DCache - Thread "; break;
+                               case 0x5: pszTagSB = "ICache - Thread 1"; break;
+                               case 0x6: pszTagSB = "JTag - Thread 1"; break;
+                               case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
+                       }
+#endif
+                       break;
+               }
+               case 0x4:
+               {
+                       pszTagID = "USC";
+                       OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                  "Cache line %d", (ui32TagSB & 0x3f));
+                       pszTagSB = pszScratchBuf;
+                       break;
+               }
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+               case 0x5:
+               {
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       if (eBankID == RGXDBG_TEXAS_BIF)
+                       {
+                               pszTagID = "PBE";
+                       }
+                       else
+                       {
+                               pszTagID = "RPM";
+                       }
+#else
+                       pszTagID = "PBE";
+#endif
+                       break;
+               }
+               case 0x6:
+               {
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       if (eBankID == RGXDBG_TEXAS_BIF)
+                       {
+                               pszTagID = "ISP";
+                               switch (ui32TagSB)
+                               {
+                                       case 0x00: pszTagSB = "ZLS"; break;
+                                       case 0x20: pszTagSB = "Occlusion Query"; break;
+                               }
+                       }
+                       else
+                       {
+                               pszTagID = "FBA";                               
+                       }
+#else
+                       pszTagID = "ISP";
+                       switch (ui32TagSB)
+                       {
+                               case 0x00: pszTagSB = "ZLS"; break;
+                               case 0x20: pszTagSB = "Occlusion Query"; break;
+                       }
+#endif
+                       break;
+               }
+               case 0x7:
+               {
+                       if (eBankID == RGXDBG_TEXAS_BIF)
+                       {
+                               pszTagID = "IPF";
+                               switch (ui32TagSB)
+                               {
+                                       case 0x0: pszTagSB = "CPF"; break;
+                                       case 0x1: pszTagSB = "DBSC"; break;
+                                       case 0x2:
+                                       case 0x4:
+                                       case 0x6:
+                                       case 0x8: pszTagSB = "Control Stream"; break;
+                                       case 0x3:
+                                       case 0x5:
+                                       case 0x7:
+                                       case 0x9: pszTagSB = "Primitive Block"; break;
+                               }
+                       }
+                       else
+                       {
+                               pszTagID = "IPP";
+                               switch (ui32TagSB)
+                               {
+                                       case 0x0: pszTagSB = "Macrotile Header"; break;
+                                       case 0x1: pszTagSB = "Region Header"; break;
+                               }
+                       }
+                       break;
+               }
+#else /* RGX_FEATURE_CLUSTER_GROUPING */
+               case 0x5:
+               {
+                       pszTagID = "PBE";
+                       break;
+               }
+               case 0x6:
+               {
+                       pszTagID = "ISP";
+                       switch (ui32TagSB)
+                       {
+                               case 0x00: pszTagSB = "ZLS"; break;
+                               case 0x20: pszTagSB = "Occlusion Query"; break;
+                       }
+                       break;
+               }
+               case 0x7:
+               {
+                       pszTagID = "IPF";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Macrotile Header"; break;
+                               case 0x1: pszTagSB = "Region Header"; break;
+                               case 0x2: pszTagSB = "DBSC"; break;
+                               case 0x3: pszTagSB = "CPF"; break;
+                               case 0x4: 
+                               case 0x6:
+                               case 0x8: pszTagSB = "Control Stream"; break;
+                               case 0x5: 
+                               case 0x7:
+                               case 0x9: pszTagSB = "Primitive Block"; break;
+                       }
+                       break;
+               }
+#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+               case 0x8:
+               {
+                       pszTagID = "CDM";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Control Stream"; break;
+                               case 0x1: pszTagSB = "Indirect Data"; break;
+                               case 0x2: pszTagSB = "Event Write"; break;
+                               case 0x3: pszTagSB = "Context State"; break;
+                       }
+                       break;
+               }
+               case 0x9:
+               {
+                       pszTagID = "VDM";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Control Stream"; break;
+                               case 0x1: pszTagSB = "PPP State"; break;
+                               case 0x2: pszTagSB = "Index Data"; break;
+                               case 0x4: pszTagSB = "Call Stack"; break;
+                               case 0x8: pszTagSB = "Context State"; break;
+                       }
+                       break;
+               }
+               case 0xA:
+               {
+                       pszTagID = "PM";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "PMA_TAFSTACK"; break;
+                               case 0x1: pszTagSB = "PMA_TAMLIST"; break;
+                               case 0x2: pszTagSB = "PMA_3DFSTACK"; break;
+                               case 0x3: pszTagSB = "PMA_3DMLIST"; break;
+                               case 0x4: pszTagSB = "PMA_PMCTX0"; break;
+                               case 0x5: pszTagSB = "PMA_PMCTX1"; break;
+                               case 0x6: pszTagSB = "PMA_MAVP"; break;
+                               case 0x7: pszTagSB = "PMA_UFSTACK"; break;
+                               case 0x8: pszTagSB = "PMD_TAFSTACK"; break;
+                               case 0x9: pszTagSB = "PMD_TAMLIST"; break;
+                               case 0xA: pszTagSB = "PMD_3DFSTACK"; break;
+                               case 0xB: pszTagSB = "PMD_3DMLIST"; break;
+                               case 0xC: pszTagSB = "PMD_PMCTX0"; break;
+                               case 0xD: pszTagSB = "PMD_PMCTX1"; break;
+                               case 0xF: pszTagSB = "PMD_UFSTACK"; break;
+                               case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break;
+                               case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break;
+                               case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break;
+                               case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break;
+                               case 0x14: pszTagSB = "PMA_TAUFSTACK"; break;
+                               case 0x15: pszTagSB = "PMA_3DUFSTACK"; break;
+                               case 0x16: pszTagSB = "PMD_TAUFSTACK"; break;
+                               case 0x17: pszTagSB = "PMD_3DUFSTACK"; break;
+                               case 0x18: pszTagSB = "PMA_TAVFP"; break;
+                               case 0x19: pszTagSB = "PMD_3DVFP"; break;
+                               case 0x1A: pszTagSB = "PMD_TAVFP"; break;
+                       }
+                       break;
+               }
+               case 0xB:
+               {
+                       pszTagID = "TA";
+                       switch (ui32TagSB)
+                       {
+                               case 0x1: pszTagSB = "VCE"; break;
+                               case 0x2: pszTagSB = "TPC"; break;
+                               case 0x3: pszTagSB = "TE Control Stream"; break;
+                               case 0x4: pszTagSB = "TE Region Header"; break;
+                               case 0x5: pszTagSB = "TE Render Target Cache"; break;
+                               case 0x6: pszTagSB = "TEAC Render Target Cache"; break;
+                               case 0x7: pszTagSB = "VCE Render Target Cache"; break;
+                               case 0x8: pszTagSB = "PPP Context State"; break;
+                       }
+                       break;
+               }
+               case 0xC:
+               {
+                       pszTagID = "TPF";
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "TPF0: Primitive Block"; break;
+                               case 0x1: pszTagSB = "TPF0: Depth Bias"; break;
+                               case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break;
+                               case 0x3: pszTagSB = "CPF - Tables"; break;
+                               case 0x4: pszTagSB = "TPF1: Primitive Block"; break;
+                               case 0x5: pszTagSB = "TPF1: Depth Bias"; break;
+                               case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break;
+                               case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break;
+                               case 0x8: pszTagSB = "TPF2: Primitive Block"; break;
+                               case 0x9: pszTagSB = "TPF2: Depth Bias"; break;
+                               case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break;
+                               case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break;
+                               case 0xC: pszTagSB = "TPF3: Primitive Block"; break;
+                               case 0xD: pszTagSB = "TPF3: Depth Bias"; break;
+                               case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break;
+                               case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break;
+                       }
+                       break;
+               }
+               case 0xD:
+               {
+                       pszTagID = "PDS";
+                       break;
+               }
+               case 0xE:
+               {
+                       pszTagID = "MCU";
+                       {
+                               IMG_UINT32 ui32Burst = (ui32TagSB >> 5) & 0x7;
+                               IMG_UINT32 ui32GroupEnc = (ui32TagSB >> 2) & 0x7;
+                               IMG_UINT32 ui32Group = ui32TagSB & 0x3;
+
+                               IMG_CHAR* pszBurst = "";
+                               IMG_CHAR* pszGroupEnc = "";
+                               IMG_CHAR* pszGroup = "";
+
+                               switch (ui32Burst)
+                               {
+                                       case 0x0:
+                                       case 0x1: pszBurst = "128bit word within the Lower 256bits"; break;
+                                       case 0x2:
+                                       case 0x3: pszBurst = "128bit word within the Upper 256bits"; break;
+                                       case 0x4: pszBurst = "Lower 256bits"; break;
+                                       case 0x5: pszBurst = "Upper 256bits"; break;
+                                       case 0x6: pszBurst = "512 bits"; break;
+                               }
+                               switch (ui32GroupEnc)
+                               {
+                                       case 0x0: pszGroupEnc = "TPUA_USC"; break;
+                                       case 0x1: pszGroupEnc = "TPUB_USC"; break;
+                                       case 0x2: pszGroupEnc = "USCA_USC"; break;
+                                       case 0x3: pszGroupEnc = "USCB_USC"; break;
+                                       case 0x4: pszGroupEnc = "PDS_USC"; break;
+#if (RGX_FEATURE_NUM_CLUSTERS < 6)
+                                       case 0x5: pszGroupEnc = "PDSRW"; break;
+#elif (RGX_FEATURE_NUM_CLUSTERS == 6)
+                                       case 0x5: pszGroupEnc = "UPUC_USC"; break;
+                                       case 0x6: pszGroupEnc = "TPUC_USC"; break;
+                                       case 0x7: pszGroupEnc = "PDSRW"; break;
+#endif
+                               }
+                               switch (ui32Group)
+                               {
+                                       case 0x0: pszGroup = "Banks 0-3"; break;
+                                       case 0x1: pszGroup = "Banks 4-7"; break;
+                                       case 0x2: pszGroup = "Banks 8-11"; break;
+                                       case 0x3: pszGroup = "Banks 12-15"; break;
+                               }
+
+                               OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                                               "%s, %s, %s", pszBurst, pszGroupEnc, pszGroup);
+                               pszTagSB = pszScratchBuf;
+                       }
+                       break;
+               }
+               case 0xF:
+               {
+                       pszTagID = "FB_CDC";
+#if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE)
+                       {
+                               IMG_UINT32 ui32Req   = (ui32TagSB >> 0) & 0xf;
+                               IMG_UINT32 ui32MCUSB = (ui32TagSB >> 4) & 0x3;
+                               IMG_CHAR* pszReqOrig = "";
+
+                               switch (ui32Req)
+                               {
+                                       case 0x0: pszReqOrig = "FBC Request, originator ZLS"; break;
+                                       case 0x1: pszReqOrig = "FBC Request, originator PBE"; break;
+                                       case 0x2: pszReqOrig = "FBC Request, originator Host"; break;
+                                       case 0x3: pszReqOrig = "FBC Request, originator TLA"; break;
+                                       case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break;
+                                       case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break;
+                                       case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
+                                       case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break;
+                                       case 0x8: pszReqOrig = "FBC Request, originator ZLS Requester Fence"; break;
+                                       case 0x9: pszReqOrig = "FBC Request, originator PBE Requester Fence"; break;
+                                       case 0xa: pszReqOrig = "FBC Request, originator Host Requester Fence"; break;
+                                       case 0xb: pszReqOrig = "FBC Request, originator TLA Requester Fence"; break;
+                                       case 0xc: pszReqOrig = "Reserved"; break;
+                                       case 0xd: pszReqOrig = "Reserved"; break;
+                                       case 0xe: pszReqOrig = "FBDC Request, originator FBCDC(Host) Memory Fence"; break;
+                                       case 0xf: pszReqOrig = "FBDC Request, originator FBCDC(TLA) Memory Fence"; break;
+                               }
+                               OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                          "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
+                               pszTagSB = pszScratchBuf;
+                       }
+#else
+                       {
+                               IMG_UINT32 ui32Req   = (ui32TagSB >> 2) & 0x7;
+                               IMG_UINT32 ui32MCUSB = (ui32TagSB >> 0) & 0x3;
+                               IMG_CHAR* pszReqOrig = "";
+
+                               switch (ui32Req)
+                               {
+                                       case 0x0: pszReqOrig = "FBC Request, originator ZLS";   break;
+                                       case 0x1: pszReqOrig = "FBC Request, originator PBE";   break;
+                                       case 0x2: pszReqOrig = "FBC Request, originator Host";  break;
+                                       case 0x3: pszReqOrig = "FBC Request, originator TLA";   break;
+                                       case 0x4: pszReqOrig = "FBDC Request, originator ZLS";  break;
+                                       case 0x5: pszReqOrig = "FBDC Request, originator MCU";  break;
+                                       case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
+                                       case 0x7: pszReqOrig = "FBDC Request, originator TLA";  break;
+                               }
+                               OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                          "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
+                               pszTagSB = pszScratchBuf;
+                       }
+#endif
+                       break;
+               }
+       } /* switch(TagID) */
+
+       *ppszTagID = pszTagID;
+       *ppszTagSB = pszTagSB;
+}
+#endif
+
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*!
+*******************************************************************************
+
+ @Function     _RGXDecodeMMULevel
+
+ @Description
+
+ Return the name for the MMU level that faulted.
+
+ @Input ui32MMULevel    - MMU level
+
+ @Return   IMG_CHAR* to the sting describing the MMU level that faulted.
+
+******************************************************************************/
+static IMG_CHAR* _RGXDecodeMMULevel(IMG_UINT32 ui32MMULevel)
+{
+       IMG_CHAR* pszMMULevel = "";
+
+       switch (ui32MMULevel)
+       {
+               case 0x0: pszMMULevel = " (Page Table)"; break;
+               case 0x1: pszMMULevel = " (Page Directory)"; break;
+               case 0x2: pszMMULevel = " (Page Catalog)"; break;
+               case 0x3: pszMMULevel = " (Cat Base)"; break;
+       }
+
+       return pszMMULevel;
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDecodeMMUReqTags
+
+ @Description
+
+ Decodes the MMU Tag ID and Sideband data fields from RGX_CR_MMU_FAULT_META_STATUS and
+ RGX_CR_MMU_FAULT_STATUS regs.
+
+ @Input ui32TagID           - Tag ID value
+ @Input ui32TagSB           - Tag Sideband data
+ @Output ppszTagID          - Decoded string from the Tag ID
+ @Output ppszTagSB          - Decoded string from the Tag SB
+ @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
+ @Input ui32ScratchBufSize  - Size of the provided buffer
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDecodeMMUReqTags(IMG_UINT32  ui32TagID, 
+                                                                        IMG_UINT32  ui32TagSB, 
+                                     IMG_CHAR    **ppszTagID, 
+                                                                        IMG_CHAR    **ppszTagSB,
+                                                                        IMG_CHAR    *pszScratchBuf,
+                                                                        IMG_UINT32  ui32ScratchBufSize)
+{
+       IMG_INT32  i32SideBandType = -1;
+       IMG_CHAR   *pszTagID = "-";
+       IMG_CHAR   *pszTagSB = "-";
+
+       PVR_ASSERT(ppszTagID != IMG_NULL);
+       PVR_ASSERT(ppszTagSB != IMG_NULL);
+
+       switch (ui32TagID)
+       {
+               case  0: pszTagID = "META (Jones)"; i32SideBandType = RGXDBG_META; break;
+               case  1: pszTagID = "TLA (Jones)"; i32SideBandType = RGXDBG_TLA; break;
+#if defined(RGX_FEATURE_META_DMA)
+               case  2: pszTagID = "DMA (Jones)"; i32SideBandType = RGXDBG_DMA; break;
+#endif
+               case  3: pszTagID = "VDMM (Jones)"; i32SideBandType = RGXDBG_VDMM; break;
+               case  4: pszTagID = "CDM (Jones)"; i32SideBandType = RGXDBG_CDM; break;
+               case  5: pszTagID = "IPP (Jones)"; i32SideBandType = RGXDBG_IPP; break;
+               case  6: pszTagID = "PM (Jones)"; i32SideBandType = RGXDBG_PM; break;
+               case  7: pszTagID = "Tiling (Jones)"; i32SideBandType = RGXDBG_TILING; break;
+               case  8: pszTagID = "MCU (Texas 0)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case  9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
+               case 10: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE break;
+               case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case  9: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE break;
+               case 10: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
+               case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case  9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
+               case 10: pszTagID = "PBE0 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break;
+               case 11: pszTagID = "PBE1 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 12: pszTagID = "VDMS (Black Pearl 0)"; i32SideBandType = RGXDBG_VDMS; break;
+               case 13: pszTagID = "IPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF; break;
+               case 14: pszTagID = "ISP (Black Pearl 0)"; i32SideBandType = RGXDBG_ISP; break;
+               case 15: pszTagID = "TPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF; break;
+               case 16: pszTagID = "USCS (Black Pearl 0)"; i32SideBandType = RGXDBG_USCS; break;
+               case 17: pszTagID = "PPP (Black Pearl 0)"; i32SideBandType = RGXDBG_PPP; break;
+#if defined(HW_ERN_47229)
+               case 18: pszTagID = "VCE (Black Pearl 0)"; i32SideBandType = RGXDBG_VCE; break;
+               case 19: pszTagID = "FBCDC (Black Pearl 0)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 18: pszTagID = "TPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF_CPF; break;
+               case 19: pszTagID = "IPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF_CPF; break;
+#endif
+               case 20: pszTagID = "MCU (Texas 1)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
+               case 22: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE break;
+               case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 21: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE break;
+               case 22: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
+               case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
+               case 22: pszTagID = "PBE0 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break;
+               case 23: pszTagID = "PBE1 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 24: pszTagID = "MCU (Texas 2)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
+               case 26: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE break;
+               case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 25: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE break;
+               case 26: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
+               case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
+               case 26: pszTagID = "PBE0 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break;
+               case 27: pszTagID = "PBE1 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 28: pszTagID = "VDMS (Black Pearl 1)"; i32SideBandType = RGXDBG_VDMS; break;
+               case 29: pszTagID = "IPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF; break;
+               case 30: pszTagID = "ISP (Black Pearl 1)"; i32SideBandType = RGXDBG_ISP; break;
+               case 31: pszTagID = "TPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF; break;
+               case 32: pszTagID = "USCS (Black Pearl 1)"; i32SideBandType = RGXDBG_USCS; break;
+               case 33: pszTagID = "PPP (Black Pearl 1)"; i32SideBandType = RGXDBG_PPP; break;
+#if defined(HW_ERN_47229)
+               case 34: pszTagID = "VCE (Black Pearl 1)"; i32SideBandType = RGXDBG_VCE; break;
+               case 35: pszTagID = "FBCDC (Black Pearl 1)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 34: pszTagID = "TPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF_CPF; break;
+               case 35: pszTagID = "IPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF_CPF; break;
+#endif
+               case 36: pszTagID = "MCU (Texas 3)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
+               case 38: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE break;
+               case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 37: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE break;
+               case 38: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
+               case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
+               case 38: pszTagID = "PBE0 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break;
+               case 39: pszTagID = "PBE1 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 40: pszTagID = "MCU (Texas 4)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
+               case 42: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE break;
+               case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 41: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE break;
+               case 42: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
+               case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
+               case 42: pszTagID = "PBE0 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break;
+               case 43: pszTagID = "PBE1 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 44: pszTagID = "VDMS (Black Pearl 2)"; i32SideBandType = RGXDBG_VDMS; break;
+               case 45: pszTagID = "IPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF; break;
+               case 46: pszTagID = "ISP (Black Pearl 2)"; i32SideBandType = RGXDBG_ISP; break;
+               case 47: pszTagID = "TPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF; break;
+               case 48: pszTagID = "USCS (Black Pearl 2)"; i32SideBandType = RGXDBG_USCS; break;
+               case 49: pszTagID = "PPP (Black Pearl 2)"; i32SideBandType = RGXDBG_PPP; break;
+#if defined(HW_ERN_47229)
+               case 50: pszTagID = "VCE (Black Pearl 2)"; i32SideBandType = RGXDBG_VCE; break;
+               case 51: pszTagID = "FBCDC (Black Pearl 2)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 50: pszTagID = "TPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF_CPF; break;
+               case 51: pszTagID = "IPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF_CPF; break;
+#endif
+               case 52: pszTagID = "MCU (Texas 5)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
+               case 54: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE break;
+               case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 53: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE break;
+               case 54: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
+               case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
+               case 54: pszTagID = "PBE0 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break;
+               case 55: pszTagID = "PBE1 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 56: pszTagID = "MCU (Texas 6)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
+               case 58: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE break;
+               case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 57: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE break;
+               case 58: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
+               case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
+               case 58: pszTagID = "PBE0 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break;
+               case 59: pszTagID = "PBE1 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+               case 60: pszTagID = "VDMS (Black Pearl 3)"; i32SideBandType = RGXDBG_VDMS; break;
+               case 61: pszTagID = "IPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF; break;
+               case 62: pszTagID = "ISP (Black Pearl 3)"; i32SideBandType = RGXDBG_ISP; break;
+               case 63: pszTagID = "TPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF; break;
+               case 64: pszTagID = "USCS (Black Pearl 3)"; i32SideBandType = RGXDBG_USCS; break;
+               case 65: pszTagID = "PPP (Black Pearl 3)"; i32SideBandType = RGXDBG_PPP; break;
+#if defined(HW_ERN_47229)
+               case 66: pszTagID = "VCE (Black Pearl 3)"; i32SideBandType = RGXDBG_VCE; break;
+               case 67: pszTagID = "FBCDC (Black Pearl 3)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 66: pszTagID = "TPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF_CPF; break;
+               case 67: pszTagID = "IPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF_CPF; break;
+#endif
+               case 68: pszTagID = "MCU (Texas 7)"; i32SideBandType = RGXDBG_MCU; break;
+#if defined(HW_ERN_47229)
+               case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
+               case 70: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE break;
+               case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break;
+#elif defined(FIX_HW_BRN_50539)
+               case 69: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE break;
+               case 70: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
+               case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break;
+#else
+               case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
+               case 70: pszTagID = "PBE0 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break;
+               case 71: pszTagID = "PBE1 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break;
+#endif
+       }
+       
+       switch (i32SideBandType)
+       {
+               case RGXDBG_META:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "DCache - Thread 0"; break;
+                               case 0x1: pszTagSB = "ICache - Thread 0"; break;
+                               case 0x2: pszTagSB = "JTag - Thread 0"; break;
+                               case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
+                               case 0x4: pszTagSB = "DCache - Thread 1"; break;
+                               case 0x5: pszTagSB = "ICache - Thread 1"; break;
+                               case 0x6: pszTagSB = "JTag - Thread 1"; break;
+                               case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_TLA:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Pixel data"; break;
+                               case 0x1: pszTagSB = "Command stream data"; break;
+                               case 0x2: pszTagSB = "Fence or flush"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_VDMM:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Control Stream - Read Only"; break;
+                               case 0x1: pszTagSB = "PPP State - Read Only"; break;
+                               case 0x2: pszTagSB = "Indices - Read Only"; break;
+                               case 0x4: pszTagSB = "Call Stack - Read/Write"; break;
+                               case 0x6: pszTagSB = "DrawIndirect - Read Only"; break;
+                               case 0xA: pszTagSB = "Context State - Write Only"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_CDM:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Control Stream"; break;
+                               case 0x1: pszTagSB = "Indirect Data"; break;
+                               case 0x2: pszTagSB = "Event Write"; break;
+                               case 0x3: pszTagSB = "Context State"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_IPP:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Macrotile Header"; break;
+                               case 0x1: pszTagSB = "Region Header"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_PM:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "PMA_TAFSTACK"; break;
+                               case 0x1: pszTagSB = "PMA_TAMLIST"; break;
+                               case 0x2: pszTagSB = "PMA_3DFSTACK"; break;
+                               case 0x3: pszTagSB = "PMA_3DMLIST"; break;
+                               case 0x4: pszTagSB = "PMA_PMCTX0"; break;
+                               case 0x5: pszTagSB = "PMA_PMCTX1"; break;
+                               case 0x6: pszTagSB = "PMA_MAVP"; break;
+                               case 0x7: pszTagSB = "PMA_UFSTACK"; break;
+                               case 0x8: pszTagSB = "PMD_TAFSTACK"; break;
+                               case 0x9: pszTagSB = "PMD_TAMLIST"; break;
+                               case 0xA: pszTagSB = "PMD_3DFSTACK"; break;
+                               case 0xB: pszTagSB = "PMD_3DMLIST"; break;
+                               case 0xC: pszTagSB = "PMD_PMCTX0"; break;
+                               case 0xD: pszTagSB = "PMD_PMCTX1"; break;
+                               case 0xF: pszTagSB = "PMD_UFSTACK"; break;
+                               case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break;
+                               case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break;
+                               case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break;
+                               case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break;
+                               case 0x14: pszTagSB = "PMA_TAUFSTACK"; break;
+                               case 0x15: pszTagSB = "PMA_3DUFSTACK"; break;
+                               case 0x16: pszTagSB = "PMD_TAUFSTACK"; break;
+                               case 0x17: pszTagSB = "PMD_3DUFSTACK"; break;
+                               case 0x18: pszTagSB = "PMA_TAVFP"; break;
+                               case 0x19: pszTagSB = "PMD_3DVFP"; break;
+                               case 0x1A: pszTagSB = "PMD_TAVFP"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_TILING:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "PSG Control Stream TP0"; break;
+                               case 0x1: pszTagSB = "TPC TP0"; break;
+                               case 0x2: pszTagSB = "VCE0"; break;
+                               case 0x3: pszTagSB = "VCE1"; break;
+                               case 0x4: pszTagSB = "PSG Control Stream TP1"; break;
+                               case 0x5: pszTagSB = "TPC TP1"; break;
+                               case 0x8: pszTagSB = "PSG Region Header TP0"; break;
+                               case 0xC: pszTagSB = "PSG Region Header TP1"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_VDMS:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "Context State - Write Only"; break;
+                       }
+                       break;
+               }
+               
+               case RGXDBG_IPF:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x00:
+                               case 0x20: pszTagSB = "CPF"; break;
+                               case 0x01: pszTagSB = "DBSC"; break;
+                               case 0x02:
+                               case 0x04:
+                               case 0x06:
+                               case 0x08:
+                               case 0x0A:
+                               case 0x0C:
+                               case 0x0E:
+                               case 0x10: pszTagSB = "Control Stream"; break;
+                               case 0x03:
+                               case 0x05:
+                               case 0x07:
+                               case 0x09:
+                               case 0x0B:
+                               case 0x0D:
+                               case 0x0F:
+                               case 0x11: pszTagSB = "Primitive Block"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_ISP:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x00: pszTagSB = "ZLS read/write"; break;
+                               case 0x20: pszTagSB = "Occlusion query read/write"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_TPF:
+               {
+                       switch (ui32TagSB)
+                       {
+                               case 0x0: pszTagSB = "TPF0: Primitive Block"; break;
+                               case 0x1: pszTagSB = "TPF0: Depth Bias"; break;
+                               case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break;
+                               case 0x3: pszTagSB = "CPF - Tables"; break;
+                               case 0x4: pszTagSB = "TPF1: Primitive Block"; break;
+                               case 0x5: pszTagSB = "TPF1: Depth Bias"; break;
+                               case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break;
+                               case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break;
+                               case 0x8: pszTagSB = "TPF2: Primitive Block"; break;
+                               case 0x9: pszTagSB = "TPF2: Depth Bias"; break;
+                               case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break;
+                               case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break;
+                               case 0xC: pszTagSB = "TPF3: Primitive Block"; break;
+                               case 0xD: pszTagSB = "TPF3: Depth Bias"; break;
+                               case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break;
+                               case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break;
+                       }
+                       break;
+               }
+
+               case RGXDBG_FBCDC:
+               {
+                       IMG_UINT32 ui32Req   = (ui32TagSB >> 0) & 0xf;
+                       IMG_UINT32 ui32MCUSB = (ui32TagSB >> 4) & 0x3;
+                       IMG_CHAR* pszReqOrig = "";
+
+                       switch (ui32Req)
+                       {
+                               case 0x0: pszReqOrig = "FBC Request, originator ZLS";  break;
+                               case 0x1: pszReqOrig = "FBC Request, originator PBE"; break;
+                               case 0x2: pszReqOrig = "FBC Request, originator Host"; break;
+                               case 0x3: pszReqOrig = "FBC Request, originator TLA"; break;
+                               case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break;
+                               case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break;
+                               case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
+                               case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break;
+                               case 0x8: pszReqOrig = "FBC Request, originator ZLS Requester Fence"; break;
+                               case 0x9: pszReqOrig = "FBC Request, originator PBE Requester Fence"; break;
+                               case 0xa: pszReqOrig = "FBC Request, originator Host Requester Fence"; break;
+                               case 0xb: pszReqOrig = "FBC Request, originator TLA Requester Fence"; break;
+                               case 0xc: pszReqOrig = "Reserved"; break;
+                               case 0xd: pszReqOrig = "Reserved"; break;
+                               case 0xe: pszReqOrig = "FBDC Request, originator FBCDC(Host) Memory Fence"; break;
+                               case 0xf: pszReqOrig = "FBDC Request, originator FBCDC(TLA) Memory Fence"; break;
+                       }
+                       OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                  "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
+                       pszTagSB = pszScratchBuf;
+                       break;
+               }
+
+               case RGXDBG_MCU:
+               {
+                       IMG_UINT32 ui32SetNumber = (ui32TagSB >> 5) & 0x7;
+                       IMG_UINT32 ui32WayNumber = (ui32TagSB >> 2) & 0x7;
+                       IMG_UINT32 ui32Group     = ui32TagSB & 0x3;
+
+                       IMG_CHAR* pszGroup = "";
+
+                       switch (ui32Group)
+                       {
+                               case 0x0: pszGroup = "Banks 0-1"; break;
+                               case 0x1: pszGroup = "Banks 2-3"; break;
+                               case 0x2: pszGroup = "Banks 4-5"; break;
+                               case 0x3: pszGroup = "Banks 6-7"; break;
+                       }
+
+                       OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
+                                  "Set=%d, Way=%d, %s", ui32SetNumber, ui32WayNumber, pszGroup);
+                       pszTagSB = pszScratchBuf;
+                       break;
+               }
+
+               default:
+               {
+                       OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, "SB=0x%02x", ui32TagSB);
+                       pszTagSB = pszScratchBuf;
+                       break;
+               }
+       }
+
+       *ppszTagID = pszTagID;
+       *ppszTagSB = pszTagSB;
+}
+#endif
+
+
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+
+typedef enum _DEVICEMEM_HISTORY_QUERY_INDEX_
+{
+       DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING,
+       DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED,
+       DEVICEMEM_HISTORY_QUERY_INDEX_NEXT,
+       DEVICEMEM_HISTORY_QUERY_INDEX_COUNT,
+} DEVICEMEM_HISTORY_QUERY_INDEX;
+
+/*!
+*******************************************************************************
+
+ @Function     _PrintDevicememHistoryQueryResult
+
+ @Description
+
+ Print details of a single result from a DevicememHistory query
+
+ @Input pfnDumpDebugPrintf       - Debug printf function
+ @Input psResult                 - The DevicememHistory result to be printed
+ @Input ui32Index                - The index of the result
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _PrintDevicememHistoryQueryResult(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                                               DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult,
+                                                               IMG_UINT32 ui32Index)
+{
+       IMG_UINT32 ui32Remainder;
+       PVR_DUMPDEBUG_LOG(("  [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC
+                               " Size: " IMG_DEVMEM_SIZE_FMTSPEC
+                               " Allocated: %c Modified %llu us ago (abs time %llu us)",
+                                                                       ui32Index,
+                                                                       psResult->szString,
+                                       (unsigned long long) psResult->sBaseDevVAddr.uiAddr,
+                                       (unsigned long long) psResult->uiSize,
+                                       psResult->bAllocated ? 'Y' : 'N',
+                                       (unsigned long long) OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder),
+                                       (unsigned long long) OSDivide64r64(psResult->ui64When, 1000, &ui32Remainder)));
+}
+
+/*!
+*******************************************************************************
+
+ @Function     _PrintDevicememHistoryQueryOut
+
+ @Description
+
+ Print details of all the results from a DevicememHistory query
+
+ @Input pfnDumpDebugPrintf       - Debug printf function
+ @Input psResult                 - The DevicememHistory result to be printed
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _PrintDevicememHistoryQueryOut(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut)
+{
+       IMG_UINT32 i;
+
+       if(psQueryOut->ui32NumResults == 0)
+       {
+               PVR_DUMPDEBUG_LOG(("  No results"));
+       }
+       else
+       {
+               for(i = 0; i < psQueryOut->ui32NumResults; i++)
+               {
+                       _PrintDevicememHistoryQueryResult(pfnDumpDebugPrintf, &psQueryOut->sResults[i], i);
+               }
+       }
+}
+
+/* table of HW page size values and the equivalent */
+static const unsigned int aui32HWPageSizeTable[][2] =
+{
+       { 0, PVRSRV_4K_PAGE_SIZE },
+       { 1, PVRSRV_16K_PAGE_SIZE },
+       { 2, PVRSRV_64K_PAGE_SIZE },
+       { 3, PVRSRV_256K_PAGE_SIZE },
+       { 4, PVRSRV_1M_PAGE_SIZE },
+       { 5, PVRSRV_2M_PAGE_SIZE }
+};
+
+/*!
+*******************************************************************************
+
+ @Function     _PageSizeHWToBytes
+
+ @Description
+
+ Convert a HW page size value to its size in bytes
+
+ @Input ui32PageSizeHW     - The HW page size value
+
+ @Return   IMG_UINT32      The page size in bytes
+
+******************************************************************************/
+static IMG_UINT32 _PageSizeHWToBytes(IMG_UINT32 ui32PageSizeHW)
+{
+       PVR_ASSERT(ui32PageSizeHW <= 5);
+
+       return aui32HWPageSizeTable[ui32PageSizeHW][1];
+}
+
+/*!
+*******************************************************************************
+
+ @Function     _GetDevicememHistoryData
+
+ @Description
+
+ Get the DevicememHistory results for the given PID and faulting device virtual address.
+ The function will query DevicememHistory for information about the faulting page, as well
+ as the page before and after.
+
+ @Input uiPID              - The process ID to search for allocations belonging to
+ @Input sFaultDevVAddr     - The device address to search for allocations at/before/after
+ @Input asQueryOut         - Storage for the query results
+ @Input ui32PageSizeBytes  - Faulted page size in bytes
+
+ @Return IMG_BOOL          - IMG_TRUE if any results were found for this page fault
+
+******************************************************************************/
+static IMG_BOOL _GetDevicememHistoryData(IMG_PID uiPID, IMG_DEV_VIRTADDR sFaultDevVAddr,
+                                                       DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT],
+                                                       IMG_UINT32 ui32PageSizeBytes)
+{
+       IMG_UINT32 i;
+       DEVICEMEM_HISTORY_QUERY_IN sQueryIn;
+       IMG_BOOL bAnyHits = IMG_FALSE;
+
+       sQueryIn.uiPID = uiPID;
+
+       /* query the DevicememHistory about the preceding / faulting / next page */
+
+       for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++)
+       {
+               IMG_BOOL bHits;
+
+               switch(i)
+               {
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING:
+                               sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) - 1;
+                               break;
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED:
+                               sQueryIn.sDevVAddr = sFaultDevVAddr;
+                               break;
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT:
+                               sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) + ui32PageSizeBytes;
+                               break;
+               }
+
+               bHits = DevicememHistoryQuery(&sQueryIn, &asQueryOut[i]);
+
+               if(bHits)
+               {
+                       bAnyHits = IMG_TRUE;
+               }
+       }
+
+       return bAnyHits;
+}
+
+/* stored data about one page fault */
+typedef struct _FAULT_INFO_
+{
+       RGXMEM_PROCESS_INFO sProcessInfo;
+       IMG_DEV_VIRTADDR sFaultDevVAddr;
+       DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT];
+       /* the CR timer value at the time of the fault, recorded by the FW.
+        * used to differentiate different page faults
+        */
+       IMG_UINT64 ui64CRTimer;
+       /* time when this FAULT_INFO entry was added. used for timing
+        * reference against the map/unmap information
+        */
+       IMG_UINT64 ui64When;
+} FAULT_INFO;
+
+/* history list of page faults.
+ * Keeps the fist `n` page faults and the last `n` page faults, like the FW
+ * HWR log
+ */
+typedef struct _FAULT_INFO_LOG_
+{
+       IMG_UINT32 ui32Head;
+       IMG_UINT32 ui32NumWrites;
+       /* the number of faults in this log need not correspond exactly to
+        * the HWINFO number of the FW, as the FW HWINFO log may contain
+        * non-page fault HWRs
+        */
+       FAULT_INFO asFaults[RGXFWIF_HWINFO_MAX];
+} FAULT_INFO_LOG;
+
+static FAULT_INFO_LOG gsFaultInfoLog = { 0 };
+
+/*!
+*******************************************************************************
+
+ @Function     _QueryFaultInfo
+
+ @Description
+
+ Searches the local list of previously analysed page faults to see if the given
+ fault has already been analysed and if so, returns a pointer to the analysis
+ objbect (FAULT_INFO *), otherwise returns NULL.
+
+ @Input pfnDumpDebugPrintf       - The debug printf function
+ @Input sFaultDevVAddr           - The faulting device virtual address
+ @Input ui64CRTimer              - The CR timer value recorded by the FW at the time of the fault
+
+ @Return   FAULT_INFO* Pointer to an existing fault analysis structure if found, otherwise IMG_NULL
+
+******************************************************************************/
+static FAULT_INFO *_QueryFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                                               IMG_DEV_VIRTADDR sFaultDevVAddr,
+                                                               IMG_UINT64 ui64CRTimer)
+{
+       IMG_UINT32 i;
+
+       for(i = 0; i < MIN(gsFaultInfoLog.ui32NumWrites, RGXFWIF_HWINFO_MAX); i++)
+       {
+               if((gsFaultInfoLog.asFaults[i].ui64CRTimer == ui64CRTimer) &&
+                       (gsFaultInfoLog.asFaults[i].sFaultDevVAddr.uiAddr == sFaultDevVAddr.uiAddr))
+                       {
+                               return &gsFaultInfoLog.asFaults[i];
+                       }
+       }
+
+       return IMG_NULL;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     _AddFaultInfo
+
+ @Description
+
+ Add the given page fault information to the page fault log.
+
+
+ @Input psProcessInfo        - Information about the user process which caused the page fault
+ @Input sFaultDevVAddr       - The faulting device virtual address
+ @Input ui64CRTimer          - The CR timer value recorded by the FW at the time of the fault
+ @Input asQueryOut           - The DevicememHistory query information with the allocations relating to the fault
+
+ @Return   FAULT_INFO* Pointer to the newly added record
+
+******************************************************************************/
+static FAULT_INFO *_AddFaultInfo(RGXMEM_PROCESS_INFO *psProcessInfo,
+                                               IMG_DEV_VIRTADDR sFaultDevVAddr,
+                                               IMG_UINT64 ui64CRTimer,
+                                               DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT])
+{
+       IMG_UINT32 ui32Head = gsFaultInfoLog.ui32Head;
+       FAULT_INFO *psInfo = &gsFaultInfoLog.asFaults[ui32Head];
+
+       if(gsFaultInfoLog.ui32Head < RGXFWIF_HWINFO_MAX - 1)
+       {
+               gsFaultInfoLog.ui32Head++;
+       }
+       else
+       {
+               /* wrap back to the first of the 'LAST' entries */
+               gsFaultInfoLog.ui32Head = RGXFWIF_HWINFO_MAX_FIRST;
+       }
+
+       gsFaultInfoLog.ui32NumWrites++;
+
+       psInfo->sProcessInfo = *psProcessInfo;
+       psInfo->sFaultDevVAddr = sFaultDevVAddr;
+       psInfo->ui64CRTimer = ui64CRTimer;
+       psInfo->ui64When = OSClockus64();
+       OSMemCopy(psInfo->asQueryOut, asQueryOut, sizeof(psInfo->asQueryOut));
+
+       return psInfo;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     _PrintFaultInfo
+
+ @Description
+
+ Print all the details of a page fault from a FAULT_INFO structure
+
+ @Input pfnDumpDebugPrintf   - The debug printf function
+ @Input psInfo               - The page fault occurrence to print
+ @Input pui32Index           - (optional) index value to include in the print output
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _PrintFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                                       FAULT_INFO *psInfo,
+                                                       const IMG_UINT32 *pui32Index)
+{
+       IMG_UINT32 i;
+
+       if(pui32Index)
+       {
+               PVR_DUMPDEBUG_LOG(("(%u) Device memory history for page fault address 0x%010llX, CRTimer: 0x%016llX, "
+                                                       "PID: %u (%s, unregistered: %u) Abs Time: %llu us",
+                                       *pui32Index,
+                                       (unsigned long long) psInfo->sFaultDevVAddr.uiAddr,
+                                       psInfo->ui64CRTimer,
+                                       (unsigned int) psInfo->sProcessInfo.uiPID,
+                                       psInfo->sProcessInfo.szProcessName,
+                                       psInfo->sProcessInfo.bUnregistered,
+                                       (unsigned long long) psInfo->ui64When));
+       }
+       else
+       {
+               PVR_DUMPDEBUG_LOG(("Device memory history for page fault address 0x%010llX, PID: %u (%s, unregistered: %u) Abs Time: %llu us",
+                                       (unsigned long long) psInfo->sFaultDevVAddr.uiAddr,
+                                       (unsigned int) psInfo->sProcessInfo.uiPID,
+                                       psInfo->sProcessInfo.szProcessName,
+                                       psInfo->sProcessInfo.bUnregistered,
+                                       (unsigned long long) psInfo->ui64When));
+       }
+
+       for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++)
+       {
+               const IMG_CHAR *pszWhich;
+
+               switch(i)
+               {
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING:
+                               pszWhich = "Preceding page";
+                               break;
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED:
+                               pszWhich = "Faulted page";
+                               break;
+                       case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT:
+                               pszWhich = "Next page";
+                               break;
+               }
+
+               PVR_DUMPDEBUG_LOG(("%s:", pszWhich));
+               _PrintDevicememHistoryQueryOut(pfnDumpDebugPrintf, &psInfo->asQueryOut[i]);
+       }
+}
+
+#endif
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDumpRGXBIFBank
+
+ @Description
+
+ Dump BIF Bank state in human readable form.
+
+ @Input psDevInfo                              - RGX device info
+ @Input eBankID                                        - BIF identifier
+ @Input ui64MMUStatus                  - MMU Status register value
+ @Input ui64ReqStatus                  - BIF request Status register value
+ @Input ui64PCAddress                   - Page catalogue base address of faulting access
+ @Input ui64CRTimer                     - RGX CR timer value at time of page fault
+ @Input bBIFSummary                            - Flag to check whether the function is called
+                                                                 as a part of the debug dump summary or
+                                                                 as a part of a HWR log
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                   PVRSRV_RGXDEV_INFO  *psDevInfo,
+                                   RGXDBG_BIF_ID               eBankID,
+                                   IMG_UINT64                  ui64MMUStatus,
+                                   IMG_UINT64                  ui64ReqStatus,
+                                   IMG_UINT64                  ui64PCAddress,
+                                   IMG_UINT64                  ui64CRTimer,
+                                   IMG_BOOL                            bBIFSummary)
+{
+
+       if (ui64MMUStatus == 0x0)
+       {
+               PVR_DUMPDEBUG_LOG(("%s - OK", pszBIFNames[eBankID]));
+       }
+       else
+       {
+               IMG_DEV_VIRTADDR sFaultDevVAddr;
+               IMG_DEV_PHYADDR sPCDevPAddr = { 0 };
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+               IMG_BOOL bFound = IMG_FALSE;
+               RGXMEM_PROCESS_INFO sProcessInfo;
+               IMG_UINT32 ui32PageSizeBytes;
+               FAULT_INFO *psInfo;
+#endif
+               /* Bank 0 & 1 share the same fields */
+               PVR_DUMPDEBUG_LOG(("%s%s - FAULT:",
+                                                 (bBIFSummary)?"":"    ",
+                                                 pszBIFNames[eBankID]));
+
+               /* MMU Status */
+               {
+                       IMG_UINT32 ui32PC = 
+                               (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >>
+                                       RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT;
+
+                       IMG_UINT32 ui32PageSize = 
+                               (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK) >>
+                                       RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT;
+
+                       IMG_UINT32 ui32MMUDataType = 
+                               (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK) >>
+                                       RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT;
+
+                       IMG_BOOL bROFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN) != 0;
+                       IMG_BOOL bProtFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN) != 0;
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+                       ui32PageSizeBytes = _PageSizeHWToBytes(ui32PageSize);
+#endif
+
+                       PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d%s, Page Size = %d, MMU data type = %d%s%s.",
+                                         (bBIFSummary)?"":"    ",
+                                                         ui64MMUStatus,
+                                         ui32PC,
+                                         (ui32PC < 0x8)?"":_RGXDecodePMPC(ui32PC),
+                                         ui32PageSize,
+                                         ui32MMUDataType,
+                                         (bROFault)?", Read Only fault":"",
+                                         (bProtFault)?", PM/META protection fault":""));
+               }
+
+               /* Req Status */
+               {
+                       IMG_CHAR *pszTagID;
+                       IMG_CHAR *pszTagSB;
+                       IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
+
+                       IMG_BOOL bRead = (ui64ReqStatus & RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN) != 0;
+                       IMG_UINT32 ui32TagSB = 
+                               (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK) >>
+                                       RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT;
+                       IMG_UINT32 ui32TagID = 
+                               (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK) >>
+                                                       RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT;
+                       IMG_UINT64 ui64Addr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK);
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+                       /* RNW bit offset is different. The TAG_SB, TAG_ID and address fields are the same. */
+                       if (eBankID == RGXDBG_DPX_BIF)
+                       {
+                               bRead = (ui64ReqStatus & DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_EN) != 0;
+                       }
+#endif
+                       _RGXDecodeBIFReqTags(eBankID, ui32TagID, ui32TagSB, &pszTagID, &pszTagSB, &aszScratch[0], RGX_DEBUG_STR_SIZE);
+
+                       PVR_DUMPDEBUG_LOG(("%s  * Request (0x%016llX): %s (%s), %s 0x%010llX.",
+                                                         (bBIFSummary)?"":"    ",
+                                                         ui64ReqStatus,
+                                         pszTagID,
+                                         pszTagSB,
+                                         (bRead)?"Reading from":"Writing to",
+                                         ui64Addr));
+               }
+
+               /* Check if the host thinks this fault is valid */
+
+               sFaultDevVAddr.uiAddr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK);
+
+               if(bBIFSummary)
+               {
+                       IMG_UINT32 ui32PC = 
+                               (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >>
+                                       RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT;
+                               
+                       /* Only the first 8 cat bases are application memory contexts which we can validate... */
+                       if (ui32PC < 8)
+                       {
+                               sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32PC));
+                               PVR_DUMPDEBUG_LOG(("Acquired live PC address: 0x%016llX", sPCDevPAddr.uiAddr));
+                       }
+                       else
+                       {
+                               sPCDevPAddr.uiAddr = 0;
+                       }
+               }
+               else
+               {
+                       PVR_DUMPDEBUG_LOG(("FW logged fault using PC Address: 0x%016llX", ui64PCAddress));
+                       sPCDevPAddr.uiAddr = ui64PCAddress;
+               }
+
+               if(bBIFSummary)
+               {
+                       PVR_DUMPDEBUG_LOG(("Checking faulting address 0x%010llX", sFaultDevVAddr.uiAddr));
+                       RGXCheckFaultAddress(psDevInfo, &sFaultDevVAddr, &sPCDevPAddr);
+               }
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+
+                /* look to see if we have already processed this fault.
+                 * if so then use the previously acquired information.
+                 */
+               OSLockAcquire(psDevInfo->hDebugFaultInfoLock);
+               psInfo = _QueryFaultInfo(pfnDumpDebugPrintf, sFaultDevVAddr, ui64CRTimer);
+
+               if(psInfo == IMG_NULL)
+               {
+                       if(sPCDevPAddr.uiAddr != RGXFWIF_INVALID_PC_PHYADDR)
+                       {
+                               /* look up the process details for the faulting page catalogue */
+                               bFound = RGXPCAddrToProcessInfo(psDevInfo, sPCDevPAddr, &sProcessInfo);
+
+                               if(bFound)
+                               {
+                                       IMG_BOOL bHits;
+                                       DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT] = {{ 0 }};
+
+                                       /* get any DevicememHistory data for the faulting address */
+                                       bHits = _GetDevicememHistoryData(sProcessInfo.uiPID,
+                                                                               sFaultDevVAddr,
+                                                                               asQueryOut,
+                                                                               ui32PageSizeBytes);
+
+                                       if(bHits)
+                                       {
+                                               psInfo = _AddFaultInfo(&sProcessInfo,
+                                                                                       sFaultDevVAddr,
+                                                                                       ui64CRTimer,
+                                                                                       asQueryOut);
+                                       }
+                               }
+                               else
+                               {
+                                       PVR_DUMPDEBUG_LOG(("Could not find PID for PC 0x%016llX", sPCDevPAddr.uiAddr));
+                               }
+                       }
+                       else
+                       {
+                               PVR_DUMPDEBUG_LOG(("Page fault not applicable to Devmem History"));
+                       }
+               }
+
+               if(psInfo != IMG_NULL)
+               {
+                       _PrintFaultInfo(pfnDumpDebugPrintf, psInfo, NULL);
+               }
+
+               OSLockRelease(psDevInfo->hDebugFaultInfoLock);
+#endif
+
+       }
+
+}
+#endif
+
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+/*!
+*******************************************************************************
+
+ @Function     _RGXDumpRGXMMUFaultStatus
+
+ @Description
+
+ Dump MMU Fault status in human readable form.
+
+ @Input psDevInfo                              - RGX device info
+ @Input ui64MMUStatus                  - MMU Status register value
+ @Input bSummary                               - Flag to check whether the function is called
+                                                                 as a part of the debug dump summary or
+                                                                 as a part of a HWR log
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDumpRGXMMUFaultStatus(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                          PVRSRV_RGXDEV_INFO    *psDevInfo,
+                                          IMG_UINT64            ui64MMUStatus,
+                                          IMG_BOOL              bSummary)
+{
+       if (ui64MMUStatus == 0x0)
+       {
+               PVR_DUMPDEBUG_LOG(("MMU (Core) - OK"));
+       }
+       else
+       {
+               IMG_UINT32 ui32PC        = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT;
+               IMG_UINT64 ui64Addr      = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT;
+               IMG_UINT32 ui32Requester = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT;
+               IMG_UINT32 ui32SideBand  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT;
+               IMG_UINT32 ui32MMULevel  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT;
+               IMG_BOOL bRead           = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_RNW_EN) != 0;
+               IMG_BOOL bFault          = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_FAULT_EN) != 0;
+               IMG_BOOL bROFault        = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >>
+                                           RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x2;
+               IMG_BOOL bProtFault      = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >>
+                                           RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x3;
+               IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
+               IMG_CHAR *pszTagID;
+               IMG_CHAR *pszTagSB;
+
+               _RGXDecodeMMUReqTags(ui32Requester, ui32SideBand, &pszTagID, &pszTagSB, aszScratch, RGX_DEBUG_STR_SIZE);
+
+               PVR_DUMPDEBUG_LOG(("%sMMU (Core) - FAULT:",  (bSummary)?"":"    "));
+               PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d, %s 0x%010llX, %s (%s)%s%s%s%s.",
+                                                 (bSummary)?"":"    ",
+                                                 ui64MMUStatus,
+                                                 ui32PC,
+                                 (bRead)?"Reading from":"Writing to",
+                                                 ui64Addr,
+                                                 pszTagID,
+                                                 pszTagSB,
+                                                 (bFault)?", Fault":"",
+                                                 (bROFault)?", Read Only fault":"",
+                                                 (bProtFault)?", PM/META protection fault":"",
+                                                 _RGXDecodeMMULevel(ui32MMULevel)));
+       }
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDumpRGXMMUMetaFaultStatus
+
+ @Description
+
+ Dump MMU Meta Fault state in human readable form.
+
+ @Input psDevInfo                              - RGX device info
+ @Input ui64MMUStatus                  - MMU Status register value
+ @Input bSummary                               - Flag to check whether the function is called
+                                                                 as a part of the debug dump summary or
+                                                                 as a part of a HWR log
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDumpRGXMMUMetaFaultStatus(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                              PVRSRV_RGXDEV_INFO    *psDevInfo,
+                                              IMG_UINT64            ui64MMUStatus,
+                                              IMG_BOOL              bSummary)
+{
+       if (ui64MMUStatus == 0x0)
+       {
+               PVR_DUMPDEBUG_LOG(("MMU (Meta) - OK"));
+       }
+       else
+       {
+               IMG_UINT32 ui32PC        = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_SHIFT;
+               IMG_UINT64 ui64Addr      = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_SHIFT;
+               IMG_UINT32 ui32SideBand  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_SHIFT;
+               IMG_UINT32 ui32Requester = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_SHIFT;
+               IMG_UINT32 ui32MMULevel  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_LEVEL_CLRMSK) >>
+                                          RGX_CR_MMU_FAULT_STATUS_META_LEVEL_SHIFT;
+               IMG_BOOL bRead           = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_META_RNW_EN) != 0;
+               IMG_BOOL bFault          = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_META_FAULT_EN) != 0;
+               IMG_BOOL bROFault        = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK) >>
+                                           RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT) == 0x2;
+               IMG_BOOL bProtFault      = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK) >>
+                                           RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT) == 0x3;
+               IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
+               IMG_CHAR *pszTagID;
+               IMG_CHAR *pszTagSB;
+
+               _RGXDecodeMMUReqTags(ui32Requester, ui32SideBand, &pszTagID, &pszTagSB, aszScratch, RGX_DEBUG_STR_SIZE);
+
+               PVR_DUMPDEBUG_LOG(("%sMMU (Meta) - FAULT:",  (bSummary)?"":"    "));
+               PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d, %s 0x%010llX, %s (%s)%s%s%s%s.",
+                                                 (bSummary)?"":"    ",
+                                                 ui64MMUStatus,
+                                                 ui32PC,
+                                 (bRead)?"Reading from":"Writing to",
+                                                 ui64Addr,
+                                                 pszTagID,
+                                                 pszTagSB,
+                                                 (bFault)?", Fault":"",
+                                                 (bROFault)?", Read Only fault":"",
+                                                 (bProtFault)?", PM/META protection fault":"",
+                                                 _RGXDecodeMMULevel(ui32MMULevel)));
+       }
+}
+#endif
+
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDumpFWAssert
+
+ @Description
+
+ Dump FW assert strings when a thread asserts.
+
+ @Input psRGXFWIfTraceBufCtl   - RGX FW trace buffer
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDumpFWAssert(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                 RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl)
+{
+       IMG_CHAR    *pszTraceAssertPath;
+       IMG_CHAR    *pszTraceAssertInfo;
+       IMG_INT32   ui32TraceAssertLine;
+       IMG_UINT32  i;
+
+       for (i = 0; i < RGXFW_THREAD_NUM; i++)
+       {
+               pszTraceAssertPath = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szPath;
+               pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szInfo;
+               ui32TraceAssertLine = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.ui32LineNum;
+
+               /* print non null assert strings */
+               if (*pszTraceAssertInfo)
+               {
+                       PVR_DUMPDEBUG_LOG(("FW-T%d Assert: %s (%s:%d)", 
+                                         i, pszTraceAssertInfo, pszTraceAssertPath, ui32TraceAssertLine));
+               }
+       }
+}
+
+static IMG_VOID _RGXDumpFWPoll(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                               RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl)
+{
+       IMG_UINT32 i;
+       for (i = 0; i < RGXFW_THREAD_NUM; i++)
+       {
+               if (psRGXFWIfTraceBufCtl->aui32CrPollAddr[i])
+               {
+                       PVR_DUMPDEBUG_LOG(("T%u polling %s (reg:0x%08X mask:0x%08X)",
+                                         i,
+                                         ((psRGXFWIfTraceBufCtl->aui32CrPollAddr[i] & RGXFW_POLL_TYPE_SET)?("set"):("unset")), 
+                                         psRGXFWIfTraceBufCtl->aui32CrPollAddr[i] & ~RGXFW_POLL_TYPE_SET, 
+                                         psRGXFWIfTraceBufCtl->aui32CrPollMask[i]));
+               }
+       }
+
+}
+
+static IMG_VOID _RGXDumpFWHWRInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                  RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl, PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       IMG_BOOL                bAnyLocked = IMG_FALSE;
+       IMG_UINT32              dm, i;
+       IMG_UINT32              ui32LineSize;
+       IMG_CHAR                *pszLine, *pszTemp;
+       const IMG_CHAR          *apszDmNames[RGXFWIF_DM_MAX + 1] = { "GP(", "2D(", "TA(", "3D(", "CDM(",
+#if defined(RGX_FEATURE_RAY_TRACING)
+                                                                "RTU(", "SHG(",
+#endif /* RGX_FEATURE_RAY_TRACING */
+                                                                NULL };
+
+       const IMG_CHAR          *pszMsgHeader = "Number of HWR: ";
+       IMG_CHAR                        *pszLockupType = "";
+       RGXFWIF_HWRINFOBUF      *psHWInfoBuf = psDevInfo->psRGXFWIfHWRInfoBuf;
+       RGX_HWRINFO             *psHWRInfo;
+       IMG_UINT32              ui32MsgHeaderSize = OSStringLength(pszMsgHeader);
+       IMG_UINT32                      ui32HWRRecoveryFlags;
+       IMG_UINT32                      ui32ReadIndex;
+
+       for (dm = 0; dm < RGXFWIF_DM_MAX; dm++)
+       {
+               if (psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[dm]  ||
+                   psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[dm])
+               {
+                       bAnyLocked = IMG_TRUE;
+                       break;                                  
+               }
+       }
+
+       if (!bAnyLocked && (psRGXFWIfTraceBufCtl->ui32HWRStateFlags & RGXFWIF_HWR_HARDWARE_OK))
+       {
+               /* No HWR situation, print nothing */
+               return;
+       }
+
+       ui32LineSize = sizeof(IMG_CHAR) * (     ui32MsgHeaderSize + 
+                       (RGXFWIF_DM_MAX*(       4/*DM name + left parenthesis*/ + 
+                                                               5/*UINT16 max num of digits*/ + 
+                                                               1/*slash*/ + 
+                                                               5/*UINT16 max num of digits*/ + 
+                                                               3/*right parenthesis + comma + space*/)) + 
+                       7 + (RGXFWIF_DM_MAX*6)/* FALSE() + (UINT16 max num + comma) per DM */ +
+                       1/* \0 */);
+
+       pszLine = OSAllocMem(ui32LineSize);
+       if (pszLine == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"_RGXDumpRGXDebugSummary: Out of mem allocating line string (size: %d)", ui32LineSize));
+               return;
+       }
+
+       OSStringCopy(pszLine,pszMsgHeader);
+       pszTemp = pszLine + ui32MsgHeaderSize;
+
+       for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
+       {
+               OSStringCopy(pszTemp,apszDmNames[dm]);
+               pszTemp += OSStringLength(apszDmNames[dm]);
+               pszTemp += OSSNPrintf(pszTemp, 
+                               5 + 1 + 5 + 1 + 5 + 1 + 1 + 1 + 1 /* UINT16 + slash + UINT16 + plus + UINT16 + right parenthesis + comma + space + \0 */,
+                               "%u/%u+%u), ",
+                               psRGXFWIfTraceBufCtl->aui16HwrDmRecoveredCount[dm],
+                               psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[dm],
+                               psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[dm]);
+       }
+
+       OSStringCopy(pszTemp, "FALSE(");
+       pszTemp += 6;
+
+       for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
+       {
+               pszTemp += OSSNPrintf(pszTemp, 
+                               5 + 1 + 1 /* UINT16 max num + comma + \0 */,
+                               (dm < RGXFWIF_DM_MAX-1 ? "%u," : "%u)"),
+                               psRGXFWIfTraceBufCtl->aui16HwrDmFalseDetectCount[dm]);
+       }
+
+       PVR_DUMPDEBUG_LOG((pszLine));
+
+       OSFreeMem(pszLine);
+
+       /* Print out per HWR info */
+       for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
+       {
+               if (dm == RGXFWIF_DM_GP)
+               {
+                       PVR_DUMPDEBUG_LOG(("DM %d (GP)", dm));
+               }
+               else
+               {
+                       PVR_DUMPDEBUG_LOG(("DM %d (HWRflags 0x%08x)", dm, psRGXFWIfTraceBufCtl->aui32HWRRecoveryFlags[dm]));
+               }
+
+               ui32ReadIndex = 0;
+               for(i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++)
+               {
+                       psHWRInfo = &psHWInfoBuf->sHWRInfo[ui32ReadIndex];
+
+                       if((psHWRInfo->eDM == dm) && (psHWRInfo->ui32HWRNumber != 0))
+                       {
+                               IMG_UINT64 ui64OSTimeStamp, ui64DeltaTime, ui64Seconds, ui64Nanoseconds;
+                               IMG_UINT32 ui32CRDeltaToOSDeltaKNs = psHWRInfo->sTimeCorr.ui32CRDeltaToOSDeltaKNs;
+                               IMG_UINT32 ui32Remainder;
+
+                               /* Get delta CR, convert to delta nS and add the result to the correlated OS timestamp */
+                               ui64DeltaTime = psHWRInfo->ui64CRTimer - psHWRInfo->sTimeCorr.ui64CRTimeStamp;
+                               ui64DeltaTime = RGXFWIF_GET_DELTA_OSTIME_NS(ui64DeltaTime, ui32CRDeltaToOSDeltaKNs);
+                               ui64OSTimeStamp = psHWRInfo->sTimeCorr.ui64OSTimeStamp + ui64DeltaTime;
+
+                               /* Split timestamp in seconds and nanoseconds */
+                               ui64Seconds = OSDivide64r64(ui64OSTimeStamp, 1000000000, &ui32Remainder);
+                               ui64Nanoseconds = ui64OSTimeStamp - (ui64Seconds * 1000000000ULL);
+
+                               ui32HWRRecoveryFlags = psHWRInfo->ui32HWRRecoveryFlags;
+                               if(ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_LOCKUP) { pszLockupType = ", Guilty Lockup"; }
+                               else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_INNOCENT_LOCKUP) { pszLockupType = ", Innocent Lockup"; }
+                               else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_OVERRUNING) { pszLockupType = ", Guilty Overrun"; }
+                               else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_LOCKUP) { pszLockupType = ", Innocent Overrun"; }
+
+                               PVR_DUMPDEBUG_LOG(("  Recovery %d: PID = %d, frame = %d, HWRTData = 0x%08X,"
+                                                  " EventStatus = 0x%08X, CRTimer = 0x%012llX, OSTimer = %llu.%09llu%s",
+                                                  psHWRInfo->ui32HWRNumber,
+                                                  psHWRInfo->ui32PID,
+                                                  psHWRInfo->ui32FrameNum,
+                                                  psHWRInfo->ui32ActiveHWRTData,
+                                                  psHWRInfo->ui32EventStatus,
+                                                  psHWRInfo->ui64CRTimer,
+                                                  ui64Seconds,
+                                                  ui64Nanoseconds,
+                                                  pszLockupType));
+
+                               switch(psHWRInfo->eHWRType)
+                               {
+#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+                                       case RGX_HWRTYPE_BIF0FAULT:
+                                       case RGX_HWRTYPE_BIF1FAULT:
+                                       {
+                                               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXFWIF_HWRTYPE_BIF_BANK_GET(psHWRInfo->eHWRType),
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
+                                                                               psHWRInfo->ui64CRTimer,
+                                                                               IMG_FALSE);
+                                       }
+                                       break;
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+                                       case RGX_HWRTYPE_TEXASBIF0FAULT:
+                                       {
+                                               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
+                                                                               psHWRInfo->ui64CRTimer,
+                                                                               IMG_FALSE);
+                                       }
+                                       break;
+#endif
+#if defined(RGX_FEATURE_RAY_TRACING)
+                                       case RGX_HWRTYPE_DPXMMUFAULT:
+                                       {
+                                               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_DPX_BIF,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
+                                                                               psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
+                                                                               psHWRInfo->ui64CRTimer,
+                                                                               IMG_FALSE);
+                                       }
+                                       break;
+#endif
+#else
+                                       case RGX_HWRTYPE_MMUFAULT:
+                                       {
+                                               _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, psDevInfo,
+                                                                         psHWRInfo->uHWRData.sMMUInfo.ui64MMUStatus,
+                                                                         IMG_FALSE);
+                                       }
+                                       break;
+
+                                       case RGX_HWRTYPE_MMUMETAFAULT:
+                                       {
+                                               _RGXDumpRGXMMUMetaFaultStatus(pfnDumpDebugPrintf, psDevInfo,
+                                                                             psHWRInfo->uHWRData.sMMUInfo.ui64MMUStatus,
+                                                                             IMG_FALSE);
+                                       }
+                                       break;
+#endif
+
+                                       case RGX_HWRTYPE_POLLFAILURE:
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("    T%u polling %s (reg:0x%08X mask:0x%08X)",
+                                                                                 psHWRInfo->uHWRData.sPollInfo.ui32ThreadNum,
+                                                                                 ((psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & RGXFW_POLL_TYPE_SET)?("set"):("unset")),
+                                                                                 psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & ~RGXFW_POLL_TYPE_SET,
+                                                                                 psHWRInfo->uHWRData.sPollInfo.ui32CrPollMask));
+                                       }
+                                       break;
+
+                                       case RGX_HWRTYPE_OVERRUN:
+                                       case RGX_HWRTYPE_UNKNOWNFAILURE:
+                                       {
+                                               /* Nothing to dump */
+                                       }
+                                       break;
+
+                                       default:
+                                       {
+                                               PVR_ASSERT(IMG_FALSE);
+                                       }
+                                       break;
+                               }
+                       }
+
+                       if(ui32ReadIndex == RGXFWIF_HWINFO_MAX_FIRST - 1)
+                                                       ui32ReadIndex = psHWInfoBuf->ui32WriteIndex;
+                       else
+                               ui32ReadIndex = (ui32ReadIndex + 1) - (ui32ReadIndex / RGXFWIF_HWINFO_LAST_INDEX) * RGXFWIF_HWINFO_MAX_LAST;
+               }
+       }       
+}
+
+#if !defined(NO_HARDWARE)
+
+/*!
+*******************************************************************************
+
+ @Function     _CheckForPendingPage
+
+ @Description
+
+ Check if the MMU indicates it is blocked on a pending page
+
+ @Input psDevInfo       - RGX device info
+
+ @Return   IMG_BOOL      - IMG_TRUE if there is a pending page
+
+******************************************************************************/
+static INLINE IMG_BOOL _CheckForPendingPage(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       IMG_UINT32 ui32BIFMMUEntry;
+
+       ui32BIFMMUEntry = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY);
+
+       if(ui32BIFMMUEntry & RGX_CR_BIF_MMU_ENTRY_PENDING_EN)
+       {
+               return IMG_TRUE;
+       }
+       else
+       {
+               return IMG_FALSE;
+       }
+}
+
+/*!
+*******************************************************************************
+
+ @Function     _GetPendingPageInfo
+
+ @Description
+
+ Get information about the pending page from the MMU status registers
+
+ @Input psDevInfo       - RGX device info
+ @Output psDevVAddr      - The device virtual address of the pending MMU address translation
+ @Output pui32CatBase    - The page catalog base
+ @Output pui32DataType   - The MMU entry data type
+
+ @Return   void
+
+******************************************************************************/
+static void _GetPendingPageInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *psDevVAddr,
+                                                                       IMG_UINT32 *pui32CatBase,
+                                                                       IMG_UINT32 *pui32DataType)
+{
+       IMG_UINT64 ui64BIFMMUEntryStatus;
+
+       ui64BIFMMUEntryStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY_STATUS);
+
+       psDevVAddr->uiAddr = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_CLRMSK);
+
+       *pui32CatBase = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_CLRMSK) >>
+                                                               RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_SHIFT;
+
+       *pui32DataType = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_CLRMSK) >>
+                                                               RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_SHIFT;
+}
+
+#endif
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXDumpRGXDebugSummary
+
+ @Description
+
+ Dump a summary in human readable form with the RGX state
+
+ @Input psDevInfo       - RGX device info
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID _RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                        PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bRGXPoweredON)
+{
+       IMG_CHAR *pszState, *pszReason;
+       RGXFWIF_TRACEBUF *psRGXFWIfTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+
+#if defined(NO_HARDWARE)
+       PVR_UNREFERENCED_PARAMETER(bRGXPoweredON);
+#else
+       if (bRGXPoweredON)
+       {
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+               IMG_UINT64      ui64RegValMMUStatus;
+
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS);
+               _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, psDevInfo, ui64RegValMMUStatus, IMG_TRUE);
+
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS_META);
+               _RGXDumpRGXMMUMetaFaultStatus(pfnDumpDebugPrintf, psDevInfo, ui64RegValMMUStatus, IMG_TRUE);
+#else
+               IMG_UINT64      ui64RegValMMUStatus, ui64RegValREQStatus;
+
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_MMU_STATUS);
+               ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_REQ_STATUS);
+
+               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF0, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
+
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_MMU_STATUS);
+               ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_REQ_STATUS);
+
+               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF1, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
+
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#if defined(RGX_NUM_PHANTOMS)
+               {
+                       IMG_UINT32  ui32Phantom;
+                       
+                       for (ui32Phantom = 0;  ui32Phantom < RGX_NUM_PHANTOMS;  ui32Phantom++)
+                       {
+                               /* This can't be done as it may interfere with the FW... */
+                               /*OSWriteHWReg64(RGX_CR_TEXAS_INDIRECT, ui32Phantom);*/
+                               
+                               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS);
+                               ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS);
+
+                               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
+                       }
+               }
+#else
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS);
+               ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS);
+
+               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
+#endif
+#endif
+#endif
+#if defined(RGX_FEATURE_RAY_TRACING)
+               ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, DPX_CR_BIF_FAULT_BANK_MMU_STATUS);
+               ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, DPX_CR_BIF_FAULT_BANK_REQ_STATUS);
+
+               _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_DPX_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
+#endif
+
+               if(_CheckForPendingPage(psDevInfo))
+               {
+                       IMG_UINT32 ui32CatBase;
+                       IMG_UINT32 ui32DataType;
+                       IMG_DEV_VIRTADDR sDevVAddr;
+
+                       PVR_DUMPDEBUG_LOG(("MMU Pending page: Yes"));
+
+                       _GetPendingPageInfo(psDevInfo, &sDevVAddr, &ui32CatBase, &ui32DataType);
+
+                       if(ui32CatBase >= 8)
+                       {
+                               PVR_DUMPDEBUG_LOG(("Cannot check address on PM cat base %u", ui32CatBase));
+                       }
+                       else
+                       {
+                               IMG_DEV_PHYADDR sPCDevPAddr;
+
+                               sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32CatBase));
+
+                               PVR_DUMPDEBUG_LOG(("Checking device virtual address " IMG_DEV_VIRTADDR_FMTSPEC
+                                                       " on cat base %u. PC Addr = 0x%llX",
+                                                               (unsigned long long) sDevVAddr.uiAddr,
+                                                               ui32CatBase,
+                                                               (unsigned long long) sPCDevPAddr.uiAddr));
+                               RGXCheckFaultAddress(psDevInfo, &sDevVAddr, &sPCDevPAddr);
+                       }
+               }
+       }
+#endif /* NO_HARDWARE */
+
+       /* Firmware state */
+       switch (psDevInfo->psDeviceNode->eHealthStatus)
+       {
+               case PVRSRV_DEVICE_HEALTH_STATUS_OK:  pszState = "OK";  break;
+               case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING:  pszState = "NOT RESPONDING";  break;
+               case PVRSRV_DEVICE_HEALTH_STATUS_DEAD:  pszState = "DEAD";  break;
+               default:  pszState = "UNKNOWN";  break;
+       }
+
+       switch (psDevInfo->psDeviceNode->eHealthReason)
+       {
+               case PVRSRV_DEVICE_HEALTH_REASON_NONE:  pszReason = "";  break;
+               case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED:  pszReason = " - FW Assert";  break;
+               case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING:  pszReason = " - Poll failure";  break;
+               case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS:  pszReason = " - Global Event Object timeouts rising";  break;
+               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT:  pszReason = " - KCCB offset invalid";  break;
+               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED:  pszReason = " - KCCB stalled";  break;
+               default:  pszReason = " - Unknown reason";  break;
+       }
+
+       if (psRGXFWIfTraceBuf == IMG_NULL)
+       {
+               PVR_DUMPDEBUG_LOG(("RGX FW State: %s%s", pszState, pszReason));
+
+               /* can't dump any more information */
+               return;
+       }
+       
+       PVR_DUMPDEBUG_LOG(("RGX FW State: %s%s (HWRState 0x%08x)", pszState, pszReason, psRGXFWIfTraceBuf->ui32HWRStateFlags));
+       PVR_DUMPDEBUG_LOG(("RGX FW Power State: %s (APM %s: %d ok, %d denied, %d other, %d total)", 
+                         pszPowStateName[psRGXFWIfTraceBuf->ePowState],
+                         (psDevInfo->pvAPMISRData)?"enabled":"disabled",
+                         psDevInfo->ui32ActivePMReqOk,
+                         psDevInfo->ui32ActivePMReqDenied,
+                         psDevInfo->ui32ActivePMReqTotal - psDevInfo->ui32ActivePMReqOk - psDevInfo->ui32ActivePMReqDenied,
+                         psDevInfo->ui32ActivePMReqTotal));
+
+
+       _RGXDumpFWAssert(pfnDumpDebugPrintf, psRGXFWIfTraceBuf);
+
+       _RGXDumpFWPoll(pfnDumpDebugPrintf, psRGXFWIfTraceBuf);
+
+       _RGXDumpFWHWRInfo(pfnDumpDebugPrintf, psRGXFWIfTraceBuf, psDevInfo);
+
+}
+
+static IMG_VOID _RGXDumpMetaSPExtraDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                             PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+/* List of extra META Slave Port debug registers */
+#define RGX_META_SP_EXTRA_DEBUG \
+                       X(RGX_CR_META_SP_MSLVCTRL0) \
+                       X(RGX_CR_META_SP_MSLVCTRL1) \
+                       X(RGX_CR_META_SP_MSLVIRQSTATUS) \
+                       X(RGX_CR_META_SP_MSLVIRQENABLE) \
+                       X(RGX_CR_META_SP_MSLVIRQLEVEL)
+
+       IMG_UINT32 ui32Idx, ui32RegIdx;
+       IMG_UINT32 ui32RegVal;
+       IMG_UINT32 ui32RegAddr;
+
+       const IMG_UINT32 aui32DebugRegAddr [] = {
+#define X(A) A,
+               RGX_META_SP_EXTRA_DEBUG
+#undef X
+               };
+
+       const IMG_CHAR* apszDebugRegName [] = {
+#define X(A) #A,
+       RGX_META_SP_EXTRA_DEBUG
+#undef X
+       };
+       
+       const IMG_UINT32 aui32Debug2RegAddr [] = {0xA28, 0x0A30, 0x0A38};
+
+       PVR_DUMPDEBUG_LOG(("META Slave Port extra debug:"));
+
+       /* dump first set of Slave Port debug registers */
+       for (ui32Idx = 0; ui32Idx < sizeof(aui32DebugRegAddr)/sizeof(IMG_UINT32); ui32Idx++)
+       {
+               const IMG_CHAR* pszRegName = apszDebugRegName[ui32Idx];
+
+               ui32RegAddr = aui32DebugRegAddr[ui32Idx];
+               ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+               PVR_DUMPDEBUG_LOG(("  * %s: 0x%8.8X", pszRegName, ui32RegVal));
+       }
+
+       /* dump second set of Slave Port debug registers */
+       for (ui32Idx = 0; ui32Idx < 4; ui32Idx++)
+       {
+               OSWriteHWReg32(psDevInfo->pvRegsBaseKM, 0xA20, ui32Idx);
+               ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, 0xA20);
+               PVR_DUMPDEBUG_LOG(("  * 0xA20[%d]: 0x%8.8X", ui32Idx, ui32RegVal));
+
+       }
+
+       for (ui32RegIdx = 0; ui32RegIdx < sizeof(aui32Debug2RegAddr)/sizeof(IMG_UINT32); ui32RegIdx++)
+       {
+               ui32RegAddr = aui32Debug2RegAddr[ui32RegIdx];
+               for (ui32Idx = 0; ui32Idx < 2; ui32Idx++)
+               {
+                       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr, ui32Idx);
+                       ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+                       PVR_DUMPDEBUG_LOG(("  * 0x%X[%d]: 0x%8.8X", ui32RegAddr, ui32Idx, ui32RegVal));
+               }
+       }
+
+}
+
+/*
+       RGXDumpDebugInfo
+*/
+IMG_VOID RGXDumpDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                          PVRSRV_RGXDEV_INFO   *psDevInfo)
+{
+       IMG_UINT32 i;
+
+       for(i=0;i<=DEBUG_REQUEST_VERBOSITY_MAX;i++)
+       {
+               RGXDebugRequestProcess(pfnDumpDebugPrintf, psDevInfo, i);
+       }
+}
+
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+/*
+ *  Array of all the Firmware Trace log IDs used to convert the trace data.
+ */
+typedef struct _TRACEBUF_LOG_ {
+       RGXFW_LOG_SFids  eSFId;
+       IMG_CHAR                 *pszName;
+       IMG_CHAR                 *pszFmt;
+       IMG_UINT32               ui32ArgNum;
+} TRACEBUF_LOG;
+
+TRACEBUF_LOG aLogDefinitions[] = {
+#define X(a, b, c, d, e) {RGXFW_LOG_CREATESFID(a,b,e), #c, d, e},
+       RGXFW_LOG_SFIDLIST 
+#undef X
+};
+
+#define NARGS_MASK ~(0xF<<16)
+static IMG_BOOL _FirmwareTraceIntegrityCheck(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       TRACEBUF_LOG  *psLogDef    = &aLogDefinitions[0];
+       IMG_BOOL      bIntegrityOk = IMG_TRUE;
+
+       /*
+        *  For every log ID, check the format string and number of arguments is valid.
+        */
+       while (psLogDef->eSFId != RGXFW_SF_LAST)
+       {
+               IMG_UINT32    ui32Count;
+               IMG_CHAR      *pszString;
+               TRACEBUF_LOG  *psLogDef2;
+
+               /*
+                * Check the number of arguments matches the number of '%' in the string and
+                * check that no string uses %s which is not supported as it requires a
+                * pointer to memory that is not going to be valid.
+                */
+               pszString = psLogDef->pszFmt;
+               ui32Count = 0;
+               
+               while (*pszString != '\0')
+               {
+                       if (*pszString++ == '%')
+                       {
+                               ui32Count++;
+                               if (*pszString == 's')
+                               {
+                                       bIntegrityOk = IMG_FALSE;
+                                       PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has an unsupported type not recognized (fmt: %%%c). Please fix.",
+                                                                         psLogDef->pszName, *pszString));
+                               }
+                               else if (*pszString == '%')
+                               {
+                                       /* Double % is a printable % sign and not a format string... */
+                                       ui32Count--;
+                               }
+                       }
+               }
+               
+               if (ui32Count != psLogDef->ui32ArgNum)
+               {
+                       bIntegrityOk = IMG_FALSE;
+                       PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has %d arguments but only %d are specified. Please fix.",
+                                         psLogDef->pszName, ui32Count, psLogDef->ui32ArgNum));
+               }
+
+               /* RGXDumpFirmwareTrace() has a hardcoded limit of supporting up to 20 arguments... */
+               if (ui32Count > 20)
+               {
+                       bIntegrityOk = IMG_FALSE;
+                       PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has %d arguments but a maximum of 20 are supported. Please fix.",
+                                         psLogDef->pszName, ui32Count));
+               }
+
+               /* Check the id number is unique (don't take into account the number of arguments) */
+               ui32Count = 0;
+               psLogDef2 = &aLogDefinitions[0];
+
+               while (psLogDef2->eSFId != RGXFW_SF_LAST)
+               {
+                       if ((psLogDef->eSFId & NARGS_MASK) == (psLogDef2->eSFId & NARGS_MASK))
+                       {
+                               ui32Count++;
+                       }
+                       psLogDef2++;
+               }
+
+               if (ui32Count != 1)
+               {
+                       bIntegrityOk = IMG_FALSE;
+                       PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s id %x is not unique, there are %d more. Please fix.",
+                                         psLogDef->pszName, psLogDef->eSFId, ui32Count - 1));
+               }
+
+               /* Move to the next log ID... */
+               psLogDef++;
+       }
+
+       return bIntegrityOk;
+}
+
+IMG_VOID RGXDumpFirmwareTrace(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                              PVRSRV_RGXDEV_INFO  *psDevInfo)
+{
+       RGXFWIF_TRACEBUF  *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+       static IMG_BOOL   bIntegrityCheckPassed = IMG_FALSE;
+
+       /* Check that the firmware trace is correctly defined... */
+       if (!bIntegrityCheckPassed)
+       {
+               bIntegrityCheckPassed = _FirmwareTraceIntegrityCheck(pfnDumpDebugPrintf);
+               if (!bIntegrityCheckPassed)
+               {
+                       return;
+               }
+       }
+
+       /* Dump FW trace information... */
+       if (psRGXFWIfTraceBufCtl != IMG_NULL)
+       {
+               IMG_CHAR    szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+               IMG_UINT32  tid;
+               
+               /* Print the log type settings... */
+               if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK)
+               {
+                       PVR_DUMPDEBUG_LOG(("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")",
+                                                         ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")),
+                                                         RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType)
+                                                         ));
+               }
+               else
+               {
+                       PVR_DUMPDEBUG_LOG(("Debug log type: none"));
+               }
+
+               /* Print the decoded log for each thread... */
+               for (tid = 0;  tid < RGXFW_THREAD_NUM;  tid++) 
+               {
+                       IMG_UINT32  *ui32TraceBuf = psRGXFWIfTraceBufCtl->sTraceBuf[tid].aui32TraceBuffer;
+                       IMG_UINT32  ui32TracePtr  = psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer;
+                       IMG_UINT32  ui32Count     = 0;
+
+                       while (ui32Count < RGXFW_TRACE_BUFFER_SIZE)
+                       {
+                               IMG_UINT32  ui32Data, ui32DataToId;
+                               
+                               /* Find the first valid log ID, skipping whitespace... */
+                               do
+                               {
+                                       ui32Data     = ui32TraceBuf[ui32TracePtr];
+                                       ui32DataToId = idToStringID(ui32Data);
+
+                                       /* If an unrecognized id is found check if it is valid, if it is tracebuf needs updating. */ 
+                                       if (ui32DataToId == RGXFW_SF_LAST  &&  RGXFW_LOG_VALIDID(ui32Data))
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("ERROR: Unrecognized id (%x). From here on the trace might be wrong!", ui32Data));
+                                               return;
+                                       }
+
+                                       /* Update the trace pointer... */
+                                       ui32TracePtr = (ui32TracePtr + 1) % RGXFW_TRACE_BUFFER_SIZE;
+                                       ui32Count++;
+                               } while ((RGXFW_SF_LAST == ui32DataToId  ||  ui32DataToId >= RGXFW_SF_FIRST)  &&
+                                        ui32Count < RGXFW_TRACE_BUFFER_SIZE);
+
+                               if (ui32Count < RGXFW_TRACE_BUFFER_SIZE)
+                               {
+                                       IMG_UINT64  ui64RGXTimer;
+                                       
+                                       /* If we hit the ASSERT message then this is the end of the log... */
+                                       if (ui32Data == RGXFW_SF_MAIN_ASSERT_FAILED)
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("ASSERTION %s failed at %s:%u",
+                                                                                 psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szInfo,
+                                                                                 psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szPath,
+                                                                                 psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.ui32LineNum));
+                                               break;
+                                       }
+
+                                       /*
+                                        *  Print the trace string and provide up to 20 arguments which
+                                        *  printf function will be able to use. We have already checked
+                                        *  that no string uses more than this.
+                                        */
+                                       OSStringCopy(szBuffer, "%llu:T%u-%s> ");
+                                       OSStringCopy(&szBuffer[OSStringLength(szBuffer)], SFs[ui32DataToId].name);
+                                       szBuffer[OSStringLength(szBuffer)-1] = '\0';
+                                       ui64RGXTimer = (IMG_UINT64)(ui32TraceBuf[(ui32TracePtr +  0) % RGXFW_TRACE_BUFFER_SIZE]) << 32 |
+                                                      (IMG_UINT64)(ui32TraceBuf[(ui32TracePtr +  1) % RGXFW_TRACE_BUFFER_SIZE]);
+                                       PVR_DUMPDEBUG_LOG((szBuffer, ui64RGXTimer, tid, groups[RGXFW_SF_GID(ui32Data)],
+                                                                         ui32TraceBuf[(ui32TracePtr +  2) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  3) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  4) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  5) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  6) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  7) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  8) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr +  9) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 10) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 11) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 12) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 13) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 14) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 15) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 16) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 17) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 18) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 19) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 20) % RGXFW_TRACE_BUFFER_SIZE],
+                                                                         ui32TraceBuf[(ui32TracePtr + 21) % RGXFW_TRACE_BUFFER_SIZE]));
+
+                                       /* Update the trace pointer... */
+                                       ui32TracePtr = (ui32TracePtr + 2 + RGXFW_SF_PARAMNUM(ui32Data)) % RGXFW_TRACE_BUFFER_SIZE;
+                                       ui32Count    = (ui32Count    + 2 + RGXFW_SF_PARAMNUM(ui32Data));
+                               }
+                       }
+               }
+       }
+}
+#endif
+
+
+static IMG_CHAR* _RGXGetDebugDevPowerStateString(PVRSRV_DEV_POWER_STATE ePowerState)
+{
+       switch(ePowerState)
+       {
+               case PVRSRV_DEV_POWER_STATE_DEFAULT: return "DEFAULT";
+               case PVRSRV_DEV_POWER_STATE_OFF: return "OFF";
+               case PVRSRV_DEV_POWER_STATE_ON: return "ON";
+               default: return "UNKNOWN";
+       }
+}
+
+IMG_VOID RGXDebugRequestProcess(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                PVRSRV_RGXDEV_INFO     *psDevInfo,
+                                IMG_UINT32                     ui32VerbLevel)
+{
+       PVRSRV_ERROR eError = PVRSRVPowerLock();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess : failed to acquire lock, error:0x%x", eError));
+               return;
+       }
+
+       switch (ui32VerbLevel)
+       {
+               case DEBUG_REQUEST_VERBOSITY_LOW :
+               {
+                       IMG_UINT32              ui32DeviceIndex;
+                       PVRSRV_DEV_POWER_STATE  ePowerState;
+                       IMG_BOOL                bRGXPoweredON;
+
+                       ui32DeviceIndex = psDevInfo->psDeviceNode->sDevId.ui32DeviceIndex;
+
+                       eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess: Error retrieving RGX power state. No debug info dumped."));
+                               goto Exit;
+                       }
+
+                       bRGXPoweredON = (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
+
+                       PVR_DUMPDEBUG_LOG(("------[ RGX summary ]------"));
+                       PVR_DUMPDEBUG_LOG(("RGX BVNC: %s", RGX_BVNC_KM));
+                       PVR_DUMPDEBUG_LOG(("RGX Power State: %s", _RGXGetDebugDevPowerStateString(ePowerState)));
+
+                       _RGXDumpRGXDebugSummary(pfnDumpDebugPrintf, psDevInfo, bRGXPoweredON);
+
+                       if (bRGXPoweredON)
+                       {
+
+                               PVR_DUMPDEBUG_LOG(("------[ RGX registers ]------"));
+                               PVR_DUMPDEBUG_LOG(("RGX Register Base Address (Linear):   0x%p", psDevInfo->pvRegsBaseKM));
+                               PVR_DUMPDEBUG_LOG(("RGX Register Base Address (Physical): 0x%08lX", (unsigned long)psDevInfo->sRegsPhysBase.uiAddr));
+
+                               /* Forcing bit 6 of MslvCtrl1 to 0 to avoid internal reg read going though the core */
+                               OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x0);
+
+                               eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgCommands, RGX_MAX_DEBUG_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING,"RGXDebugRequestProcess: RGXRunScript failed (%d) - Retry", eError));
+
+                                       /* use thread1 for slave port accesses */
+                                       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x1 << RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT);
+
+                                       eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgCommands, RGX_MAX_DEBUG_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
+                                       if (eError != PVRSRV_OK)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: RGXRunScript retry failed (%d) - Dump Slave Port debug information", eError));
+                                               _RGXDumpMetaSPExtraDebugInfo(pfnDumpDebugPrintf, psDevInfo);
+                                       }
+
+                                       /* use thread0 again */
+                                       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x0 << RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT);
+                               }
+                       }
+                       else
+                       {
+                               PVR_DUMPDEBUG_LOG((" (!) RGX power is down. No registers dumped"));
+                       }
+
+                       /* Dump out the kernel CCBs. */
+                       {
+                               RGXFWIF_DM      eKCCBType;
+                               
+                               for (eKCCBType = 0; eKCCBType < RGXFWIF_DM_MAX; eKCCBType++)
+                               {
+                                       RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eKCCBType];
+               
+                                       if (psKCCBCtl != IMG_NULL)
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("RGX Kernel CCB %u WO:0x%X RO:0x%X",
+                                                                 eKCCBType, psKCCBCtl->ui32WriteOffset, psKCCBCtl->ui32ReadOffset));
+                                       }
+                               }
+                       }
+
+                       /* Dump out the firmware CCBs. */
+                       {
+                               RGXFWIF_DM      eFCCBType;
+                               
+                               for (eFCCBType = 0; eFCCBType < RGXFWIF_DM_MAX; eFCCBType++)
+                               {
+                                       RGXFWIF_CCB_CTL *psFCCBCtl = psDevInfo->apsFirmwareCCBCtl[eFCCBType];
+               
+                                       if (psFCCBCtl != IMG_NULL)
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("RGX Firmware CCB %u WO:0x%X RO:0x%X",
+                                                                 eFCCBType, psFCCBCtl->ui32WriteOffset, psFCCBCtl->ui32ReadOffset));
+                                       }
+                               }
+                       }
+
+                       /* Dump the KCCB commands executed */
+                       {
+                               PVR_DUMPDEBUG_LOG(("RGX Kernel CCB commands executed = %d",
+                                                 psDevInfo->psRGXFWIfTraceBuf->ui32KCCBCmdsExecuted));
+                       }
+
+                       /* Dump the IRQ info */
+                       {
+                               PVR_DUMPDEBUG_LOG(("RGX FW IRQ count = %d, last sampled in MISR = %d",
+                                                 psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount,
+                                                 g_ui32HostSampleIRQCount));
+                       }
+
+                       /* Dump the FW config flags */
+                       {
+                               RGXFWIF_INIT            *psRGXFWInit;
+
+                               eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
+                                               (IMG_VOID **)&psRGXFWInit);
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: Failed to acquire kernel fw if ctl (%u)",
+                                                               eError));
+                                       goto Exit;
+                               }
+
+                               PVR_DUMPDEBUG_LOG(("RGX FW config flags = 0x%X", psRGXFWInit->ui32ConfigFlags));
+
+                               DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+                       }
+
+                       break;
+
+               }
+               case DEBUG_REQUEST_VERBOSITY_MEDIUM :
+               {
+                       IMG_INT tid;
+                       /* Dump FW trace information */
+                       if (psDevInfo->psRGXFWIfTraceBuf != IMG_NULL)
+                       {
+                               RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+               
+                               for ( tid = 0 ; tid < RGXFW_THREAD_NUM ; tid++) 
+                               {
+                                       IMG_UINT32      i;
+                                       IMG_BOOL        bPrevLineWasZero = IMG_FALSE;
+                                       IMG_BOOL        bLineIsAllZeros = IMG_FALSE;
+                                       IMG_UINT32      ui32CountLines = 0;
+                                       IMG_UINT32      *pui32TraceBuffer;
+                                       IMG_CHAR        *pszLine;
+               
+                                       pui32TraceBuffer = &psRGXFWIfTraceBufCtl->sTraceBuf[tid].aui32TraceBuffer[0];
+               
+                                       /* each element in the line is 8 characters plus a space.  The '+1' is because of the final trailing '\0'. */
+                                       pszLine = OSAllocMem(9*RGXFW_TRACE_BUFFER_LINESIZE+1);
+                                       if (pszLine == IMG_NULL)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: Out of mem allocating line string (size: %d)", 9*RGXFW_TRACE_BUFFER_LINESIZE));
+                                               goto Exit;
+                                       }
+               
+                                       /* Print the tracepointer */
+                                       if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK)
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")",
+                                                                 ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")),
+                                                                 RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType)
+                                                                 ));
+                                       }
+                                       else
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("Debug log type: none"));
+                                       }
+                                       
+                                       PVR_DUMPDEBUG_LOG(("------[ RGX FW thread %d trace START ]------", tid));
+                                       PVR_DUMPDEBUG_LOG(("FWT[traceptr]: %X", psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer));
+                                       PVR_DUMPDEBUG_LOG(("FWT[tracebufsize]: %X", RGXFW_TRACE_BUFFER_SIZE));
+               
+                                       for (i = 0; i < RGXFW_TRACE_BUFFER_SIZE; i += RGXFW_TRACE_BUFFER_LINESIZE)
+                                       {
+                                               IMG_UINT32 k = 0;
+                                               IMG_UINT32 ui32Line = 0x0;
+                                               IMG_UINT32 ui32LineOffset = i*sizeof(IMG_UINT32);
+                                               IMG_CHAR   *pszBuf = pszLine;
+               
+                                               for (k = 0; k < RGXFW_TRACE_BUFFER_LINESIZE; k++)
+                                               {
+                                                       ui32Line |= pui32TraceBuffer[i + k];
+               
+                                                       /* prepare the line to print it. The '+1' is because of the trailing '\0' added */
+                                                       OSSNPrintf(pszBuf, 9 + 1, " %08x", pui32TraceBuffer[i + k]);
+                                                       pszBuf += 9; /* write over the '\0' */
+                                               }
+               
+                                               bLineIsAllZeros = (ui32Line == 0x0);
+               
+                                               if (bLineIsAllZeros)
+                                               {
+                                                       if (bPrevLineWasZero)
+                                                       {
+                                                               ui32CountLines++;
+                                                       }
+                                                       else
+                                                       {
+                                                               bPrevLineWasZero = IMG_TRUE;
+                                                               ui32CountLines = 1;
+                                                               PVR_DUMPDEBUG_LOG(("FWT[%08x]: 00000000 ... 00000000", ui32LineOffset));
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       if (bPrevLineWasZero  &&  ui32CountLines > 1)
+                                                       {
+                                                               PVR_DUMPDEBUG_LOG(("FWT[...]: %d lines were all zero", ui32CountLines));
+                                                       }
+                                                       bPrevLineWasZero = IMG_FALSE;
+
+                                                       PVR_DUMPDEBUG_LOG(("FWT[%08x]:%s", ui32LineOffset, pszLine));
+                                               }
+               
+                                       }
+                                       if (bPrevLineWasZero)
+                                       {
+                                               PVR_DUMPDEBUG_LOG(("FWT[END]: %d lines were all zero", ui32CountLines));
+                                       }
+               
+                                       PVR_DUMPDEBUG_LOG(("------[ RGX FW thread %d trace END ]------", tid));
+               
+                                       OSFreeMem(pszLine);
+                               }
+                       }
+
+                       {
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
+                               PVR_DUMPDEBUG_LOG(("------[ Full CCB Status ]------"));
+#else
+                               PVR_DUMPDEBUG_LOG(("------[ Stalled FWCtxs ]------"));
+#endif
+                               CheckForStalledTransferCtxt(psDevInfo, pfnDumpDebugPrintf);
+                               CheckForStalledRenderCtxt(psDevInfo, pfnDumpDebugPrintf);
+                               CheckForStalledComputeCtxt(psDevInfo, pfnDumpDebugPrintf);
+#if defined(RGX_FEATURE_RAY_TRACING)
+                               CheckForStalledRayCtxt(psDevInfo, pfnDumpDebugPrintf);
+#endif
+                       }
+                       break;
+               }
+               case DEBUG_REQUEST_VERBOSITY_HIGH:
+               {
+                       PVRSRV_ERROR            eError;
+                       IMG_UINT32              ui32DeviceIndex;
+                       PVRSRV_DEV_POWER_STATE  ePowerState;
+                       IMG_BOOL                bRGXPoweredON;
+
+                       ui32DeviceIndex = psDevInfo->psDeviceNode->sDevId.ui32DeviceIndex;
+
+                       eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess: Error retrieving RGX power state. No debug info dumped."));
+                               return;
+                       }
+
+                       bRGXPoweredON = (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
+
+                       PVR_DUMPDEBUG_LOG(("------[ Debug bus ]------"));
+
+                       _RGXDumpRGXDebugSummary(pfnDumpDebugPrintf, psDevInfo, bRGXPoweredON);
+
+                       if (bRGXPoweredON)
+                       {
+                               eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgBusCommands, RGX_MAX_DBGBUS_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING,"RGXDebugRequestProcess: RGXRunScript failed (%s)", PVRSRVGetErrorStringKM(eError)));
+                               }
+                               break;
+                       }
+               }
+               default:
+                       break;
+       }
+
+Exit:
+       PVRSRVPowerUnlock();
+}
+
+/*
+       RGXPanic
+*/
+IMG_VOID RGXPanic(PVRSRV_RGXDEV_INFO   *psDevInfo)
+{
+       PVR_LOG(("RGX panic"));
+       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+       OSPanic();
+}
+
+/*
+       RGXQueryDMState
+*/
+PVRSRV_ERROR RGXQueryDMState(PVRSRV_RGXDEV_INFO *psDevInfo, RGXFWIF_DM eDM, RGXFWIF_DM_STATE *peState, RGXFWIF_DEV_VIRTADDR *psCommonContextDevVAddr)
+{
+       PVRSRV_ERROR    eError = PVRSRV_OK;
+       RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+
+       if (eDM >= RGXFWIF_DM_MAX)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: eDM parameter is out of range (%u)",eError));
+               return eError;
+       }
+
+       if (peState == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: peState is NULL (%u)",eError));
+               return eError;
+       }
+
+       if (psCommonContextDevVAddr == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: psCommonContextDevVAddr is NULL (%u)",eError));
+               return eError;
+       }
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: Failed (%d) to acquire address for trace buffer", eError));
+               return eError;
+       }
+
+       if (psRGXFWIfTraceBufCtl->apsHwrDmFWCommonContext[eDM].ui32Addr)
+       {
+               *peState = RGXFWIF_DM_STATE_LOCKEDUP;
+       }
+       else
+       {
+               *peState = RGXFWIF_DM_STATE_NORMAL;
+       }
+       
+       *psCommonContextDevVAddr = psRGXFWIfTraceBufCtl->apsHwrDmFWCommonContext[eDM];
+
+       return eError;
+}
+
+
+/******************************************************************************
+ End of file (rgxdebug.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdebug.h
new file mode 100644 (file)
index 0000000..498dc99
--- /dev/null
@@ -0,0 +1,166 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX debug header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX debugging functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXDEBUG_H__)
+#define __RGXDEBUG_H__
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "device.h"
+#include "pvrsrv.h"
+#include "rgxdevice.h"
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXPanic
+
+ @Description
+
+ Called when an unrecoverable situation is detected. Dumps RGX debug
+ information and tells the OS to panic.
+
+ @Input psDevInfo - RGX device info
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXPanic(PVRSRV_RGXDEV_INFO   *psDevInfo);
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDumpDebugInfo
+
+ @Description
+
+ Dump useful debugging info. Dumps lesser information than PVRSRVDebugRequest.
+ Does not dump debugging information for all requester types.(SysDebug, ServerSync info)
+
+ @Input pfnDumpDebugPrintf  - Optional replacement print function
+ @Input psDevInfo              - RGX device info
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXDumpDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                          PVRSRV_RGXDEV_INFO   *psDevInfo);
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDebugRequestProcess
+
+ @Description
+
+ This function will print out the debug for the specificed level of
+ verbosity
+
+ @Input pfnDumpDebugPrintf  - Optional replacement print function
+ @Input psDevInfo              - RGX device info
+ @Input ui32VerbLevel       - Verbosity level
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXDebugRequestProcess(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                                PVRSRV_RGXDEV_INFO     *psDevInfo,
+                                IMG_UINT32                     ui32VerbLevel);
+
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+/*!
+*******************************************************************************
+
+ @Function     RGXDumpFirmwareTrace
+
+ @Description Dumps the decoded version of the firmware trace buffer.
+
+ Dump useful debugging info
+
+ @Input pfnDumpDebugPrintf  - Optional replacement print function
+ @Input psDevInfo              - RGX device info
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXDumpFirmwareTrace(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+                              PVRSRV_RGXDEV_INFO       *psDevInfo);
+#endif
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXQueryDMState
+
+ @Description
+
+ Query DM state
+
+ @Input  psDevInfo        - RGX device info
+ @Input  eDM              - DM number for which to return status
+ @Output peState          - RGXFWIF_DM_STATE
+ @Output psComCtxDevVAddr - If DM is locked-up, Firmware address of Firmware Common Context, otherwise IMG_NULL
+
+ @Return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR RGXQueryDMState(PVRSRV_RGXDEV_INFO *psDevInfo, RGXFWIF_DM eDM, RGXFWIF_DM_STATE *peState, RGXFWIF_DEV_VIRTADDR *psComCtxDevVAddr);
+
+/*!
+*******************************************************************************
+
+ @Function     RGXReadWithSP
+
+ @Description
+
+ Reads data from a memory location (FW memory map) using the META Slave Port
+
+ @Input  ui32FWAddr - 32 bit FW address
+
+ @Return IMG_UINT32
+******************************************************************************/
+IMG_UINT32 RGXReadWithSP(IMG_UINT32 ui32FWAddr);
+
+#endif /* __RGXDEBUG_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdevice.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxdevice.h
new file mode 100644 (file)
index 0000000..00e2e50
--- /dev/null
@@ -0,0 +1,422 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX device node header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX device node
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXDEVICE_H__)
+#define __RGXDEVICE_H__
+
+#include "img_types.h"
+#include "pvrsrv_device_types.h"
+#include "mmu_common.h"
+#include "rgx_fwif_km.h"
+#include "rgx_fwif.h"
+#include "rgxscript.h"
+#include "cache_external.h"
+#include "device.h"
+#include "osfunc.h"
+
+typedef struct _RGX_SERVER_COMMON_CONTEXT_ RGX_SERVER_COMMON_CONTEXT;
+
+typedef struct {
+       DEVMEM_MEMDESC          *psFWFrameworkMemDesc;
+       IMG_DEV_VIRTADDR        *psMCUFenceAddr;
+} RGX_COMMON_CONTEXT_INFO;
+
+
+/*!
+ ******************************************************************************
+ * Device state flags
+ *****************************************************************************/
+#define RGXKM_DEVICE_STATE_ZERO_FREELIST                       (0x1 << 0)              /*!< Zeroing the physical pages of reconstructed free lists */
+#define RGXKM_DEVICE_STATE_FTRACE_EN                           (0x1 << 1)              /*!< Used to enable device FTrace thread to consume HWPerf data */
+#define RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN       (0x1 << 2)              /*!< Used to disable the Devices Watchdog logging */
+
+
+/*!
+ ******************************************************************************
+ * GPU DVFS Table
+ *****************************************************************************/
+
+#define RGX_GPU_DVFS_TABLE_SIZE            100                      /* DVFS Table size */
+#define RGX_GPU_DVFS_GET_INDEX(clockfreq)  ((clockfreq) / 10000000) /* Assuming different GPU clocks are separated by at least 10MHz
+                                                                     * WARNING: this macro must be used only with nominal values of
+                                                                     * the GPU clock speed (the ones provided by the customer code) */
+#define RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US       25000          /* Time required to calibrate a clock frequency the first time */
+#define RGX_GPU_DVFS_TRANSITION_CALIBRATION_TIME_US  150000         /* Time required for a recalibration after a DVFS transition */
+#define RGX_GPU_DVFS_PERIODIC_CALIBRATION_TIME_US    10000000       /* Time before the next periodic calibration and correlation */
+
+typedef struct _RGX_GPU_DVFS_TABLE_
+{
+       IMG_UINT64 ui64CalibrationCRTimestamp;              /*!< CR timestamp used to calibrate GPU frequencies (beginning of a calibration period) */
+       IMG_UINT64 ui64CalibrationOSTimestamp;              /*!< OS timestamp used to calibrate GPU frequencies (beginning of a calibration period) */
+       IMG_UINT64 ui64CalibrationCRTimediff;               /*!< CR timediff used to calibrate GPU frequencies (calibration period) */
+       IMG_UINT64 ui64CalibrationOSTimediff;               /*!< OS timediff used to calibrate GPU frequencies (calibration period) */
+       IMG_UINT32 ui32CalibrationPeriod;                   /*!< Threshold used to determine whether the current GPU frequency should be calibrated */
+       IMG_UINT32 ui32CurrentDVFSId;                       /*!< Current table entry index */
+       IMG_BOOL   bAccumulatePeriod;                       /*!< Accumulate many consecutive periods to get a better calibration at the end */
+       IMG_UINT32 aui32DVFSClock[RGX_GPU_DVFS_TABLE_SIZE]; /*!< DVFS clocks table (clocks in Hz) */
+} RGX_GPU_DVFS_TABLE;
+
+
+/*!
+ ******************************************************************************
+ * GPU utilisation statistics
+ *****************************************************************************/
+
+typedef struct _RGXFWIF_GPU_UTIL_STATS_
+{
+       IMG_BOOL   bValid;                /* If TRUE, statistics are valid.
+                                            FALSE if the driver couldn't get reliable stats. */
+       IMG_UINT64 ui64GpuStatActiveHigh; /* GPU active high statistic */
+       IMG_UINT64 ui64GpuStatActiveLow;  /* GPU active low (i.e. TLA active only) statistic */
+       IMG_UINT64 ui64GpuStatBlocked;    /* GPU blocked statistic */
+       IMG_UINT64 ui64GpuStatIdle;       /* GPU idle statistic */
+       IMG_UINT64 ui64GpuStatCumulative; /* Sum of active/blocked/idle stats */
+
+#if defined(GPU_UTIL_SLC_STALL_COUNTERS)
+       IMG_UINT32 ui32SLCStallsRatio;    /* SLC Read/Write stalls ratio expressed in 0,01% units */
+#endif
+#if defined(PVR_POWER_ACTOR) && defined (PVR_DVFS)
+       IMG_UINT32 ui32GpuEnergy;         /* GPU dynamic energy */
+#endif
+} RGXFWIF_GPU_UTIL_STATS;
+
+
+typedef struct _RGX_REG_CONFIG_
+{
+       IMG_BOOL                        bEnabled;
+       RGXFWIF_PWR_EVT         ePowerIslandToPush;
+       IMG_UINT32              ui32NumRegRecords;
+} RGX_REG_CONFIG;
+
+typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
+
+/* there is a corresponding define in rgxapi.h */
+#define RGX_MAX_TIMER_QUERIES 16
+
+/*!
+ ******************************************************************************
+ * RGX Device info
+ *****************************************************************************/
+
+typedef struct _PVRSRV_RGXDEV_INFO_
+{
+       PVRSRV_DEVICE_TYPE              eDeviceType;
+       PVRSRV_DEVICE_CLASS             eDeviceClass;
+       PVRSRV_DEVICE_NODE              *psDeviceNode;
+
+       IMG_UINT8                               ui8VersionMajor;
+       IMG_UINT8                               ui8VersionMinor;
+       IMG_UINT32                              ui32CoreConfig;
+       IMG_UINT32                              ui32CoreFlags;
+
+       IMG_BOOL                bFirmwareInitialised;
+       IMG_BOOL                                bPDPEnabled;
+
+       /* Kernel mode linear address of device registers */
+       IMG_PVOID                               pvRegsBaseKM;
+
+       /* FIXME: The alloc for this should go through OSAllocMem in future */
+       IMG_HANDLE                              hRegMapping;
+
+       /* System physical address of device registers*/
+       IMG_CPU_PHYADDR                 sRegsPhysBase;
+       /*  Register region size in bytes */
+       IMG_UINT32                              ui32RegSize;
+
+       PVRSRV_STUB_PBDESC              *psStubPBDescListKM;
+
+       /* Firmware memory context info */
+       DEVMEM_CONTEXT                  *psKernelDevmemCtx;
+       DEVMEM_HEAP                             *psFirmwareHeap;
+       MMU_CONTEXT                             *psKernelMMUCtx;
+       IMG_UINT32                              ui32KernelCatBaseIdReg;
+       IMG_UINT32                              ui32KernelCatBaseId;
+       IMG_UINT32                              ui32KernelCatBaseReg;
+       IMG_UINT32                              ui32KernelCatBaseWordSize;
+       IMG_UINT32                              ui32KernelCatBaseAlignShift;
+       IMG_UINT32                              ui32KernelCatBaseShift;
+       IMG_UINT64                              ui64KernelCatBaseMask;
+
+       IMG_VOID                                *pvDeviceMemoryHeap;
+       
+       /* Kernel CCBs */
+       DEVMEM_MEMDESC                  *apsKernelCCBCtlMemDesc[RGXFWIF_DM_MAX];        /*!< memdesc for kernel CCB control */
+       RGXFWIF_CCB_CTL                 *apsKernelCCBCtl[RGXFWIF_DM_MAX];                       /*!< kernel CCB control kernel mapping */
+       DEVMEM_MEMDESC                  *apsKernelCCBMemDesc[RGXFWIF_DM_MAX];           /*!< memdesc for kernel CCB */
+       IMG_UINT8                               *apsKernelCCB[RGXFWIF_DM_MAX];                          /*!< kernel CCB kernel mapping */
+
+       /* Firmware CCBs */
+       DEVMEM_MEMDESC                  *apsFirmwareCCBCtlMemDesc[RGXFWIF_DM_MAX];      /*!< memdesc for Firmware CCB control */
+       RGXFWIF_CCB_CTL                 *apsFirmwareCCBCtl[RGXFWIF_DM_MAX];                     /*!< kernel CCB control Firmware mapping */
+       DEVMEM_MEMDESC                  *apsFirmwareCCBMemDesc[RGXFWIF_DM_MAX];         /*!< memdesc for Firmware CCB */
+       IMG_UINT8                               *apsFirmwareCCB[RGXFWIF_DM_MAX];                                /*!< kernel CCB Firmware mapping */
+
+       /*
+               if we don't preallocate the pagetables we must 
+               insert newly allocated page tables dynamically 
+       */
+       IMG_VOID                                *pvMMUContextList;
+
+       IMG_UINT32                              ui32ClkGateStatusReg;
+       IMG_UINT32                              ui32ClkGateStatusMask;
+       RGX_SCRIPTS                             *psScripts;
+
+       DEVMEM_MEMDESC                  *psRGXFWCodeMemDesc;
+       DEVMEM_EXPORTCOOKIE             sRGXFWCodeExportCookie;
+
+       DEVMEM_MEMDESC                  *psRGXFWDataMemDesc;
+       DEVMEM_EXPORTCOOKIE             sRGXFWDataExportCookie;
+
+       DEVMEM_MEMDESC                  *psRGXFWCorememMemDesc;
+       DEVMEM_EXPORTCOOKIE             sRGXFWCorememExportCookie;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfTraceBufCtlMemDesc;
+       RGXFWIF_TRACEBUF                *psRGXFWIfTraceBuf;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfHWRInfoBufCtlMemDesc;
+       RGXFWIF_HWRINFOBUF              *psRGXFWIfHWRInfoBuf;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfGpuUtilFWCbCtlMemDesc;
+       RGXFWIF_GPU_UTIL_FWCB   *psRGXFWIfGpuUtilFWCb;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfHWPerfBufMemDesc;
+       IMG_BYTE                                *psRGXFWIfHWPerfBuf;
+       IMG_UINT32                              ui32RGXFWIfHWPerfBufSize; /* in bytes */
+
+       DEVMEM_MEMDESC                  *psRGXFWIfCorememDataStoreMemDesc;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfRegCfgMemDesc;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfHWPerfCountersMemDesc;
+       DEVMEM_EXPORTCOOKIE     sRGXFWHWPerfCountersExportCookie;
+       DEVMEM_MEMDESC                  *psRGXFWIfInitMemDesc;
+
+       DEVMEM_MEMDESC                  *psRGXFWIfRuntimeCfgMemDesc;
+       RGXFWIF_RUNTIME_CFG             *psRGXFWIfRuntimeCfg;
+
+#if defined(RGXFW_ALIGNCHECKS)
+       DEVMEM_MEMDESC                  *psRGXFWAlignChecksMemDesc;
+#endif
+
+       DEVMEM_MEMDESC                  *psRGXFWSigTAChecksMemDesc;
+       IMG_UINT32                              ui32SigTAChecksSize;
+
+       DEVMEM_MEMDESC                  *psRGXFWSig3DChecksMemDesc;
+       IMG_UINT32                              ui32Sig3DChecksSize;
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       DEVMEM_MEMDESC                  *psRGXFWSigRTChecksMemDesc;
+       IMG_UINT32                              ui32SigRTChecksSize;
+       
+       DEVMEM_MEMDESC                  *psRGXFWSigSHChecksMemDesc;
+       IMG_UINT32                              ui32SigSHChecksSize;
+#endif
+
+       IMG_VOID                                *pvLISRData;
+       IMG_VOID                                *pvMISRData;
+       IMG_VOID                                *pvAPMISRData;
+       
+       DEVMEM_MEMDESC                  *psRGXFaultAddressMemDesc;
+
+#if defined(FIX_HW_BRN_37200)
+       DEVMEM_MEMDESC                  *psRGXFWHWBRN37200MemDesc;
+#endif
+
+#if defined(RGX_FEATURE_SLC_VIVT)
+       DEVMEM_MEMDESC                  *psSLC3FenceMemDesc;
+#endif
+
+#if defined (PDUMP)
+       IMG_BOOL                                abDumpedKCCBCtlAlready[RGXFWIF_DM_MAX];
+       
+#endif 
+
+       /*! Handles to the lock and stream objects used to transport
+        * HWPerf data to user side clients. See RGXHWPerfInit() RGXHWPerfDeinit().
+        * Set during initialisation if the application hint turns bit 7
+        * 'Enable HWPerf' on in the ConfigFlags sent to the FW. FW stores this
+        * bit in the RGXFW_CTL.ui32StateFlags member. They may also get
+        * set by the API RGXCtrlHWPerf(). Thus these members may be 0 if HWPerf is
+        * not enabled as these members are created on demand and destroyed at
+        * driver unload.
+        */
+       POS_LOCK                                hLockHWPerfStream;
+       IMG_HANDLE                              hHWPerfStream;
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+       IMG_HANDLE                              hGPUTraceCmdCompleteHandle;
+       IMG_BOOL                                bFTraceGPUEventsEnabled;
+       IMG_HANDLE                              hGPUTraceTLConnection;
+       IMG_HANDLE                              hGPUTraceTLStream;
+       IMG_UINT64                              ui64LastSampledTimeCorrOSTimeStamp;
+#endif
+
+       /* If we do 10 deferred memory allocations per second, then the ID would warp around after 13 years */
+       IMG_UINT32                              ui32ZSBufferCurrID;     /*!< ID assigned to the next deferred devmem allocation */
+       IMG_UINT32                              ui32FreelistCurrID;     /*!< ID assigned to the next freelist */
+       IMG_UINT32                              ui32RPMFreelistCurrID;  /*!< ID assigned to the next RPM freelist */
+
+       POS_LOCK                                hLockZSBuffer;          /*!< Lock to protect simultaneous access to ZSBuffers */
+       DLLIST_NODE                             sZSBufferHead;          /*!< List of on-demand ZSBuffers */
+       POS_LOCK                                hLockFreeList;          /*!< Lock to protect simultaneous access to Freelists */
+       DLLIST_NODE                             sFreeListHead;          /*!< List of growable Freelists */
+       POS_LOCK                                hLockRPMFreeList;       /*!< Lock to protect simultaneous access to RPM Freelists */
+       DLLIST_NODE                             sRPMFreeListHead;       /*!< List of growable RPM Freelists */
+       PSYNC_PRIM_CONTEXT              hSyncPrimContext;
+       PVRSRV_CLIENT_SYNC_PRIM *psPowSyncPrim;
+
+       IMG_UINT32                              ui32ActivePMReqOk;
+       IMG_UINT32                              ui32ActivePMReqDenied;
+       IMG_UINT32                              ui32ActivePMReqTotal;
+       
+       IMG_HANDLE                              hProcessQueuesMISR;
+
+       IMG_UINT32                              ui32DeviceFlags;        /*!< Flags to track general device state  */
+
+       /* Poll data for detecting firmware fatal errors */
+       IMG_UINT32  aui32CrLastPollAddr[RGXFW_THREAD_NUM];
+       IMG_UINT32  ui32KCCBCmdsExecutedLastTime;
+       IMG_BOOL    bKCCBCmdsWaitingLastTime;
+       IMG_UINT32  ui32GEOTimeoutsLastTime;
+
+       /* Client stall detection */
+       IMG_BOOL        bStalledClient;
+
+       /* Timer Queries */
+       IMG_UINT32        ui32ActiveQueryId;       /*!< id of the active line */
+       IMG_BOOL          bSaveStart;              /*!< save the start time of the next kick on the device*/
+       IMG_BOOL          bSaveEnd;                /*!< save the end time of the next kick on the device*/
+
+       DEVMEM_MEMDESC    * psStartTimeMemDesc;    /*!< memdesc for Start Times */
+       RGXFWIF_TIMESTAMP * pasStartTimeById;      /*!< CPU mapping of the above */
+
+       DEVMEM_MEMDESC    * psEndTimeMemDesc;      /*!< memdesc for End Timer */
+       RGXFWIF_TIMESTAMP * pasEndTimeById;        /*!< CPU mapping of the above */
+
+       IMG_UINT32        aui32ScheduledOnId[RGX_MAX_TIMER_QUERIES];      /*!< kicks Scheduled on QueryId */
+       DEVMEM_MEMDESC    * psCompletedMemDesc;    /*!< kicks Completed on QueryId */
+       IMG_UINT32        * pui32CompletedById;    /*!< CPU mapping of the above */
+
+       /* GPU DVFS Table */
+       RGX_GPU_DVFS_TABLE  *psGpuDVFSTable;
+
+       /* Pointer to function returning the GPU utilisation statistics since the last
+        * time the function was called. Supports different users at the same time.
+        *
+        * psReturnStats [out]: GPU utilisation statistics (active high/active low/idle/blocked)
+        *                      in microseconds since the last time the function was called
+        *                      by a specific user (identified by hGpuUtilUser)
+        *
+        * Returns PVRSRV_OK in case the call completed without errors,
+        * some other value otherwise.
+        */
+       PVRSRV_ERROR (*pfnGetGpuUtilStats) (PVRSRV_DEVICE_NODE *psDeviceNode,
+                                           IMG_HANDLE hGpuUtilUser,
+                                           RGXFWIF_GPU_UTIL_STATS *psReturnStats);
+
+       PVRSRV_ERROR (*pfnRegisterGpuUtilStats) (IMG_HANDLE *phGpuUtilUser);
+       PVRSRV_ERROR (*pfnUnregisterGpuUtilStats) (IMG_HANDLE hGpuUtilUser);
+
+       POS_LOCK    hGPUUtilLock;
+
+       /* Register configuration */
+       RGX_REG_CONFIG          sRegCongfig;
+
+       IMG_BOOL                                bIgnoreFurtherIRQs;
+       DLLIST_NODE                             sMemoryContextList;
+
+       POSWR_LOCK              hRenderCtxListLock;
+       POSWR_LOCK              hComputeCtxListLock;
+       POSWR_LOCK              hTransferCtxListLock;
+       POSWR_LOCK              hRaytraceCtxListLock;
+       POSWR_LOCK              hMemoryCtxListLock;
+
+       /* Linked lists of contexts on this device */
+       DLLIST_NODE             sRenderCtxtListHead;
+       DLLIST_NODE             sComputeCtxtListHead;
+       DLLIST_NODE             sTransferCtxtListHead;
+       DLLIST_NODE             sRaytraceCtxtListHead;
+
+       DLLIST_NODE             sCommonCtxtListHead;
+       IMG_UINT32                      ui32CommonCtxtCurrentID;                        /*!< ID assigned to the next common context */
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       POS_LOCK                                hDebugFaultInfoLock;            /*!< Lock to protect the debug fault info list */
+       POS_LOCK                                hMMUCtxUnregLock;       /*!< Lock to protect list of unregistered MMU contexts */
+#endif
+} PVRSRV_RGXDEV_INFO;
+
+
+
+typedef struct _RGX_TIMING_INFORMATION_
+{
+       /*! GPU default core clock speed in Hz */
+       IMG_UINT32                      ui32CoreClockSpeed;
+
+       /*! Active Power Management: GPU actively requests the host driver to be powered off */
+       IMG_BOOL                        bEnableActivePM;
+
+       /*! Enable the GPU to power off internal Power Islands independently from the host driver */
+       IMG_BOOL                        bEnableRDPowIsland;
+       
+       /*! Active Power Management: Delay between the GPU idle and the request to the host */
+       IMG_UINT32                      ui32ActivePMLatencyms;
+
+} RGX_TIMING_INFORMATION;
+
+typedef struct _RGX_DATA_
+{
+       /*! Timing information */
+       RGX_TIMING_INFORMATION  *psRGXTimingInfo;
+       IMG_BOOL bHasTDMetaCodePhysHeap;
+       IMG_UINT32 uiTDMetaCodePhysHeapID;
+       IMG_BOOL bHasTDSecureBufPhysHeap;
+       IMG_UINT32 uiTDSecureBufPhysHeapID;
+} RGX_DATA;
+
+
+/*
+       RGX PDUMP register bank name (prefix)
+*/
+#define RGX_PDUMPREG_NAME              "RGXREG"
+
+#endif /* __RGXDEVICE_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.c
new file mode 100644 (file)
index 0000000..9026aef
--- /dev/null
@@ -0,0 +1,4062 @@
+ /*************************************************************************/ /*!
+@File
+@Title          Rogue firmware utility routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Rogue firmware utility routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "lists.h"
+
+#include "rgxdefs_km.h"
+#include "rgx_fwif_km.h"
+#include "pdump_km.h"
+#include "osfunc.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "devicemem_server.h"
+#include "pvr_debug.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif.h"
+#include "rgx_fwif_alignchecks_km.h"
+#include "rgx_fwif_resetframework.h"
+#include "rgx_pdump_panics.h"
+#include "rgxheapconfig.h"
+#include "pvrsrv.h"
+#include "rgxdebug.h"
+#include "rgxhwperf.h"
+#include "rgxccb.h"
+#include "rgxcompute.h"
+#include "rgxtransfer.h"
+#if defined(RGX_FEATURE_RAY_TRACING)
+#include "rgxray.h"
+#endif
+#if defined(SUPPORT_DISPLAY_CLASS)
+#include "dc_server.h"
+#endif
+#include "rgxmem.h"
+#include "rgxta3d.h"
+#include "rgxutils.h"
+#include "sync_internal.h"
+#include "tlstream.h"
+#include "devicemem_server_utils.h"
+
+#if defined(TDMETACODE)
+#include "physmem_osmem.h"
+#endif
+
+#ifdef __linux__
+#include <linux/kernel.h>      // sprintf
+#include <linux/string.h>      // strncpy, strlen
+#include "trace_events.h"
+#else
+#include <stdio.h>
+#endif
+
+#include "process_stats.h"
+/* Kernel CCB length */
+#define RGXFWIF_KCCB_TA_NUMCMDS_LOG2   (6)
+#define RGXFWIF_KCCB_3D_NUMCMDS_LOG2   (6)
+#define RGXFWIF_KCCB_2D_NUMCMDS_LOG2   (6)
+#define RGXFWIF_KCCB_CDM_NUMCMDS_LOG2  (6)
+#define RGXFWIF_KCCB_GP_NUMCMDS_LOG2   (6)
+#define RGXFWIF_KCCB_RTU_NUMCMDS_LOG2  (6)
+#define RGXFWIF_KCCB_SHG_NUMCMDS_LOG2  (6)
+
+/* Firmware CCB length */
+#define RGXFWIF_FWCCB_TA_NUMCMDS_LOG2  (4)
+#define RGXFWIF_FWCCB_3D_NUMCMDS_LOG2  (4)
+#define RGXFWIF_FWCCB_2D_NUMCMDS_LOG2  (4)
+#define RGXFWIF_FWCCB_CDM_NUMCMDS_LOG2 (4)
+#define RGXFWIF_FWCCB_GP_NUMCMDS_LOG2  (4)
+#define RGXFWIF_FWCCB_RTU_NUMCMDS_LOG2 (4)
+#define RGXFWIF_FWCCB_SHG_NUMCMDS_LOG2 (4)
+
+#if defined(RGX_FEATURE_SLC_VIVT)
+static PVRSRV_ERROR _AllocateSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo, RGXFWIF_INIT* psRGXFWInit)
+{
+       PVRSRV_ERROR eError;
+       DEVMEM_MEMDESC** ppsSLC3FenceMemDesc = &psDevInfo->psSLC3FenceMemDesc;
+
+       PVR_DPF_ENTERED;
+
+       eError = DevmemAllocate(psDevInfo->psFirmwareHeap,
+                                                       1,
+                                                       ROGUE_CACHE_LINE_SIZE,
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                            PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | 
+                                                       PVRSRV_MEMALLOCFLAG_UNCACHED,
+                                                       "SLC3 Fence WA",
+                                                       ppsSLC3FenceMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF_RETURN_RC(eError);
+       }
+
+       /*
+               We need to map it so the heap for this allocation
+               is set
+       */
+       eError = DevmemMapToDevice(*ppsSLC3FenceMemDesc,
+                                                          psDevInfo->psFirmwareHeap,
+                                                          &psRGXFWInit->sSLC3FenceDevVAddr);
+       if (eError != PVRSRV_OK)
+       {
+               DevmemFwFree(*ppsSLC3FenceMemDesc);
+       }
+
+       PVR_DPF_RETURN_RC1(eError, *ppsSLC3FenceMemDesc);
+}
+
+static IMG_VOID _FreeSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo)
+{
+       DEVMEM_MEMDESC* psSLC3FenceMemDesc = psDevInfo->psSLC3FenceMemDesc;
+
+       if (psSLC3FenceMemDesc)
+       {
+               DevmemReleaseDevVirtAddr(psSLC3FenceMemDesc);
+               DevmemFree(psSLC3FenceMemDesc);
+       }
+}
+#endif
+
+static IMG_VOID __MTSScheduleWrite(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Value)
+{
+       /* ensure memory is flushed before kicking MTS */
+       OSWriteMemoryBarrier();
+
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_SCHEDULE, ui32Value);
+
+       /* ensure the MTS kick goes through before continuing */
+       OSMemoryBarrier();
+}
+
+
+/*!
+*******************************************************************************
+ @Function             RGXFWSetupSignatureChecks
+ @Description  
+ @Input                        psDevInfo
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR RGXFWSetupSignatureChecks(PVRSRV_RGXDEV_INFO* psDevInfo,
+                                              DEVMEM_MEMDESC**    ppsSigChecksMemDesc, 
+                                              IMG_UINT32          ui32SigChecksBufSize,
+                                              RGXFWIF_SIGBUF_CTL* psSigBufCtl,
+                                              const IMG_CHAR*     pszBufferName)
+{
+       PVRSRV_ERROR    eError;
+       DEVMEM_FLAGS_T  uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                                         PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                                                         PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                         PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                                         PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | 
+                                                                         PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                                         PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /* Allocate memory for the checks */
+       PDUMPCOMMENT("Allocate memory for %s signature checks", pszBufferName);
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       ui32SigChecksBufSize,
+                                                       uiMemAllocFlags,
+                                                       "SignatureChecks",
+                                                       ppsSigChecksMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for signature checks (%u)",
+                                       ui32SigChecksBufSize,
+                                       eError));
+               return eError;
+       }
+
+       /* Prepare the pointer for the fw to access that memory */
+       RGXSetFirmwareAddress(&psSigBufCtl->psBuffer,
+                                                 *ppsSigChecksMemDesc,
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       DevmemPDumpLoadMem(     *ppsSigChecksMemDesc,
+                                               0,
+                                               ui32SigChecksBufSize,
+                                               PDUMP_FLAGS_CONTINUOUS);
+
+       psSigBufCtl->ui32LeftSizeInRegs = ui32SigChecksBufSize / sizeof(IMG_UINT32);
+
+       return PVRSRV_OK;
+}
+
+#if defined(RGXFW_ALIGNCHECKS)
+/*!
+*******************************************************************************
+ @Function             RGXFWSetupAlignChecks
+ @Description  
+ @Input                        psDevInfo
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR RGXFWSetupAlignChecks(PVRSRV_RGXDEV_INFO* psDevInfo, 
+                                                               RGXFWIF_DEV_VIRTADDR    *psAlignChecksDevFW,
+                                                               IMG_UINT32                              *pui32RGXFWAlignChecks,
+                                                               IMG_UINT32                              ui32RGXFWAlignChecksSize)
+{
+       IMG_UINT32              aui32RGXFWAlignChecksKM[] = { RGXFW_ALIGN_CHECKS_INIT_KM };
+       IMG_UINT32              ui32RGXFWAlingChecksTotal = sizeof(aui32RGXFWAlignChecksKM) + ui32RGXFWAlignChecksSize;
+       IMG_UINT32*             paui32AlignChecks;
+       PVRSRV_ERROR    eError;
+
+       /* Allocate memory for the checks */
+       PDUMPCOMMENT("Allocate memory for alignment checks");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       ui32RGXFWAlingChecksTotal,
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | PVRSRV_MEMALLOCFLAG_UNCACHED,
+                                                       "AlignmentChecks",
+                                                       &psDevInfo->psRGXFWAlignChecksMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for alignment checks (%u)",
+                                       ui32RGXFWAlingChecksTotal,
+                                       eError));
+               goto failAlloc;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc,
+                                                                       (IMG_VOID **)&paui32AlignChecks);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel addr for alignment checks (%u)",
+                                       eError));
+               goto failAqCpuAddr;
+       }
+
+       /* Copy the values */
+       OSMemCopy(paui32AlignChecks, &aui32RGXFWAlignChecksKM[0], sizeof(aui32RGXFWAlignChecksKM));
+       paui32AlignChecks += sizeof(aui32RGXFWAlignChecksKM)/sizeof(IMG_UINT32);
+
+       OSMemCopy(paui32AlignChecks, pui32RGXFWAlignChecks, ui32RGXFWAlignChecksSize);
+
+       DevmemPDumpLoadMem(     psDevInfo->psRGXFWAlignChecksMemDesc,
+                                               0,
+                                               ui32RGXFWAlingChecksTotal,
+                                               PDUMP_FLAGS_CONTINUOUS);
+
+       /* Prepare the pointer for the fw to access that memory */
+       RGXSetFirmwareAddress(psAlignChecksDevFW,
+                                                 psDevInfo->psRGXFWAlignChecksMemDesc,
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       return PVRSRV_OK;
+
+
+
+
+failAqCpuAddr:
+       DevmemFwFree(psDevInfo->psRGXFWAlignChecksMemDesc);
+failAlloc:
+
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static IMG_VOID RGXFWFreeAlignChecks(PVRSRV_RGXDEV_INFO* psDevInfo)
+{
+       if (psDevInfo->psRGXFWAlignChecksMemDesc != IMG_NULL)
+       {
+               DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc);
+               DevmemFwFree(psDevInfo->psRGXFWAlignChecksMemDesc);
+               psDevInfo->psRGXFWAlignChecksMemDesc = IMG_NULL;
+       }
+}
+#endif
+
+
+IMG_VOID RGXSetFirmwareAddress(RGXFWIF_DEV_VIRTADDR    *ppDest,
+                                                          DEVMEM_MEMDESC               *psSrc,
+                                                          IMG_UINT32                   uiExtraOffset,
+                                                          IMG_UINT32                   ui32Flags)
+{
+       PVRSRV_ERROR            eError;
+       IMG_DEV_VIRTADDR        psDevVirtAddr;
+       IMG_UINT64                      ui64Offset;
+       IMG_BOOL            bCachedInMETA;
+       DEVMEM_FLAGS_T      uiDevFlags;
+
+       eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Convert to an address in META memmap */
+       ui64Offset = psDevVirtAddr.uiAddr + uiExtraOffset - RGX_FIRMWARE_HEAP_BASE;
+
+       /* The biggest offset for the Shared region that can be addressed */
+       PVR_ASSERT(ui64Offset < 3*RGXFW_SEGMMU_DMAP_SIZE);
+
+       /* Check in the devmem flags whether this memory is cached/uncached */
+       DevmemGetFlags(psSrc, &uiDevFlags);
+
+       /* Honour the META cache flags */       
+       bCachedInMETA = (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) & uiDevFlags) != 0;
+       
+#if defined(HW_ERN_45914)
+       /* We only cache in META if it's also cached in the SLC */
+       {
+               IMG_BOOL bCachedInSLC = (DevmemDeviceCacheMode(uiDevFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHED);
+
+               bCachedInMETA = bCachedInMETA && bCachedInSLC;
+       }
+#endif
+
+       if (bCachedInMETA)
+       {
+               ppDest->ui32Addr = ((IMG_UINT32) ui64Offset) | RGXFW_BOOTLDR_META_ADDR;
+       }
+       else
+       {
+               ppDest->ui32Addr = ((IMG_UINT32) ui64Offset) | RGXFW_SEGMMU_DMAP_ADDR_START;
+       }
+
+       if (ui32Flags & RFW_FWADDR_NOREF_FLAG)
+       {
+               DevmemReleaseDevVirtAddr(psSrc);
+       }
+}
+
+#if defined(RGX_FEATURE_META_DMA)
+IMG_VOID RGXSetMetaDMAAddress(RGXFWIF_DMA_ADDR         *psDest,
+                                                         DEVMEM_MEMDESC                *psSrcMemDesc,
+                                                         RGXFWIF_DEV_VIRTADDR  *psSrcFWDevVAddr,
+                                                         IMG_UINT32                    uiOffset)
+{
+       PVRSRV_ERROR            eError;
+       IMG_DEV_VIRTADDR        sDevVirtAddr;
+
+       eError = DevmemAcquireDevVirtAddr(psSrcMemDesc, &sDevVirtAddr);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       psDest->psDevVirtAddr.uiAddr = sDevVirtAddr.uiAddr;
+       psDest->psDevVirtAddr.uiAddr += uiOffset;
+       psDest->pbyFWAddr.ui32Addr = psSrcFWDevVAddr->ui32Addr;
+
+       DevmemReleaseDevVirtAddr(psSrcMemDesc);
+}
+#endif
+
+IMG_VOID RGXUnsetFirmwareAddress(DEVMEM_MEMDESC *psSrc)
+{
+       DevmemReleaseDevVirtAddr(psSrc);
+}
+
+struct _RGX_SERVER_COMMON_CONTEXT_ {
+       DEVMEM_MEMDESC *psFWCommonContextMemDesc;
+       PRGXFWIF_FWCOMMONCONTEXT sFWCommonContextFWAddr;
+       DEVMEM_MEMDESC *psFWMemContextMemDesc;
+       DEVMEM_MEMDESC *psFWFrameworkMemDesc;
+       DEVMEM_MEMDESC *psContextStateMemDesc;
+       RGX_CLIENT_CCB *psClientCCB;
+       DEVMEM_MEMDESC *psClientCCBMemDesc;
+       DEVMEM_MEMDESC *psClientCCBCtrlMemDesc;
+       IMG_BOOL bCommonContextMemProvided;
+       IMG_UINT32 ui32ContextID;
+       DLLIST_NODE sListNode;
+       RGXFWIF_CONTEXT_RESET_REASON eLastResetReason;
+};
+
+PVRSRV_ERROR FWCommonContextAllocate(CONNECTION_DATA *psConnection,
+                                                                        PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                        const IMG_CHAR *pszContextName,
+                                                                        DEVMEM_MEMDESC *psAllocatedMemDesc,
+                                                                        IMG_UINT32 ui32AllocatedOffset,
+                                                                        DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                                        DEVMEM_MEMDESC *psContextStateMemDesc,
+                                                                        IMG_UINT32 ui32CCBAllocSize,
+                                                                        IMG_UINT32 ui32Priority,
+                                                                        RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                                        RGX_SERVER_COMMON_CONTEXT **ppsServerCommonContext)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       RGX_SERVER_COMMON_CONTEXT *psServerCommonContext;
+       RGXFWIF_FWCOMMONCONTEXT *psFWCommonContext;
+       IMG_UINT32 ui32FWCommonContextOffset;
+       IMG_UINT8 *pui8Ptr;
+       PVRSRV_ERROR eError;
+
+       /*
+               Allocate all the resources that are required
+       */
+       psServerCommonContext = OSAllocMem(sizeof(*psServerCommonContext));
+       if (psServerCommonContext == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       if (psAllocatedMemDesc)
+       {
+               PDUMPCOMMENT("Using existing MemDesc for Rogue firmware %s context (offset = %d)",
+                                        pszContextName,
+                                        ui32AllocatedOffset);
+               ui32FWCommonContextOffset = ui32AllocatedOffset;
+               psServerCommonContext->psFWCommonContextMemDesc = psAllocatedMemDesc;
+               psServerCommonContext->bCommonContextMemProvided = IMG_TRUE;
+       }
+       else
+       {
+               /* Allocate device memory for the firmware context */
+               PDUMPCOMMENT("Allocate Rogue firmware %s context", pszContextName);
+               eError = DevmemFwAllocate(psDevInfo,
+                                                               sizeof(*psFWCommonContext),
+                                                               RGX_FWCOMCTX_ALLOCFLAGS,
+                                                               "FirmwareContext",
+                                                               &psServerCommonContext->psFWCommonContextMemDesc);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"%s : Failed to allocate firmware %s context (%s)",
+                                                                       __FUNCTION__,
+                                                                       pszContextName,
+                                                                       PVRSRVGetErrorStringKM(eError)));
+                       goto fail_contextalloc;
+               }
+               ui32FWCommonContextOffset = 0;
+               psServerCommonContext->bCommonContextMemProvided = IMG_FALSE;
+       }
+
+       /* Record this context so we can refer to it if the FW needs to tell us it was reset. */
+       psServerCommonContext->eLastResetReason = RGXFWIF_CONTEXT_RESET_REASON_NONE;
+       psServerCommonContext->ui32ContextID    = psDevInfo->ui32CommonCtxtCurrentID++;
+       dllist_add_to_tail(&(psDevInfo->sCommonCtxtListHead), &(psServerCommonContext->sListNode));
+
+       /* Allocate the client CCB */
+       eError = RGXCreateCCB(psDeviceNode,
+                                                 ui32CCBAllocSize,
+                                                 psConnection,
+                                                 pszContextName,
+                                                 psServerCommonContext,
+                                                 &psServerCommonContext->psClientCCB,
+                                                 &psServerCommonContext->psClientCCBMemDesc,
+                                                 &psServerCommonContext->psClientCCBCtrlMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: failed to create CCB for %s context(%s)",
+                                                               __FUNCTION__,
+                                                               pszContextName,
+                                                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_allocateccb;
+       }
+
+       /*
+               Temporarily map the firmware context to the kernel and init it
+       */
+       eError = DevmemAcquireCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc,
+                                      (IMG_VOID **)&pui8Ptr);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Failed to map firmware %s context (%s)to CPU",
+                                                               __FUNCTION__,
+                                                               pszContextName,
+                                                               PVRSRVGetErrorStringKM(eError)));
+               goto fail_cpuvirtacquire;
+       }
+
+       psFWCommonContext = (RGXFWIF_FWCOMMONCONTEXT *) (pui8Ptr + ui32FWCommonContextOffset);
+
+       /* Set the firmware CCB device addresses in the firmware common context */
+       RGXSetFirmwareAddress(&psFWCommonContext->psCCB,
+                                                 psServerCommonContext->psClientCCBMemDesc,
+                                                 0, RFW_FWADDR_FLAG_NONE);
+       RGXSetFirmwareAddress(&psFWCommonContext->psCCBCtl,
+                                                 psServerCommonContext->psClientCCBCtrlMemDesc,
+                                                 0, RFW_FWADDR_FLAG_NONE);
+
+       /* Set the memory context device address */
+       psServerCommonContext->psFWMemContextMemDesc = psFWMemContextMemDesc;
+       RGXSetFirmwareAddress(&psFWCommonContext->psFWMemContext,
+                                                 psFWMemContextMemDesc,
+                                                 0, RFW_FWADDR_FLAG_NONE);
+
+       /* Set the framework register updates address */
+       psServerCommonContext->psFWFrameworkMemDesc = psInfo->psFWFrameworkMemDesc;
+       RGXSetFirmwareAddress(&psFWCommonContext->psRFCmd,
+                                                 psInfo->psFWFrameworkMemDesc,
+                                                 0, RFW_FWADDR_FLAG_NONE);
+
+       psFWCommonContext->ui32Priority = ui32Priority;
+       psFWCommonContext->ui32PrioritySeqNum = 0;
+
+       if(psInfo->psMCUFenceAddr != IMG_NULL)
+       {
+               psFWCommonContext->ui64MCUFenceAddr = psInfo->psMCUFenceAddr->uiAddr;
+       }
+
+       /* Store a references to Server Common Context and PID for notifications back from the FW. */
+       psFWCommonContext->ui32ServerCommonContextID = psServerCommonContext->ui32ContextID;
+       psFWCommonContext->ui32PID                   = OSGetCurrentProcessID();
+
+       /* Set the firmware GPU context state buffer */
+       psServerCommonContext->psContextStateMemDesc = psContextStateMemDesc;
+       if (psContextStateMemDesc)
+       {
+               RGXSetFirmwareAddress(&psFWCommonContext->psContextState,
+                                                         psContextStateMemDesc,
+                                                         0,
+                                                         RFW_FWADDR_FLAG_NONE);
+       }
+
+       /*
+        * Dump the created context
+        */
+       PDUMPCOMMENT("Dump %s context", pszContextName);
+       DevmemPDumpLoadMem(psServerCommonContext->psFWCommonContextMemDesc,
+                                          ui32FWCommonContextOffset,
+                                          sizeof(*psFWCommonContext),
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       /* We've finished the setup so release the CPU mapping */
+       DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc);
+
+       /* Map this allocation into the FW */
+       RGXSetFirmwareAddress(&psServerCommonContext->sFWCommonContextFWAddr,
+                                                 psServerCommonContext->psFWCommonContextMemDesc,
+                                                 ui32FWCommonContextOffset,
+                                                 RFW_FWADDR_FLAG_NONE);
+
+#if defined(LINUX)
+       trace_rogue_create_fw_context(OSGetCurrentProcessName(),
+                                                                 pszContextName,
+                                                                 psServerCommonContext->sFWCommonContextFWAddr.ui32Addr);
+#endif
+
+       *ppsServerCommonContext = psServerCommonContext;
+       return PVRSRV_OK;
+
+fail_allocateccb:
+       DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc);
+fail_cpuvirtacquire:
+       RGXUnsetFirmwareAddress(psServerCommonContext->psFWCommonContextMemDesc);
+       if (!psServerCommonContext->bCommonContextMemProvided)
+       {
+               DevmemFwFree(psServerCommonContext->psFWCommonContextMemDesc);
+       }
+fail_contextalloc:
+       OSFreeMem(psServerCommonContext);
+fail_alloc:
+       return eError;
+}
+
+IMG_VOID FWCommonContextFree(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
+{
+       /*
+               Unmap the context itself and then all it's resources
+       */
+
+       /* Unmap the FW common context */
+       RGXUnsetFirmwareAddress(psServerCommonContext->psFWCommonContextMemDesc);
+       /* Umap context state buffer (if there was one) */
+       if (psServerCommonContext->psContextStateMemDesc)
+       {
+               RGXUnsetFirmwareAddress(psServerCommonContext->psContextStateMemDesc);
+       }
+       /* Unmap the framework buffer */
+       RGXUnsetFirmwareAddress(psServerCommonContext->psFWFrameworkMemDesc);
+       /* Unmap client CCB and CCB control */
+       RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBCtrlMemDesc);
+       RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBMemDesc);
+       /* Unmap the memory context */
+       RGXUnsetFirmwareAddress(psServerCommonContext->psFWMemContextMemDesc);
+
+       /* Destroy the client CCB */
+       RGXDestroyCCB(psServerCommonContext->psClientCCB);
+       
+       /* Remove the context from the list of all contexts. */
+       dllist_remove_node(&psServerCommonContext->sListNode);
+
+       /* Free the FW common context (if there was one) */
+       if (!psServerCommonContext->bCommonContextMemProvided)
+       {
+               DevmemFwFree(psServerCommonContext->psFWCommonContextMemDesc);
+       }
+       /* Free the hosts representation of the common context */
+       OSFreeMem(psServerCommonContext);
+}
+
+PRGXFWIF_FWCOMMONCONTEXT FWCommonContextGetFWAddress(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
+{
+       return psServerCommonContext->sFWCommonContextFWAddr;
+}
+
+RGX_CLIENT_CCB *FWCommonContextGetClientCCB(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
+{
+       return psServerCommonContext->psClientCCB;
+}
+
+RGXFWIF_CONTEXT_RESET_REASON FWCommonContextGetLastResetReason(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
+{
+       RGXFWIF_CONTEXT_RESET_REASON  eLastResetReason;
+       
+       PVR_ASSERT(psServerCommonContext != IMG_NULL);
+       
+       /* Take the most recent reason and reset for next time... */
+       eLastResetReason = psServerCommonContext->eLastResetReason;
+       psServerCommonContext->eLastResetReason = RGXFWIF_CONTEXT_RESET_REASON_NONE;
+
+       return eLastResetReason;
+}
+
+/*!
+*******************************************************************************
+ @Function             RGXFreeKernelCCB
+ @Description  Free a kernel CCB
+ @Input                        psDevInfo
+ @Input                        eKCCBType
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static IMG_VOID RGXFreeKernelCCB(PVRSRV_RGXDEV_INFO    *psDevInfo,
+                                                                RGXFWIF_DM                             eKCCBType)
+{
+       if (psDevInfo->apsKernelCCBMemDesc[eKCCBType] != IMG_NULL)
+       {
+               if (psDevInfo->apsKernelCCB[eKCCBType] != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->apsKernelCCBMemDesc[eKCCBType]);
+                       psDevInfo->apsKernelCCB[eKCCBType] = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->apsKernelCCBMemDesc[eKCCBType]);
+               psDevInfo->apsKernelCCBMemDesc[eKCCBType] = IMG_NULL;
+       }
+       if (psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType] != IMG_NULL)
+       {
+               if (psDevInfo->apsKernelCCBCtl[eKCCBType] != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType]);
+                       psDevInfo->apsKernelCCBCtl[eKCCBType] = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType]);
+               psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType] = IMG_NULL;
+       }
+}
+
+/*!
+*******************************************************************************
+ @Function             RGXSetupKernelCCB
+ @Description  Allocate and initialise a kernel CCB
+ @Input                        psDevInfo
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR RGXSetupKernelCCB(PVRSRV_RGXDEV_INFO       *psDevInfo, 
+                                                                         RGXFWIF_INIT                  *psRGXFWInit,
+                                                                         RGXFWIF_DM                    eKCCBType,
+                                                                         IMG_UINT32                    ui32NumCmdsLog2,
+                                                                         IMG_UINT32                    ui32CmdSize)
+{
+       PVRSRV_ERROR            eError;
+       RGXFWIF_CCB_CTL         *psKCCBCtl;
+       DEVMEM_FLAGS_T          uiCCBCtlMemAllocFlags, uiCCBMemAllocFlags;
+       IMG_UINT32                      ui32kCCBSize = (1U << ui32NumCmdsLog2);
+
+
+       /*
+        * FIXME: the write offset need not be writeable by the firmware, indeed may
+        * not even be needed for reading. Consider moving it to its own data
+        * structure.
+        */
+       uiCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                                       PVRSRV_MEMALLOCFLAG_UNCACHED | 
+                                                        PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /* Allocation flags for Kernel CCB */
+       uiCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                                PVRSRV_MEMALLOCFLAG_UNCACHED | 
+                                                PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /*
+               Allocate memory for the kernel CCB control.
+       */
+       PDUMPCOMMENT("Allocate memory for kernel CCB control %u", eKCCBType);
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_CCB_CTL),
+                                                       uiCCBCtlMemAllocFlags,
+                                                       "KernelCCBControl",
+                            &psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType]);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to allocate kernel CCB ctl %u (%u)",
+                               eKCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Allocate memory for the kernel CCB.
+               (this will reference further command data in non-shared CCBs)
+       */
+       PDUMPCOMMENT("Allocate memory for kernel CCB %u", eKCCBType);
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       ui32kCCBSize * ui32CmdSize,
+                                                       uiCCBMemAllocFlags,
+                                                       "KernelCCB",
+                            &psDevInfo->apsKernelCCBMemDesc[eKCCBType]);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to allocate kernel CCB %u (%u)",
+                               eKCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Map the kernel CCB control to the kernel.
+       */
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                      (IMG_VOID **)&psDevInfo->apsKernelCCBCtl[eKCCBType]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to acquire cpu kernel CCB Ctl %u (%u)",
+                               eKCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Map the kernel CCB to the kernel.
+       */
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->apsKernelCCBMemDesc[eKCCBType],
+                                      (IMG_VOID **)&psDevInfo->apsKernelCCB[eKCCBType]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to acquire cpu kernel CCB %u (%u)",
+                               eKCCBType, eError));
+               goto fail;
+       }
+
+       /*
+        * Initialise the kernel CCB control.
+        */
+       psKCCBCtl = psDevInfo->apsKernelCCBCtl[eKCCBType];
+       psKCCBCtl->ui32WriteOffset = 0;
+       psKCCBCtl->ui32ReadOffset = 0;
+       psKCCBCtl->ui32WrapMask = ui32kCCBSize - 1;
+       psKCCBCtl->ui32CmdSize = ui32CmdSize;
+
+       /*
+        * Set-up RGXFWIfCtl pointers to access the kCCBs
+        */
+       RGXSetFirmwareAddress(&psRGXFWInit->psKernelCCBCtl[eKCCBType],
+                                                 psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psKernelCCB[eKCCBType],
+                                                 psDevInfo->apsKernelCCBMemDesc[eKCCBType],
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       psRGXFWInit->eDM[eKCCBType] = eKCCBType;
+
+       /*
+        * Pdump the kernel CCB control.
+        */
+       PDUMPCOMMENT("Initialise kernel CCB ctl %d", eKCCBType);
+       DevmemPDumpLoadMem(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                          0,
+                                          sizeof(RGXFWIF_CCB_CTL),
+                                          0);
+
+       return PVRSRV_OK;
+
+fail:
+       RGXFreeKernelCCB(psDevInfo, eKCCBType);
+
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function             RGXFreeFirmwareCCB
+ @Description  Free a firmware CCB
+ @Input                        psDevInfo
+ @Input                        eFWCCBType
+
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static IMG_VOID RGXFreeFirmwareCCB(PVRSRV_RGXDEV_INFO  *psDevInfo,
+                                                                RGXFWIF_DM                             eFWCCBType)
+{
+       if (psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType] != IMG_NULL)
+       {
+               if (psDevInfo->apsFirmwareCCB[eFWCCBType] != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType]);
+                       psDevInfo->apsFirmwareCCB[eFWCCBType] = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType]);
+               psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType] = IMG_NULL;
+       }
+       if (psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType] != IMG_NULL)
+       {
+               if (psDevInfo->apsFirmwareCCBCtl[eFWCCBType] != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType]);
+                       psDevInfo->apsFirmwareCCBCtl[eFWCCBType] = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType]);
+               psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType] = IMG_NULL;
+       }
+}
+
+/*!
+*******************************************************************************
+ @Function             RGXSetupFirmwareCCB
+ @Description  Allocate and initialise a Firmware CCB
+ @Input                        psDevInfo
+
+ @Return               PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR RGXSetupFirmwareCCB(PVRSRV_RGXDEV_INFO     *psDevInfo,
+                                                                         RGXFWIF_INIT                  *psRGXFWInit,
+                                                                         RGXFWIF_DM                    eFWCCBType,
+                                                                         IMG_UINT32                    ui32NumCmdsLog2,
+                                                                         IMG_UINT32                    ui32CmdSize)
+{
+       PVRSRV_ERROR            eError;
+       RGXFWIF_CCB_CTL         *psFWCCBCtl;
+       DEVMEM_FLAGS_T          uiCCBCtlMemAllocFlags, uiCCBMemAllocFlags;
+       IMG_UINT32                      ui32FWCCBSize = (1U << ui32NumCmdsLog2);
+
+       /*
+        * FIXME: the write offset need not be writeable by the host, indeed may
+        * not even be needed for reading. Consider moving it to its own data
+        * structure.
+        */
+       uiCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                                       PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                        PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /* Allocation flags for Firmware CCB */
+       uiCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                                PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /*
+               Allocate memory for the Firmware CCB control.
+       */
+       PDUMPCOMMENT("Allocate memory for firmware CCB control %u", eFWCCBType);
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_CCB_CTL),
+                                                       uiCCBCtlMemAllocFlags,
+                                                       "FirmwareCCBControl",
+                            &psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType]);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to allocate Firmware CCB ctl %u (%u)",
+                               eFWCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Allocate memory for the Firmware CCB.
+               (this will reference further command data in non-shared CCBs)
+       */
+       PDUMPCOMMENT("Allocate memory for firmware CCB %u", eFWCCBType);
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       ui32FWCCBSize * ui32CmdSize,
+                                                       uiCCBMemAllocFlags,
+                                                       "FirmwareCCB",
+                            &psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType]);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to allocate Firmware CCB %u (%u)",
+                               eFWCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Map the Firmware CCB control to the kernel.
+       */
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType],
+                                      (IMG_VOID **)&psDevInfo->apsFirmwareCCBCtl[eFWCCBType]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to acquire cpu firmware CCB Ctl %u (%u)",
+                               eFWCCBType, eError));
+               goto fail;
+       }
+
+       /*
+               Map the firmware CCB to the kernel.
+       */
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType],
+                                      (IMG_VOID **)&psDevInfo->apsFirmwareCCB[eFWCCBType]);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to acquire cpu firmware CCB %u (%u)",
+                               eFWCCBType, eError));
+               goto fail;
+       }
+
+       /*
+        * Initialise the firmware CCB control.
+        */
+       psFWCCBCtl = psDevInfo->apsFirmwareCCBCtl[eFWCCBType];
+       psFWCCBCtl->ui32WriteOffset = 0;
+       psFWCCBCtl->ui32ReadOffset = 0;
+       psFWCCBCtl->ui32WrapMask = ui32FWCCBSize - 1;
+       psFWCCBCtl->ui32CmdSize = ui32CmdSize;
+
+       /*
+        * Set-up RGXFWIfCtl pointers to access the kCCBs
+        */
+       RGXSetFirmwareAddress(&psRGXFWInit->psFirmwareCCBCtl[eFWCCBType],
+                                                 psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType],
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psFirmwareCCB[eFWCCBType],
+                                                 psDevInfo->apsFirmwareCCBMemDesc[eFWCCBType],
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       psRGXFWInit->eDM[eFWCCBType] = eFWCCBType;
+
+       /*
+        * Pdump the kernel CCB control.
+        */
+       PDUMPCOMMENT("Initialise firmware CCB ctl %d", eFWCCBType);
+       DevmemPDumpLoadMem(psDevInfo->apsFirmwareCCBCtlMemDesc[eFWCCBType],
+                                          0,
+                                          sizeof(RGXFWIF_CCB_CTL),
+                                          0);
+
+       return PVRSRV_OK;
+
+fail:
+       RGXFreeFirmwareCCB(psDevInfo, eFWCCBType);
+
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static IMG_VOID RGXSetupFaultReadRegisterRollback(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PMR *psPMR;
+       
+       if (psDevInfo->psRGXFaultAddressMemDesc)
+       {
+               if (DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc,(IMG_VOID **)&psPMR) == PVRSRV_OK)
+               {
+                       PMRUnlockSysPhysAddresses(psPMR);
+               }
+               DevmemFwFree(psDevInfo->psRGXFaultAddressMemDesc);
+               psDevInfo->psRGXFaultAddressMemDesc = IMG_NULL;
+       }
+}
+
+static PVRSRV_ERROR RGXSetupFaultReadRegister(PVRSRV_DEVICE_NODE       *psDeviceNode, RGXFWIF_INIT *psRGXFWInit)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       IMG_UINT32                      *pui32MemoryVirtAddr;
+       IMG_UINT32                      i;
+       IMG_SIZE_T                      ui32PageSize;
+       DEVMEM_FLAGS_T          uiMemAllocFlags;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       PMR                                     *psPMR;
+
+       ui32PageSize = OSGetPageSize();
+
+       /* Allocate page of memory to use for page faults on non-blocking memory transactions */
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED;
+       
+       psDevInfo->psRGXFaultAddressMemDesc = IMG_NULL;
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               ui32PageSize,
+                                                                               uiMemAllocFlags,
+                                                                               "FaultAddress",
+                                                                               &psDevInfo->psRGXFaultAddressMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to allocate mem for fault address (%u)",
+                               eError));
+               goto failFaultAddressDescAlloc;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc,
+                                                                         (IMG_VOID **)&pui32MemoryVirtAddr);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire mem for fault adress (%u)",
+                               eError));
+               goto failFaultAddressDescAqCpuVirt;
+       }
+
+       for (i = 0; i < ui32PageSize/sizeof(IMG_UINT32); i++)
+       {
+               *(pui32MemoryVirtAddr + i) = 0xDEADBEEF;
+       }
+
+       eError = DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc,(IMG_VOID **)&psPMR);
+               
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error getting PMR for fault adress (%u)",
+                               eError));
+               
+               goto failFaultAddressDescGetPMR;
+       }
+       else
+       {
+               IMG_BOOL bValid;
+               IMG_UINT32 ui32Log2PageSize = OSGetPageShift();
+               
+               eError = PMRLockSysPhysAddresses(psPMR,ui32Log2PageSize);
+                       
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error locking physical address for fault address MemDesc (%u)",
+                                       eError));
+                       
+                       goto failFaultAddressDescLockPhys;
+               }
+                       
+               eError = PMR_DevPhysAddr(psPMR,ui32Log2PageSize,1,0,&(psRGXFWInit->sFaultPhysAddr),&bValid);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error getting physical address for fault address MemDesc (%u)",
+                                       eError));
+                       
+                       goto failFaultAddressDescGetPhys;
+               }
+
+               if (!bValid)
+               {
+                       psRGXFWInit->sFaultPhysAddr.uiAddr = 0;
+                       PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed getting physical address for fault address MemDesc - invalid page (0x%llX)",
+                                       psRGXFWInit->sFaultPhysAddr.uiAddr));
+
+                       goto failFaultAddressDescGetPhys;
+               }
+       }
+
+       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc);
+       
+       return PVRSRV_OK;
+
+failFaultAddressDescGetPhys:
+       PMRUnlockSysPhysAddresses(psPMR);
+
+failFaultAddressDescLockPhys:
+
+failFaultAddressDescGetPMR:
+       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc);
+
+failFaultAddressDescAqCpuVirt:
+       DevmemFwFree(psDevInfo->psRGXFaultAddressMemDesc);
+       psDevInfo->psRGXFaultAddressMemDesc = IMG_NULL;
+
+failFaultAddressDescAlloc:
+
+       return eError;
+}
+
+static PVRSRV_ERROR RGXHwBrn37200(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVRSRV_ERROR                    eError = PVRSRV_OK;
+
+#if defined(FIX_HW_BRN_37200)
+       struct _DEVMEM_HEAP_    *psBRNHeap;
+       DEVMEM_FLAGS_T                  uiFlags;
+       IMG_DEV_VIRTADDR                sTmpDevVAddr;
+       IMG_SIZE_T                              uiPageSize;
+
+       uiPageSize = OSGetPageSize();
+       
+       uiFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                               PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | 
+                               PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                               PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx,
+                                                         "HWBRN37200", /* FIXME: We need to create an IDENT macro for this string.
+                                                                        Make sure the IDENT macro is not accessible to userland */
+                                                         &psBRNHeap);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: HWBRN37200 Failed DevmemFindHeapByName (%u)", eError));
+               goto failFWHWBRN37200FindHeapByName;
+       }
+
+       psDevInfo->psRGXFWHWBRN37200MemDesc = IMG_NULL;
+       eError = DevmemAllocate(psBRNHeap,
+                                               uiPageSize,
+                                               ROGUE_CACHE_LINE_SIZE,
+                                               uiFlags,
+                                               "HWBRN37200",
+                                               &psDevInfo->psRGXFWHWBRN37200MemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: Failed to allocate %u bytes for HWBRN37200 (%u)",
+                               (IMG_UINT32)uiPageSize,
+                               eError));
+               goto failFWHWBRN37200MemDescAlloc;
+       }
+               
+       /*
+               We need to map it so the heap for this allocation
+               is set
+       */
+       eError = DevmemMapToDevice(psDevInfo->psRGXFWHWBRN37200MemDesc,
+                                                  psBRNHeap,
+                                                  &sTmpDevVAddr);
+               
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: Failed to allocate %u bytes for HWBRN37200 (%u)",
+                               (IMG_UINT32)uiPageSize,
+                               eError));
+               goto failFWHWBRN37200DevmemMapToDevice;
+       }
+
+       return PVRSRV_OK;
+
+failFWHWBRN37200DevmemMapToDevice:
+
+failFWHWBRN37200MemDescAlloc:
+       DevmemFwFree(psDevInfo->psRGXFWHWBRN37200MemDesc);
+       psDevInfo->psRGXFWHWBRN37200MemDesc = IMG_NULL;
+
+failFWHWBRN37200FindHeapByName:
+#endif
+
+       return eError;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXSetupFirmware
+
+ @Description
+
+ Setups all the firmware related data
+
+ @Input psDevInfo
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RGXSetupFirmware(PVRSRV_DEVICE_NODE       *psDeviceNode, 
+                                                            IMG_BOOL                   bEnableSignatureChecks,
+                                                            IMG_UINT32                 ui32SignatureChecksBufSize,
+                                                            IMG_UINT32                 ui32HWPerfFWBufSizeKB,
+                                                            IMG_UINT64                 ui64HWPerfFilter,
+                                                            IMG_UINT32                 ui32RGXFWAlignChecksSize,
+                                                            IMG_UINT32                 *pui32RGXFWAlignChecks,
+                                                            IMG_UINT32                 ui32ConfigFlags,
+                                                            IMG_UINT32                 ui32LogType,
+                                                            IMG_UINT32            ui32NumTilingCfgs,
+                                                            IMG_UINT32            *pui32BIFTilingXStrides,
+                                                            IMG_UINT32                 ui32FilterFlags,
+                                                            IMG_UINT32                 ui32JonesDisableMask,
+                                                            IMG_UINT32                 ui32HWRDebugDumpLimit,
+                                                                IMG_UINT32                     ui32HWPerfCountersDataSize,
+                                                            RGXFWIF_DEV_VIRTADDR       *psRGXFWInitFWAddr,
+                                                            RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf)
+
+{
+       PVRSRV_ERROR            eError;
+       DEVMEM_FLAGS_T          uiMemAllocFlags;
+       RGXFWIF_INIT            *psRGXFWInit;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       IMG_UINT32                      dm;
+#if defined(RGX_FEATURE_META_DMA)
+       RGXFWIF_DEV_VIRTADDR sRGXTmpCorememDataStoreFWAddr;
+#endif
+
+       /* Fw init data */
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+                                               /* FIXME: Change to Cached */
+
+       PDUMPCOMMENT("Allocate RGXFWIF_INIT structure");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_INIT),
+                                                       uiMemAllocFlags,
+                                                       "FirmwareInitStructure",
+                                                       &psDevInfo->psRGXFWIfInitMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw if ctl (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_INIT),
+                               eError));
+               goto fail;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                         (IMG_VOID **)&psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel fw if ctl (%u)",
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(psRGXFWInitFWAddr,
+                                               psDevInfo->psRGXFWIfInitMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+
+       /* FW Trace buffer */
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate rgxfw trace structure");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_TRACEBUF),
+                                                       uiMemAllocFlags,
+                                                       "FirmwareTraceStructure",
+                                                       &psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw trace (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_TRACEBUF),
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psTraceBufCtl,
+                                               psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
+                                                                         (IMG_VOID **)&psDevInfo->psRGXFWIfTraceBuf);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel tracebuf ctl (%u)",
+                               eError));
+               goto fail;
+       }
+
+       /* Determine the size of the HWPerf FW buffer */
+       if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MAX>>10))
+       {
+               /* Size specified as a AppHint but it is too big */
+               PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: HWPerfFWBufSizeInKB value (%u) too big, using maximum (%u)",
+                               ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MAX>>10));
+               psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_MAX;
+               
+       }
+       else if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MIN>>10))
+       {
+               /* Size specified as in AppHint HWPerfFWBufSizeInKB */
+               PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: Using HWPerf FW buffer size of %u KB",
+                               ui32HWPerfFWBufSizeKB));
+               psDevInfo->ui32RGXFWIfHWPerfBufSize = ui32HWPerfFWBufSizeKB<<10;
+       }
+       else if (ui32HWPerfFWBufSizeKB > 0)
+       {
+               /* Size specified as a AppHint but it is too small */
+               PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: HWPerfFWBufSizeInKB value (%u) too small, using minimum (%u)",
+                               ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MIN>>10));
+               psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_MIN;
+       }
+       else
+       {
+               /* 0 size implies AppHint not set or is set to zero,
+                * use default size from driver constant. */
+               psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_DEFAULT;
+       }
+
+       /* Allocate HWPerf FW L1 buffer */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         psDevInfo->ui32RGXFWIfHWPerfBufSize+RGXFW_HWPERF_L1_PADDING_DEFAULT,
+                                                         uiMemAllocFlags,
+                                                         "FirmwareHWPerfBuffer",
+                                                         &psDevInfo->psRGXFWIfHWPerfBufMemDesc);
+       
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSetupFirmware: Failed to allocate kernel fw hwperf buffer (%u)",
+                                eError));
+               goto fail;
+       }
+
+       /* Meta cached flag removed from this allocation as it was found
+        * FW performance was better without it. */
+       RGXSetFirmwareAddress(&psRGXFWInit->psHWPerfInfoCtl,
+                                                 psDevInfo->psRGXFWIfHWPerfBufMemDesc,
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfHWPerfBufMemDesc,
+                                                                         (IMG_VOID**)&psDevInfo->psRGXFWIfHWPerfBuf);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSetupFirmware: Failed to acquire kernel hwperf buffer (%u)",
+                                eError));
+               goto fail;
+       }
+
+
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | 
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       /* Allocate buffer to store FW data */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         RGX_META_COREMEM_DATA_SIZE,
+                                                         uiMemAllocFlags,
+                                                         "FirmwareCorememDataStore",
+                                                         &psDevInfo->psRGXFWIfCorememDataStoreMemDesc);
+       
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSetupFirmware: Failed to allocate coremem data store (%u)",
+                                eError));
+               goto fail;
+       }
+
+#if defined(RGX_FEATURE_META_DMA)
+       RGXSetFirmwareAddress(&sRGXTmpCorememDataStoreFWAddr,
+                                                 psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+
+       RGXSetMetaDMAAddress(&psRGXFWInit->sCorememDataStore,
+                                                psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
+                                                &sRGXTmpCorememDataStoreFWAddr,
+                                                0);
+#else
+       RGXSetFirmwareAddress(&psRGXFWInit->sCorememDataStore.pbyFWAddr,
+                                                 psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
+                                                 0, RFW_FWADDR_NOREF_FLAG);
+#endif
+
+       /* init HW frame info */
+       PDUMPCOMMENT("Allocate rgxfw HW info buffer");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_HWRINFOBUF),
+                                                       uiMemAllocFlags,
+                                                       "FirmwareHWInfoBuffer",
+                                                       &psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for HW info (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_HWRINFOBUF),
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psRGXFWIfHWRInfoBufCtl,
+                                               psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc,
+                                                                         (IMG_VOID **)&psDevInfo->psRGXFWIfHWRInfoBuf);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel tracebuf ctl (%u)",
+                               eError));
+               goto fail;
+       }
+       OSMemSet(psDevInfo->psRGXFWIfHWRInfoBuf, 0, sizeof(RGXFWIF_HWRINFOBUF));
+
+       /* init HWPERF data */
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfRIdx = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfWIdx = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfWrapCount = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfSize = psDevInfo->ui32RGXFWIfHWPerfBufSize;
+       psRGXFWInit->ui64HWPerfFilter = ui64HWPerfFilter;
+       psRGXFWInit->bDisableFilterHWPerfCustomCounter = (ui32ConfigFlags & RGXFWIF_INICFG_HWP_DISABLE_FILTER) ? IMG_TRUE : IMG_FALSE;
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfUt = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfDropCount = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32FirstDropOrdinal = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32LastDropOrdinal = 0;
+       psDevInfo->psRGXFWIfTraceBuf->ui32PowMonEnergy = 0;
+
+       
+       /* Initialise the HWPerf module in the Rogue device driver.
+        * May allocate host buffer if HWPerf enabled at driver load time.
+        */
+       eError = RGXHWPerfInit(psDeviceNode, (ui32ConfigFlags & RGXFWIF_INICFG_HWPERF_EN));
+       PVR_LOGG_IF_ERROR(eError, "RGXHWPerfInit", fail);
+
+       /* Set initial log type */
+       if (ui32LogType & ~RGXFWIF_LOG_TYPE_MASK)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Invalid initial log type (0x%X)",ui32LogType));
+               goto fail;
+       }
+       psDevInfo->psRGXFWIfTraceBuf->ui32LogType = ui32LogType;
+
+       /* Allocate shared buffer for GPU utilisation */
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate shared buffer for GPU utilisation");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_GPU_UTIL_FWCB),
+                                                       uiMemAllocFlags,
+                                                       "FirmwareGPUUtilisationBuffer",
+                                                       &psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for GPU utilisation buffer ctl (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_GPU_UTIL_FWCB),
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psGpuUtilFWCbCtl,
+                                               psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc,
+                                                                         (IMG_VOID **)&psDevInfo->psRGXFWIfGpuUtilFWCb);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel GPU utilization FW CB ctl (%u)",
+                               eError));
+               goto fail;
+       }
+
+       /* Initialise GPU utilisation buffer */
+       psDevInfo->psRGXFWIfGpuUtilFWCb->ui64LastWord =
+           RGXFWIF_GPU_UTIL_MAKE_WORD(OSClockns64(),RGXFWIF_GPU_UTIL_STATE_IDLE);
+
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate rgxfw FW runtime configuration (FW)");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_RUNTIME_CFG),
+                                                       uiMemAllocFlags,
+                                                       "FirmwareFWRuntimeCfg",
+                                                       &psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for FW runtime configuration (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_RUNTIME_CFG),
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psRuntimeCfg,
+                                               psDevInfo->psRGXFWIfRuntimeCfgMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfRuntimeCfgMemDesc,
+                                                                       (IMG_VOID **)&psDevInfo->psRGXFWIfRuntimeCfg);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel FW runtime configuration (%u)",
+                               eError));
+               goto fail;
+       }
+
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PDUMPCOMMENT("Allocate rgxfw register configuration structure");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_REG_CFG),
+                                                       uiMemAllocFlags,
+                                                       "Firmware register configuration structure",
+                                                       &psDevInfo->psRGXFWIfRegCfgMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw register configurations (%u)",
+                               (IMG_UINT32)sizeof(RGXFWIF_REG_CFG),
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psRegCfg,
+                                               psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                               0, RFW_FWADDR_NOREF_FLAG);
+#endif
+
+       uiMemAllocFlags =       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate rgxfw hwperfctl structure");
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                       ui32HWPerfCountersDataSize,
+                                                       uiMemAllocFlags,
+                                                       "Firmware hwperf control structure",
+                                                       &psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXInitHWPerfCounters: Failed to allocate %u bytes for fw hwperf control (%u)",
+                               ui32HWPerfCountersDataSize,
+                               eError));
+               goto fail;
+       }
+
+       eError = DevmemExport(psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
+                             &psDevInfo->sRGXFWHWPerfCountersExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to export fw hwperf ctl (%u)",
+                               eError));
+               goto fail;
+       }
+
+       RGXSetFirmwareAddress(&psRGXFWInit->psHWPerfCtl,
+                                               psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
+                                               0, 0);
+       
+       /* Allocate a sync for power management */
+       eError = SyncPrimContextCreate(IMG_NULL,
+                                                                       psDevInfo->psDeviceNode,
+                                                                       &psDevInfo->hSyncPrimContext);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate sync primitive context with error (%u)", eError));
+               goto fail;
+       }
+
+       eError = SyncPrimAlloc(psDevInfo->hSyncPrimContext, &psDevInfo->psPowSyncPrim, "fw power ack");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate sync primitive with error (%u)", eError));
+               goto fail;
+       }
+
+       psRGXFWInit->uiPowerSync = SyncPrimGetFirmwareAddr(psDevInfo->psPowSyncPrim);
+
+       /* Required info by FW to calculate the ActivePM idle timer latency */
+       {
+               RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
+               RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg;
+
+               psRGXFWInit->ui32InitialCoreClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
+               psRGXFWInit->ui32ActivePMLatencyms = psRGXData->psRGXTimingInfo->ui32ActivePMLatencyms;
+
+               /* Initialise variable runtime configuration to the system defaults */
+               psRuntimeCfg->ui32CoreClockSpeed = psRGXFWInit->ui32InitialCoreClockSpeed;
+               psRuntimeCfg->ui32ActivePMLatencyms = psRGXFWInit->ui32ActivePMLatencyms;
+               psRuntimeCfg->bActivePMLatencyPersistant = IMG_TRUE;
+       }
+
+       /* Setup Fault read register */
+       eError = RGXSetupFaultReadRegister(psDeviceNode, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup fault read register"));
+               goto fail;
+       }
+
+       /* Apply FIX_HW_BRN_37200 */
+       eError = RGXHwBrn37200(psDevInfo);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to apply HWBRN37200"));
+               goto fail;
+       }
+
+       /*
+        * Set up kernel TA CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_TA, RGXFWIF_KCCB_TA_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel TA CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up firmware TA CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_TA, RGXFWIF_FWCCB_TA_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware TA CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up kernel 3D CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_3D, RGXFWIF_KCCB_3D_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel 3D CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up Firmware 3D CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_3D, RGXFWIF_FWCCB_3D_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware 3D CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up kernel 2D CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_2D, RGXFWIF_KCCB_2D_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel 2D CCB"));
+               goto fail;
+       }
+       /*
+        * Set up Firmware 2D CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_2D, RGXFWIF_FWCCB_2D_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware 2D CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up kernel compute CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_CDM, RGXFWIF_KCCB_CDM_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel Compute CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up Firmware Compute CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_CDM, RGXFWIF_FWCCB_CDM_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware Compute CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up kernel general purpose CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_GP, RGXFWIF_KCCB_GP_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel General Purpose CCB"));
+               goto fail;
+       }
+       
+       /*
+        * Set up Firmware general purpose CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_GP, RGXFWIF_FWCCB_GP_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware General Purpose CCB"));
+               goto fail;
+       }
+#if defined(RGX_FEATURE_RAY_TRACING)   
+       /*
+        * Set up kernel SHG CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_SHG, RGXFWIF_KCCB_SHG_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel SHG CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up Firmware SHG CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_SHG, RGXFWIF_FWCCB_SHG_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware SHG CCB"));
+               goto fail;
+       }
+       
+       /*
+        * Set up kernel RTU CCB.
+        */
+       eError = RGXSetupKernelCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_RTU, RGXFWIF_KCCB_RTU_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_KCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate kernel RTU CCB"));
+               goto fail;
+       }
+
+       /*
+        * Set up Firmware RTU CCB.
+        */
+       eError = RGXSetupFirmwareCCB(psDevInfo,
+                                                          psRGXFWInit,
+                                                          RGXFWIF_DM_RTU, RGXFWIF_FWCCB_RTU_NUMCMDS_LOG2,
+                                                          sizeof(RGXFWIF_FWCCB_CMD));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware SHG CCB"));
+               goto fail;
+       }
+#endif
+
+       /* Setup Signature and Checksum Buffers for TA and 3D */
+       eError = RGXFWSetupSignatureChecks(psDevInfo,
+                                          &psDevInfo->psRGXFWSigTAChecksMemDesc, 
+                                          ui32SignatureChecksBufSize,
+                                          &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_TA],
+                                          "TA");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup TA signature checks"));
+               goto fail;
+       }
+       psDevInfo->ui32SigTAChecksSize = ui32SignatureChecksBufSize;
+
+       eError = RGXFWSetupSignatureChecks(psDevInfo,
+                                          &psDevInfo->psRGXFWSig3DChecksMemDesc, 
+                                          ui32SignatureChecksBufSize,
+                                          &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_3D],
+                                          "3D");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup 3D signature checks"));
+               goto fail;
+       }
+       psDevInfo->ui32Sig3DChecksSize = ui32SignatureChecksBufSize;
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       eError = RGXFWSetupSignatureChecks(psDevInfo,
+                                          &psDevInfo->psRGXFWSigRTChecksMemDesc, 
+                                          ui32SignatureChecksBufSize,
+                                          &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_RTU],
+                                          "RTU");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup RTU signature checks"));
+               goto fail;
+       }
+       psDevInfo->ui32SigRTChecksSize = ui32SignatureChecksBufSize;
+       
+       eError = RGXFWSetupSignatureChecks(psDevInfo,
+                                          &psDevInfo->psRGXFWSigSHChecksMemDesc, 
+                                          ui32SignatureChecksBufSize,
+                                          &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_SHG],
+                                          "SHG");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup SHG signature checks"));
+               goto fail;
+       }
+       psDevInfo->ui32SigSHChecksSize = ui32SignatureChecksBufSize;
+#endif
+
+#if defined(RGXFW_ALIGNCHECKS)
+       eError = RGXFWSetupAlignChecks(psDevInfo, 
+                                                               &psRGXFWInit->paui32AlignChecks, 
+                                                               pui32RGXFWAlignChecks, 
+                                                               ui32RGXFWAlignChecksSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup alignment checks"));
+               goto fail;
+       }
+#endif
+
+       /* Fill the remaining bits of fw the init data */
+       psRGXFWInit->sPDSExecBase.uiAddr = RGX_PDSCODEDATA_HEAP_BASE;
+       psRGXFWInit->sUSCExecBase.uiAddr = RGX_USCCODE_HEAP_BASE;
+       psRGXFWInit->sDPXControlStreamBase.uiAddr = RGX_DOPPLER_HEAP_BASE;
+       psRGXFWInit->sResultDumpBase.uiAddr = RGX_DOPPLER_OVERFLOW_HEAP_BASE;
+       psRGXFWInit->sRTUHeapBase.uiAddr = RGX_DOPPLER_HEAP_BASE;
+
+       /* RD Power Island */
+       {
+               RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
+               IMG_BOOL bSysEnableRDPowIsland = psRGXData->psRGXTimingInfo->bEnableRDPowIsland;
+               IMG_BOOL bEnableRDPowIsland = ((eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_DEFAULT) && bSysEnableRDPowIsland) ||
+                                               (eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_FORCE_ON);
+
+               ui32ConfigFlags |= bEnableRDPowIsland? RGXFWIF_INICFG_POW_RASCALDUST : 0;
+       }
+
+       psRGXFWInit->ui32ConfigFlags = ui32ConfigFlags & RGXFWIF_INICFG_ALL;
+       psRGXFWInit->ui32FilterFlags = ui32FilterFlags;
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+       psRGXFWInit->ui32JonesDisableMask = ui32JonesDisableMask;
+#endif
+       psDevInfo->bPDPEnabled = (ui32ConfigFlags & RGXFWIF_SRVCFG_DISABLE_PDP_EN)
+                       ? IMG_FALSE : IMG_TRUE;
+       psRGXFWInit->ui32HWRDebugDumpLimit = ui32HWRDebugDumpLimit;
+
+#if defined(RGX_FEATURE_SLC_VIVT)
+       eError = _AllocateSLC3Fence(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate memory for SLC3Fence"));
+               goto fail;
+       }
+#endif
+
+       /* Timestamps */
+       uiMemAllocFlags =
+               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+               PVRSRV_MEMALLOCFLAG_GPU_READABLE | /* XXX ?? */
+               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+               PVRSRV_MEMALLOCFLAG_UNCACHED |
+               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+       
+       /*
+         the timer query arrays
+       */
+       PDUMPCOMMENT("Allocate timer query arrays (FW)");
+       eError = DevmemFwAllocate(psDevInfo,
+                                 sizeof(RGXFWIF_TIMESTAMP) * RGX_MAX_TIMER_QUERIES,
+                                 uiMemAllocFlags,
+                                 "Start times array",
+                                 & psDevInfo->psStartTimeMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map start times array"));
+               goto fail;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psStartTimeMemDesc,
+                                         (IMG_VOID **)& psDevInfo->pasStartTimeById);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map start times array"));
+               goto fail;
+       }
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                 sizeof(RGXFWIF_TIMESTAMP) * RGX_MAX_TIMER_QUERIES,
+                                 uiMemAllocFlags,
+                                 "End times array",
+                                 & psDevInfo->psEndTimeMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map end times array"));
+               goto fail;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psEndTimeMemDesc,
+                                         (IMG_VOID **)& psDevInfo->pasEndTimeById);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map end times array"));
+               goto fail;
+       }
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                 sizeof(IMG_UINT32) * RGX_MAX_TIMER_QUERIES,
+                                 uiMemAllocFlags,
+                                 "Completed ops array",
+                                 & psDevInfo->psCompletedMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to completed ops array"));
+               goto fail;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psCompletedMemDesc,
+                                         (IMG_VOID **)& psDevInfo->pui32CompletedById);
+       
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map completed ops array"));
+               goto fail;
+       }
+
+               /* Initialize FW started flag */
+       psRGXFWInit->bFirmwareStarted = IMG_FALSE;
+       
+       /* Initialise the compatibility check data */
+       RGXFWIF_COMPCHECKS_BVNC_INIT(psRGXFWInit->sRGXCompChecks.sFWBVNC);
+       RGXFWIF_COMPCHECKS_BVNC_INIT(psRGXFWInit->sRGXCompChecks.sHWBVNC);
+       
+       {
+               /* Below line is to make sure (compilation time check) that 
+                               RGX_BVNC_KM_V_ST fits into RGXFWIF_COMPCHECKS_BVNC structure */
+               IMG_CHAR _tmp_[RGXFWIF_COMPCHECKS_BVNC_V_LEN_MAX] = RGX_BVNC_KM_V_ST;
+               _tmp_[0] = '\0';
+       }
+       
+       PDUMPCOMMENT("Dump RGXFW Init data");
+       if (!bEnableSignatureChecks)
+       {
+#if defined(PDUMP)
+               PDUMPCOMMENT("(to enable rgxfw signatures place the following line after the RTCONF line)");
+               DevmemPDumpLoadMem(     psDevInfo->psRGXFWIfInitMemDesc,
+                                                       offsetof(RGXFWIF_INIT, asSigBufCtl),
+                                                       sizeof(RGXFWIF_SIGBUF_CTL)*RGXFWIF_DM_MAX,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+#endif
+               psRGXFWInit->asSigBufCtl[RGXFWIF_DM_3D].psBuffer.ui32Addr = 0x0;
+               psRGXFWInit->asSigBufCtl[RGXFWIF_DM_TA].psBuffer.ui32Addr = 0x0;
+       }
+       
+       for (dm = 0; dm < RGXFWIF_DM_MAX; dm++)
+       {
+               psDevInfo->psRGXFWIfTraceBuf->aui16HwrDmLockedUpCount[dm] = 0;
+               psDevInfo->psRGXFWIfTraceBuf->aui16HwrDmOverranCount[dm] = 0;
+               psDevInfo->psRGXFWIfTraceBuf->aui16HwrDmRecoveredCount[dm] = 0;
+               psDevInfo->psRGXFWIfTraceBuf->aui16HwrDmFalseDetectCount[dm] = 0;
+               psDevInfo->psRGXFWIfTraceBuf->apsHwrDmFWCommonContext[dm].ui32Addr = 0;
+       }
+       
+       /*
+        * BIF Tiling configuration
+        */
+
+       psRGXFWInit->sBifTilingCfg[0].uiBase = RGX_BIF_TILING_HEAP_1_BASE;
+       psRGXFWInit->sBifTilingCfg[0].uiLen = RGX_BIF_TILING_HEAP_SIZE;
+       psRGXFWInit->sBifTilingCfg[0].uiXStride = pui32BIFTilingXStrides[0];
+       psRGXFWInit->sBifTilingCfg[1].uiBase = RGX_BIF_TILING_HEAP_2_BASE;
+       psRGXFWInit->sBifTilingCfg[1].uiLen = RGX_BIF_TILING_HEAP_SIZE;
+       psRGXFWInit->sBifTilingCfg[1].uiXStride = pui32BIFTilingXStrides[1];
+       psRGXFWInit->sBifTilingCfg[2].uiBase = RGX_BIF_TILING_HEAP_3_BASE;
+       psRGXFWInit->sBifTilingCfg[2].uiLen = RGX_BIF_TILING_HEAP_SIZE;
+       psRGXFWInit->sBifTilingCfg[2].uiXStride = pui32BIFTilingXStrides[2];
+       psRGXFWInit->sBifTilingCfg[3].uiBase = RGX_BIF_TILING_HEAP_4_BASE;
+       psRGXFWInit->sBifTilingCfg[3].uiLen = RGX_BIF_TILING_HEAP_SIZE;
+       psRGXFWInit->sBifTilingCfg[3].uiXStride = pui32BIFTilingXStrides[3];
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Dump rgxfw hwperfctl structure");
+       DevmemPDumpLoadZeroMem (psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
+                               0,
+                                                       ui32HWPerfCountersDataSize,
+                               PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("Dump rgxfw HW Perf Info structure");
+       DevmemPDumpLoadMem (psDevInfo->psRGXFWIfHWPerfBufMemDesc,
+                                               0,
+                                               psDevInfo->ui32RGXFWIfHWPerfBufSize,
+                                               PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("Dump rgxfw trace structure");
+       DevmemPDumpLoadMem(     psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
+                                               0,
+                                               sizeof(RGXFWIF_TRACEBUF),
+                                               PDUMP_FLAGS_CONTINUOUS);
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PDUMPCOMMENT("Dump rgxfw register configuration buffer");
+       DevmemPDumpLoadMem(     psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                               0,
+                                               sizeof(RGXFWIF_REG_CFG),
+                                               PDUMP_FLAGS_CONTINUOUS);
+#endif
+       PDUMPCOMMENT("Dump rgxfw init structure");
+       DevmemPDumpLoadMem(     psDevInfo->psRGXFWIfInitMemDesc,
+                                               0,
+                                               sizeof(RGXFWIF_INIT),
+                                               PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENT("Dump rgxfw coremem data store");
+       DevmemPDumpLoadMem(     psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
+                                               0,
+                                               RGX_META_COREMEM_DATA_SIZE,
+                                               PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENT("RTCONF: run-time configuration");
+
+       
+       /* Dump the config options so they can be edited.
+        * 
+        * FIXME: Need new DevmemPDumpWRW API which writes a WRW to load ui32ConfigFlags
+        */
+       PDUMPCOMMENT("(Set the FW config options here)");
+       PDUMPCOMMENT("( Ctx Switch TA Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_TA_EN);
+       PDUMPCOMMENT("( Ctx Switch 3D Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_3D_EN);
+       PDUMPCOMMENT("( Ctx Switch CDM Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_CDM_EN);
+       PDUMPCOMMENT("( Ctx Switch Rand mode: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_MODE_RAND);
+       PDUMPCOMMENT("( Ctx Switch Soft Reset Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_SRESET_EN);
+       PDUMPCOMMENT("( Reserved (do not set): 0x%08x)", RGXFWIF_INICFG_RSVD);
+       PDUMPCOMMENT("( Rascal+Dust Power Island: 0x%08x)", RGXFWIF_INICFG_POW_RASCALDUST);
+       PDUMPCOMMENT("( Enable HWPerf: 0x%08x)", RGXFWIF_INICFG_HWPERF_EN);
+       PDUMPCOMMENT("( Enable HWR: 0x%08x)", RGXFWIF_INICFG_HWR_EN);
+       PDUMPCOMMENT("( Check MList: 0x%08x)", RGXFWIF_INICFG_CHECK_MLIST_EN);
+       PDUMPCOMMENT("( Disable Auto Clock Gating: 0x%08x)", RGXFWIF_INICFG_DISABLE_CLKGATING_EN);
+       PDUMPCOMMENT("( Enable HWPerf Polling Perf Counter: 0x%08x)", RGXFWIF_INICFG_POLL_COUNTERS_EN);
+#if defined(RGX_FEATURE_VDM_OBJECT_LEVEL_LLS)
+       PDUMPCOMMENT("( Ctx Switch Object mode Index: 0x%08x)", RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX);
+       PDUMPCOMMENT("( Ctx Switch Object mode Instance: 0x%08x)", RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INSTANCE);
+       PDUMPCOMMENT("( Ctx Switch Object mode List: 0x%08x)", RGXFWIF_INICFG_VDM_CTX_STORE_MODE_LIST);
+#endif
+       PDUMPCOMMENT("( Enable SHG Bypass mode: 0x%08x)", RGXFWIF_INICFG_SHG_BYPASS_EN);
+       PDUMPCOMMENT("( Enable RTU Bypass mode: 0x%08x)", RGXFWIF_INICFG_RTU_BYPASS_EN);
+       PDUMPCOMMENT("( Enable register configuration: 0x%08x)", RGXFWIF_INICFG_REGCONFIG_EN);
+       PDUMPCOMMENT("( Assert on TA Out-of-Memory: 0x%08x)", RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY);
+       PDUMPCOMMENT("( Disable HWPerf custom counter filter: 0x%08x)", RGXFWIF_INICFG_HWP_DISABLE_FILTER);
+       PDUMPCOMMENT("( Enable HWPerf custom performance timer: 0x%08x)", RGXFWIF_INICFG_CUSTOM_PERF_TIMER_EN);
+       PDUMPCOMMENT("( Enable CDM Killing Rand mode: 0x%08x)", RGXFWIF_INICFG_CDM_KILL_MODE_RAND_EN);
+       PDUMPCOMMENT("( Disable DM overlap (except TA during SPM): 0x%08x)", RGXFWIF_INICFG_DISABLE_DM_OVERLAP);
+
+       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                       offsetof(RGXFWIF_INIT, ui32ConfigFlags),
+                                                       psRGXFWInit->ui32ConfigFlags,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+
+       /* default: no filter */
+       psRGXFWInit->sPIDFilter.eMode = RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT;
+       psRGXFWInit->sPIDFilter.asItems[0].uiPID = 0;
+
+       PDUMPCOMMENT("( PID filter type: %X=INCLUDE_ALL_EXCEPT, %X=EXCLUDE_ALL_EXCEPT)",
+                                                       RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT,
+                                                       RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT);
+
+       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                       offsetof(RGXFWIF_INIT, sPIDFilter.eMode),
+                                                       psRGXFWInit->sPIDFilter.eMode,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENT("( PID filter PID/OSID list (Up to %u entries. Terminate with a zero PID))",
+                                                                       RGXFWIF_PID_FILTER_MAX_NUM_PIDS);
+       {
+               IMG_UINT32 i;
+
+               /* generate a few WRWs in the pdump stream as an example */
+               for(i = 0; i < MIN(RGXFWIF_PID_FILTER_MAX_NUM_PIDS, 8); i++)
+               {
+                       PDUMPCOMMENT("(PID and OSID pair %u)", i);
+
+                       PDUMPCOMMENT("(PID)");
+                       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
+                                               offsetof(RGXFWIF_INIT, sPIDFilter.asItems[i].uiPID),
+                                               0,
+                                               PDUMP_FLAGS_CONTINUOUS);
+
+                       PDUMPCOMMENT("(OSID)");
+                       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
+                                               offsetof(RGXFWIF_INIT, sPIDFilter.asItems[i].ui32OSID),
+                                               0,
+                                               PDUMP_FLAGS_CONTINUOUS);
+               }
+       }
+
+       /* 
+        * Dump the log config so it can be edited.
+        */
+       PDUMPCOMMENT("(Set the log config here)");
+       PDUMPCOMMENT("( Log Type: set bit 0 for TRACE, reset for TBI)");
+       PDUMPCOMMENT("( MAIN Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MAIN);
+       PDUMPCOMMENT("( MTS Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MTS);
+       PDUMPCOMMENT("( CLEANUP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CLEANUP);
+       PDUMPCOMMENT("( CSW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CSW);
+       PDUMPCOMMENT("( BIF Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_BIF);
+       PDUMPCOMMENT("( PM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_PM);
+       PDUMPCOMMENT("( RTD Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_RTD);
+       PDUMPCOMMENT("( SPM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_SPM);
+       PDUMPCOMMENT("( POW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_POW);
+       PDUMPCOMMENT("( HWR Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWR);
+       PDUMPCOMMENT("( HWP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWP);
+#if defined(RGX_FEATURE_RAY_TRACING)
+       PDUMPCOMMENT("( RPM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_RPM);
+#endif
+#if defined(RGX_FEATURE_META_DMA)
+       PDUMPCOMMENT("( DMA Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DMA);
+#endif
+       PDUMPCOMMENT("( DEBUG Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DEBUG);
+       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
+                                                       offsetof(RGXFWIF_TRACEBUF, ui32LogType),
+                                                       psDevInfo->psRGXFWIfTraceBuf->ui32LogType,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENT("Set the HWPerf Filter config here");
+       DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfInitMemDesc,
+                                               offsetof(RGXFWIF_INIT, ui64HWPerfFilter),
+                                               psRGXFWInit->ui64HWPerfFilter,
+                                               PDUMP_FLAGS_CONTINUOUS);                                                
+                                                       
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PDUMPCOMMENT("(Number of registers configurations in sidekick)");
+       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                                       offsetof(RGXFWIF_REG_CFG, ui32NumRegsSidekick),
+                                                       0,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("(Number of registers configurations in rascal/dust)");
+       DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                                       offsetof(RGXFWIF_REG_CFG, ui32NumRegsRascalDust),
+                                                       0,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("(Set registers here, address, value)");
+       DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                                       offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Addr),
+                                                       0,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+       DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc,
+                                                       offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Value),
+                                                       0,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+#endif /* SUPPORT_USER_REGISTER_CONFIGURATION */
+#endif
+
+       /* We don't need access to the fw init data structure anymore */
+       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+       psRGXFWInit = IMG_NULL;
+
+       psDevInfo->bFirmwareInitialised = IMG_TRUE;
+
+       return PVRSRV_OK;
+
+fail:
+       if (psDevInfo->psRGXFWIfInitMemDesc != IMG_NULL && psRGXFWInit != IMG_NULL)
+       {
+               DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+       }
+       RGXFreeFirmware(psDevInfo);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXFreeFirmware
+
+ @Description
+
+ Frees all the firmware-related allocations
+
+ @Input psDevInfo
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_VOID RGXFreeFirmware(PVRSRV_RGXDEV_INFO    *psDevInfo)
+{
+       RGXFWIF_DM      eCCBType;
+       
+       psDevInfo->bFirmwareInitialised = IMG_FALSE;
+
+       for (eCCBType = 0; eCCBType < RGXFWIF_DM_MAX; eCCBType++)
+       {
+               RGXFreeKernelCCB(psDevInfo, eCCBType);
+               RGXFreeFirmwareCCB(psDevInfo, eCCBType);
+       }
+
+#if defined(RGXFW_ALIGNCHECKS)
+       if (psDevInfo->psRGXFWAlignChecksMemDesc)
+       {
+               RGXFWFreeAlignChecks(psDevInfo);
+       }
+#endif
+
+       if (psDevInfo->psRGXFWSigTAChecksMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWSigTAChecksMemDesc);
+               psDevInfo->psRGXFWSigTAChecksMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psRGXFWSig3DChecksMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWSig3DChecksMemDesc);
+               psDevInfo->psRGXFWSig3DChecksMemDesc = IMG_NULL;
+       }
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       if (psDevInfo->psRGXFWSigRTChecksMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWSigRTChecksMemDesc);
+               psDevInfo->psRGXFWSigRTChecksMemDesc = IMG_NULL;
+       }
+       
+       if (psDevInfo->psRGXFWSigSHChecksMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWSigSHChecksMemDesc);
+               psDevInfo->psRGXFWSigSHChecksMemDesc = IMG_NULL;
+       }
+#endif
+
+#if defined(FIX_HW_BRN_37200)
+       if (psDevInfo->psRGXFWHWBRN37200MemDesc)
+       {
+               DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWHWBRN37200MemDesc);
+               DevmemFree(psDevInfo->psRGXFWHWBRN37200MemDesc);
+               psDevInfo->psRGXFWHWBRN37200MemDesc = IMG_NULL;
+       }
+#endif
+
+       RGXSetupFaultReadRegisterRollback(psDevInfo);
+
+       if (psDevInfo->psPowSyncPrim != IMG_NULL)
+       {
+               SyncPrimFree(psDevInfo->psPowSyncPrim);
+               psDevInfo->psPowSyncPrim = IMG_NULL;
+       }
+       
+       if (psDevInfo->hSyncPrimContext != 0)
+       {
+               SyncPrimContextDestroy(psDevInfo->hSyncPrimContext);
+               psDevInfo->hSyncPrimContext = 0;
+       }
+
+       if (psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc)
+       {
+               if (psDevInfo->psRGXFWIfGpuUtilFWCb != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
+                       psDevInfo->psRGXFWIfGpuUtilFWCb = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
+               psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psRGXFWIfRuntimeCfgMemDesc)
+       {
+               if (psDevInfo->psRGXFWIfRuntimeCfg != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
+                       psDevInfo->psRGXFWIfRuntimeCfg = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
+               psDevInfo->psRGXFWIfRuntimeCfgMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc)
+       {
+               if (psDevInfo->psRGXFWIfHWRInfoBuf != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
+                       psDevInfo->psRGXFWIfHWRInfoBuf = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
+               psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc = IMG_NULL;
+       }
+
+       RGXHWPerfDeinit();
+       
+       if (psDevInfo->psRGXFWIfHWPerfBufMemDesc)
+       {
+               if (psDevInfo->psRGXFWIfHWPerfBuf != IMG_NULL)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfHWPerfBufMemDesc);
+                       psDevInfo->psRGXFWIfHWPerfBuf = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfHWPerfBufMemDesc);
+               psDevInfo->psRGXFWIfHWPerfBufMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psRGXFWIfCorememDataStoreMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWIfCorememDataStoreMemDesc);
+               psDevInfo->psRGXFWIfCorememDataStoreMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psRGXFWIfTraceBufCtlMemDesc)
+       {
+               if (psDevInfo->psRGXFWIfTraceBuf != IMG_NULL)
+               {    
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
+                       psDevInfo->psRGXFWIfTraceBuf = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
+               psDevInfo->psRGXFWIfTraceBufCtlMemDesc = IMG_NULL;
+       }
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       if (psDevInfo->psRGXFWIfRegCfgMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWIfRegCfgMemDesc);
+               psDevInfo->psRGXFWIfRegCfgMemDesc = IMG_NULL;
+       }
+#endif
+       if (psDevInfo->psRGXFWIfHWPerfCountersMemDesc)
+       {
+               RGXUnsetFirmwareAddress(psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
+               if (DevmemIsValidExportCookie(&psDevInfo->sRGXFWHWPerfCountersExportCookie))
+               {
+                       /* if the export cookie is valid, the init sequence failed */
+                       PVR_DPF((PVR_DBG_ERROR, "RGXFreeFirmware: FW HWPerf Export cookie"
+                                "still valid (should have been unexported at init time)"));
+                       DevmemUnexport(psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
+                                      &psDevInfo->sRGXFWHWPerfCountersExportCookie);
+               }
+               DevmemFwFree(psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
+               psDevInfo->psRGXFWIfHWPerfCountersMemDesc = IMG_NULL;
+       }
+#if defined(RGX_FEATURE_SLC_VIVT)
+       _FreeSLC3Fence(psDevInfo);
+#endif
+
+       if (psDevInfo->psRGXFWIfInitMemDesc)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWIfInitMemDesc);
+               psDevInfo->psRGXFWIfInitMemDesc = IMG_NULL;
+       }
+
+       if (psDevInfo->psCompletedMemDesc)
+       {
+               if (psDevInfo->pui32CompletedById)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psCompletedMemDesc);
+                       psDevInfo->pui32CompletedById = IMG_NULL;
+               }
+               DevmemFwFree(psDevInfo->psCompletedMemDesc);
+               psDevInfo->psCompletedMemDesc = IMG_NULL;
+       }
+       if (psDevInfo->psEndTimeMemDesc)
+       {
+               if (psDevInfo->pasEndTimeById)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psEndTimeMemDesc);
+                       psDevInfo->pasEndTimeById = IMG_NULL;
+               }
+
+               DevmemFwFree(psDevInfo->psEndTimeMemDesc);
+               psDevInfo->psEndTimeMemDesc = IMG_NULL;
+       }
+       if (psDevInfo->psStartTimeMemDesc)
+       {
+               if (psDevInfo->pasStartTimeById)
+               {
+                       DevmemReleaseCpuVirtAddr(psDevInfo->psStartTimeMemDesc);
+                       psDevInfo->pasStartTimeById = IMG_NULL;
+               }
+
+               DevmemFwFree(psDevInfo->psStartTimeMemDesc);
+               psDevInfo->psStartTimeMemDesc = IMG_NULL;
+       }
+}
+
+
+/******************************************************************************
+ FUNCTION      : RGXStartFirmware
+
+ PURPOSE       : Attempts to obtain a slot in the Kernel CCB
+
+ PARAMETERS    : psDevInfo
+
+ RETURNS       : PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR RGXStartFirmware(PVRSRV_RGXDEV_INFO       *psDevInfo)
+{
+       PVRSRV_ERROR    eError = PVRSRV_OK;
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Rogue Firmware Slave boot Start");
+       /*
+        * Run init script.
+        */
+       eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asInitCommands, RGX_MAX_INIT_COMMANDS, PDUMP_FLAGS_CONTINUOUS, IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXStart: RGXRunScript failed (%d)", eError));
+               return eError;
+       }
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Rogue Firmware startup complete\n");
+       
+       return eError;
+}
+
+
+/******************************************************************************
+ FUNCTION      : RGXAcquireKernelCCBSlot
+
+ PURPOSE       : Attempts to obtain a slot in the Kernel CCB
+
+ PARAMETERS    : psCCB - the CCB
+                       : Address of space if available, IMG_NULL otherwise
+
+ RETURNS       : PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR RGXAcquireKernelCCBSlot(DEVMEM_MEMDESC *psKCCBCtrlMemDesc,
+                                                                                       RGXFWIF_CCB_CTL *psKCCBCtl,
+                                                                                       IMG_UINT32                      *pui32Offset)
+{
+       IMG_UINT32      ui32OldWriteOffset, ui32NextWriteOffset;
+
+       ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset;
+       ui32NextWriteOffset = (ui32OldWriteOffset + 1) & psKCCBCtl->ui32WrapMask;
+
+       /* Note: The MTS can queue up to 255 kicks (254 pending kicks and 1 executing kick)
+        * Hence the kernel CCB should not queue more 254 commands
+        */
+       PVR_ASSERT(psKCCBCtl->ui32WrapMask < 255);
+       
+#if defined(PDUMP)
+       /* Wait for sufficient CCB space to become available */
+       PDUMPCOMMENTWITHFLAGS(0, "Wait for kCCB woff=%u", ui32NextWriteOffset);
+       DevmemPDumpCBP(psKCCBCtrlMemDesc,
+                      offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset),
+                      ui32NextWriteOffset,
+                      1,
+                      (psKCCBCtl->ui32WrapMask + 1));
+#endif
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+
+               if (ui32NextWriteOffset != psKCCBCtl->ui32ReadOffset)
+               {
+                       *pui32Offset = ui32NextWriteOffset;
+                       return PVRSRV_OK;
+               }
+               {
+                       /* 
+                        * The following sanity check doesn't impact performance,
+                        * since the CPU has to wait for the GPU anyway (full kernel CCB).
+                        */
+                       if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK)
+                       {
+                               return PVRSRV_ERROR_KERNEL_CCB_FULL;
+                       }
+               }
+
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       /* Time out on waiting for CCB space */
+       return PVRSRV_ERROR_KERNEL_CCB_FULL;
+}
+
+
+PVRSRV_ERROR RGXSendCommandWithPowLock(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                                RGXFWIF_DM                     eKCCBType,
+                                                                                RGXFWIF_KCCB_CMD       *psKCCBCmd,
+                                                                                IMG_UINT32                     ui32CmdSize,
+                                                                                IMG_BOOL                       bPDumpContinuous)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
+
+       /* Ensure Rogue is powered up before kicking MTS */
+       eError = PVRSRVPowerLock();
+
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandWithPowLock: failed to acquire powerlock (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               goto _PVRSRVPowerLock_Exit;
+       }
+
+       PDUMPPOWCMDSTART();
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE_ON,
+                                                                                IMG_FALSE);
+       PDUMPPOWCMDEND();
+
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandWithPowLock: failed to transition Rogue to ON (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               goto _PVRSRVSetDevicePowerStateKM_Exit;
+       }
+
+       eError = RGXSendCommandRaw(psDevInfo, eKCCBType,  psKCCBCmd, ui32CmdSize, bPDumpContinuous?PDUMP_FLAGS_CONTINUOUS:0);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandWithPowLock: failed to schedule command (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+#if defined(DEBUG)
+               /* PVRSRVDebugRequest must be called without powerlock */
+               PVRSRVPowerUnlock();
+               PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+               goto _PVRSRVPowerLock_Exit;
+#endif
+       }
+
+_PVRSRVSetDevicePowerStateKM_Exit:
+       PVRSRVPowerUnlock();
+
+_PVRSRVPowerLock_Exit:
+       return eError;
+}
+
+PVRSRV_ERROR RGXSendCommandRaw(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                RGXFWIF_DM                     eKCCBType,
+                                                                RGXFWIF_KCCB_CMD       *psKCCBCmd,
+                                                                IMG_UINT32                     ui32CmdSize,
+                                                                PDUMP_FLAGS_T          uiPdumpFlags)
+{
+       PVRSRV_ERROR            eError;
+       RGXFWIF_CCB_CTL         *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eKCCBType];
+       IMG_UINT8                       *pui8KCCB = psDevInfo->apsKernelCCB[eKCCBType];
+       IMG_UINT32                      ui32NewWriteOffset;
+       IMG_UINT32                      ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset;
+#if !defined(PDUMP)
+       PVR_UNREFERENCED_PARAMETER(uiPdumpFlags);
+#endif
+#if defined(PDUMP)
+       IMG_BOOL bIsInCaptureRange;
+       IMG_BOOL bPdumpEnabled;
+       IMG_BOOL bPDumpContinuous = (uiPdumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0;
+       IMG_BOOL bPDumpPowTrans = PDUMPPOWCMDINTRANS();
+
+       PDumpIsCaptureFrameKM(&bIsInCaptureRange);
+       bPdumpEnabled = (bIsInCaptureRange || bPDumpContinuous) && !bPDumpPowTrans;
+
+       /* in capture range */
+       if (bPdumpEnabled)
+       {
+               if (!psDevInfo->abDumpedKCCBCtlAlready[eKCCBType])
+               {
+                       /* entering capture range */
+                       psDevInfo->abDumpedKCCBCtlAlready[eKCCBType] = IMG_TRUE;
+
+                       /* wait for firmware to catch up */
+                       PVR_DPF((PVR_DBG_MESSAGE, "RGXSendCommandRaw: waiting on fw to catch-up. DM: %d, roff: %d, woff: %d",
+                                               eKCCBType, psKCCBCtl->ui32ReadOffset, ui32OldWriteOffset));
+                       PVRSRVPollForValueKM(&psKCCBCtl->ui32ReadOffset, ui32OldWriteOffset, 0xFFFFFFFF);
+
+                       /* Dump Init state of Kernel CCB control (read and write offset) */
+                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Initial state of kernel CCB Control(%d), roff: %d, woff: %d", eKCCBType, psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset);
+                       DevmemPDumpLoadMem(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                       0,
+                                       sizeof(RGXFWIF_CCB_CTL),
+                                       PDUMP_FLAGS_CONTINUOUS);
+               }
+       }
+#endif
+
+       PVR_ASSERT(ui32CmdSize == psKCCBCtl->ui32CmdSize);
+       if (!OSLockIsLocked(PVRSRVGetPVRSRVData()->hPowerLock))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandRaw called without power lock held!"));
+               PVR_ASSERT(OSLockIsLocked(PVRSRVGetPVRSRVData()->hPowerLock));
+       }
+
+       /*
+        * Acquire a slot in the CCB.
+        */ 
+       eError = RGXAcquireKernelCCBSlot(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType], psKCCBCtl, &ui32NewWriteOffset);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandRaw failed to acquire CCB slot. Type:%u Error:%u",
+                               eKCCBType, eError));
+               goto _RGXSendCommandRaw_Exit;
+       }
+       
+       /*
+        * Copy the command into the CCB.
+        */
+       OSMemCopy(&pui8KCCB[ui32OldWriteOffset * psKCCBCtl->ui32CmdSize],
+                         psKCCBCmd, psKCCBCtl->ui32CmdSize);
+
+       /* ensure kCCB data is written before the offsets */
+       OSWriteMemoryBarrier();
+
+       /* Move past the current command */
+       psKCCBCtl->ui32WriteOffset = ui32NewWriteOffset;
+
+
+#if defined(PDUMP)
+       /* in capture range */
+       if (bPdumpEnabled)
+       {
+               /* Dump new Kernel CCB content */
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Dump kCCB(%d) cmd, woff = %d", eKCCBType, ui32OldWriteOffset);
+               DevmemPDumpLoadMem(psDevInfo->apsKernelCCBMemDesc[eKCCBType],
+                               ui32OldWriteOffset * psKCCBCtl->ui32CmdSize,
+                               psKCCBCtl->ui32CmdSize,
+                               PDUMP_FLAGS_CONTINUOUS);
+
+               /* Dump new kernel CCB write offset */
+               PDUMPCOMMENTWITHFLAGS(uiPdumpFlags, "Dump kCCBCtl(%d) woff: %d", eKCCBType, ui32NewWriteOffset);
+               DevmemPDumpLoadMem(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                                          offsetof(RGXFWIF_CCB_CTL, ui32WriteOffset),
+                                                          sizeof(IMG_UINT32),
+                                                          uiPdumpFlags);
+       }
+
+       /* out of capture range */
+       if (!bPdumpEnabled)
+       {
+               eError = RGXPdumpDrainKCCB(psDevInfo, ui32OldWriteOffset, eKCCBType);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandRaw: problem draining kCCB (%d)", eError));
+                       goto _RGXSendCommandRaw_Exit;
+               }
+       }
+#endif
+
+
+       PDUMPCOMMENTWITHFLAGS(uiPdumpFlags, "MTS kick for kernel CCB %d", eKCCBType);
+       /*
+        * Kick the MTS to schedule the firmware.
+        */
+       {
+               IMG_UINT32      ui32MTSRegVal = (eKCCBType & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_COUNTED;
+               
+               __MTSScheduleWrite(psDevInfo, ui32MTSRegVal);
+
+               PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_MTS_SCHEDULE, ui32MTSRegVal, uiPdumpFlags);
+       }
+       
+#if defined (NO_HARDWARE)
+       /* keep the roff updated because fw isn't there to update it */
+       psKCCBCtl->ui32ReadOffset = psKCCBCtl->ui32WriteOffset;
+#endif
+
+_RGXSendCommandRaw_Exit:
+       return eError;
+}
+
+IMG_VOID RGXScheduleProcessQueuesKM(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*) hCmdCompHandle;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+       OSScheduleMISR(psDevInfo->hProcessQueuesMISR);
+}
+
+/*!
+******************************************************************************
+
+ @Function     _RGXScheduleProcessQueuesMISR
+
+ @Description - Sends uncounted kick to all the DMs (the FW will process all
+                               the queue for all the DMs)
+******************************************************************************/
+static IMG_VOID _RGXScheduleProcessQueuesMISR(IMG_VOID *pvData)
+{
+       PVRSRV_DEVICE_NODE     *psDeviceNode = pvData;
+       PVRSRV_RGXDEV_INFO     *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_DM                         eDM;
+       PVRSRV_ERROR               eError;
+       PVRSRV_DEV_POWER_STATE ePowerState;
+
+       /* We don't need to acquire the BridgeLock as this power transition won't
+          send a command to the FW */
+       eError = PVRSRVPowerLock();
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXScheduleProcessQueuesKM: failed to acquire powerlock (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               return;
+       }
+
+       /* Check whether it's worth waking up the GPU */
+       eError = PVRSRVGetDevicePowerState(psDeviceNode->sDevId.ui32DeviceIndex, &ePowerState);
+
+       if ((eError == PVRSRV_OK) && (ePowerState == PVRSRV_DEV_POWER_STATE_OFF))
+       {
+               RGXFWIF_GPU_UTIL_FWCB  *psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb;
+               IMG_BOOL               bGPUHasWorkWaiting;
+
+               bGPUHasWorkWaiting =
+                   (RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord) == RGXFWIF_GPU_UTIL_STATE_BLOCKED);
+
+               if (!bGPUHasWorkWaiting)
+               {
+                       /* all queues are empty, don't wake up the GPU */
+                       PVRSRVPowerUnlock();
+                       return;
+               }
+       }
+
+       PDUMPPOWCMDSTART();
+       /* wake up the GPU */
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE_ON,
+                                                                                IMG_FALSE);
+       PDUMPPOWCMDEND();
+
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXScheduleProcessQueuesKM: failed to transition Rogue to ON (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               PVRSRVPowerUnlock();
+               return;
+       }
+
+       /* uncounted kick for all DMs */
+       for (eDM = RGXFWIF_HWDM_MIN; eDM < RGXFWIF_HWDM_MAX; eDM++)
+       {
+               IMG_UINT32      ui32MTSRegVal = (eDM & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED;
+
+               __MTSScheduleWrite(psDevInfo, ui32MTSRegVal);
+       }
+
+       PVRSRVPowerUnlock();
+}
+
+PVRSRV_ERROR RGXInstallProcessQueuesMISR(IMG_HANDLE *phMISR, PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       return OSInstallMISR(phMISR,
+                            _RGXScheduleProcessQueuesMISR,
+                            psDeviceNode);
+}
+
+typedef struct _DEVMEM_COMMON_CONTEXT_LOOKUP_
+{
+       IMG_UINT32                 ui32ContextID;
+       RGX_SERVER_COMMON_CONTEXT  *psServerCommonContext;
+} DEVMEM_COMMON_CONTEXT_LOOKUP;
+
+
+static IMG_BOOL _FindServerCommonContext(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       DEVMEM_COMMON_CONTEXT_LOOKUP  *psRefLookUp = (DEVMEM_COMMON_CONTEXT_LOOKUP *)pvCallbackData;
+       RGX_SERVER_COMMON_CONTEXT     *psServerCommonContext;
+
+       psServerCommonContext = IMG_CONTAINER_OF(psNode, RGX_SERVER_COMMON_CONTEXT, sListNode);
+
+       if (psServerCommonContext->ui32ContextID == psRefLookUp->ui32ContextID)
+       {
+               psRefLookUp->psServerCommonContext = psServerCommonContext;
+               return IMG_FALSE;
+       }
+       else
+       {
+               return IMG_TRUE;
+       }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     RGXScheduleCommand
+
+ @Description - Submits a CCB command and kicks the firmware but first schedules
+                any commands which have to happen before handle  
+
+ @Input psDevInfo - pointer to device info
+ @Input eKCCBType - see RGXFWIF_CMD_*
+ @Input pvKCCBCmd - kernel CCB command
+ @Input ui32CmdSize -
+ @Input bPDumpContinuous - TRUE if the pdump flags should be continuous
+
+
+ @Return ui32Error - success or failure
+
+******************************************************************************/
+PVRSRV_ERROR RGXScheduleCommand(PVRSRV_RGXDEV_INFO     *psDevInfo,
+                                                               RGXFWIF_DM                      eKCCBType,
+                                                               RGXFWIF_KCCB_CMD        *psKCCBCmd,
+                                                               IMG_UINT32                      ui32CmdSize,
+                                                               IMG_BOOL                        bPDumpContinuous)
+{
+       PVRSRV_DATA *psData = PVRSRVGetPVRSRVData();
+       PVRSRV_ERROR eError;
+
+       if ((eKCCBType == RGXFWIF_DM_3D) || (eKCCBType == RGXFWIF_DM_2D) || (eKCCBType == RGXFWIF_DM_CDM))
+       {
+               /* This handles the no operation case */
+               OSCPUOperation(psData->uiCacheOp);
+               psData->uiCacheOp = PVRSRV_CACHE_OP_NONE;
+       }
+
+       eError = RGXPreKickCacheCommand(psDevInfo);
+       if (eError != PVRSRV_OK) goto RGXScheduleCommand_exit;
+
+       eError = RGXSendCommandWithPowLock(psDevInfo, eKCCBType, psKCCBCmd, ui32CmdSize, bPDumpContinuous);
+       if (eError != PVRSRV_OK) goto RGXScheduleCommand_exit;
+
+
+RGXScheduleCommand_exit:
+       return eError;
+}
+
+/*
+ * RGXCheckFirmwareCCBs
+ */
+IMG_VOID RGXCheckFirmwareCCBs(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       RGXFWIF_FWCCB_CMD       *psFwCCBCmd;
+       IMG_UINT32                      ui32DMCount;
+
+       for (ui32DMCount = 0; ui32DMCount < RGXFWIF_DM_MAX; ui32DMCount++)
+       {
+               RGXFWIF_CCB_CTL *psFWCCBCtl = psDevInfo->apsFirmwareCCBCtl[ui32DMCount];
+               IMG_UINT8               *psFWCCB = psDevInfo->apsFirmwareCCB[ui32DMCount];
+
+               while (psFWCCBCtl->ui32ReadOffset != psFWCCBCtl->ui32WriteOffset)
+               {
+                       /* Point to the next command */
+                       psFwCCBCmd = ((RGXFWIF_FWCCB_CMD *)psFWCCB) + psFWCCBCtl->ui32ReadOffset;
+
+                       switch(psFwCCBCmd->eCmdType)
+                       {
+                               case RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING:
+                               {
+                                       if (psDevInfo->bPDPEnabled)
+                                       {
+                                               PDUMP_PANIC(RGX, ZSBUFFER_BACKING, "Request to add backing to ZSBuffer");
+                                       }
+                                       RGXProcessRequestZSBufferBacking(psDevInfo,
+                                                                                                       psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID);
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING:
+                               {
+                                       if (psDevInfo->bPDPEnabled)
+                                       {
+                                               PDUMP_PANIC(RGX, ZSBUFFER_UNBACKING, "Request to remove backing from ZSBuffer");
+                                       }
+                                       RGXProcessRequestZSBufferUnbacking(psDevInfo,
+                                                                                                       psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID);
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_FREELIST_GROW:
+                               {
+                                       if (psDevInfo->bPDPEnabled)
+                                       {
+                                               PDUMP_PANIC(RGX, FREELIST_GROW, "Request to grow the free list");
+                                       }
+                                       RGXProcessRequestGrow(psDevInfo,
+                                                                               psFwCCBCmd->uCmdData.sCmdFreeListGS.ui32FreelistID);
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION:
+                               {
+                                       if (psDevInfo->bPDPEnabled)
+                                       {
+                                               PDUMP_PANIC(RGX, FREELISTS_RECONSTRUCTION, "Request to reconstruct free lists");
+                                       }
+
+                                       PVR_DPF((PVR_DBG_MESSAGE, "RGXCheckFirmwareCCBs: Freelist reconstruction request (%d/%d) for %d freelists",
+                                               psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32HwrCounter+1,
+                                               psDevInfo->psRGXFWIfTraceBuf->ui32HwrCounter+1,
+                                               psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount));
+
+                                       RGXProcessRequestFreelistsReconstruction(psDevInfo, ui32DMCount,
+                                                                               psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount,
+                                                                               psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.aui32FreelistIDs);
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION:
+                               {
+                                       DEVMEM_COMMON_CONTEXT_LOOKUP  sLookUp;
+
+                                       sLookUp.ui32ContextID         = psFwCCBCmd->uCmdData.sCmdContextResetNotification.ui32ServerCommonContextID;
+                                       sLookUp.psServerCommonContext = IMG_NULL;
+                                       
+                                       dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, _FindServerCommonContext, (IMG_PVOID)&sLookUp);
+
+                                       PVR_DPF((PVR_DBG_MESSAGE, "RGXCheckFirmwareCCBs: Context 0x%p reset (ID=0x%08x, Reason=%d)",
+                                               sLookUp.psServerCommonContext,
+                                               (IMG_UINT32)(psFwCCBCmd->uCmdData.sCmdContextResetNotification.ui32ServerCommonContextID),
+                                               (IMG_UINT32)(psFwCCBCmd->uCmdData.sCmdContextResetNotification.eResetReason)));
+
+                                       if (sLookUp.psServerCommonContext != IMG_NULL)
+                                       {
+                                               sLookUp.psServerCommonContext->eLastResetReason = psFwCCBCmd->uCmdData.sCmdContextResetNotification.eResetReason;
+                                       }
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_DEBUG_DUMP:
+                               {
+                                       RGXDumpDebugInfo(IMG_NULL,psDevInfo);
+                                       break;
+                               }
+
+                               case RGXFWIF_FWCCB_CMD_UPDATE_STATS:
+                               {
+                    IMG_PID       pidTmp = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.pidOwner;
+                    IMG_INT32  i32AdjustmentValue = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.i32AdjustmentValue;
+
+                    switch (psFwCCBCmd->uCmdData.sCmdUpdateStatsData.eElementToUpdate)
+                                       {
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS:
+                                               {
+                            PVRSRVStatsUpdateRenderContextStats(i32AdjustmentValue,0,0,0,0,0,pidTmp);
+                                                       break;
+                                               }
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY:
+                                               {
+                                                       PVRSRVStatsUpdateRenderContextStats(0,i32AdjustmentValue,0,0,0,0,pidTmp);
+                                                       break;
+                                               }
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES:
+                                               {
+                                                       PVRSRVStatsUpdateRenderContextStats(0,0,i32AdjustmentValue,0,0,0,pidTmp);
+                                                       break;
+                                               }
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES:
+                                               {
+                                                       PVRSRVStatsUpdateRenderContextStats(0,0,0,i32AdjustmentValue,0,0,pidTmp);
+                                                       break;
+                                               }
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_SH_STORES:
+                                               {
+                                                       PVRSRVStatsUpdateRenderContextStats(0,0,0,0,i32AdjustmentValue,0,pidTmp);
+                                                       break;
+                                               }
+                                               case RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES:
+                                               {
+                                                       PVRSRVStatsUpdateRenderContextStats(0,0,0,0,0,i32AdjustmentValue,pidTmp);
+                                                       break;
+                                               }
+                                       }
+                                       break;
+                               }
+                               default:
+                                       PVR_ASSERT(IMG_FALSE);
+                       }
+
+                       /* Update read offset */
+                       psFWCCBCtl->ui32ReadOffset = (psFWCCBCtl->ui32ReadOffset + 1) & psFWCCBCtl->ui32WrapMask;
+               }
+       }
+}
+
+/*
+ * PVRSRVRGXFrameworkCopyCommand
+ */ 
+PVRSRV_ERROR PVRSRVRGXFrameworkCopyCommand(DEVMEM_MEMDESC      *psFWFrameworkMemDesc,
+                                                                                  IMG_PBYTE            pbyGPUFRegisterList,
+                                                                                  IMG_UINT32           ui32FrameworkRegisterSize)
+{
+       PVRSRV_ERROR    eError;
+       RGXFWIF_RF_REGISTERS    *psRFReg;
+
+       eError = DevmemAcquireCpuVirtAddr(psFWFrameworkMemDesc,
+                                      (IMG_VOID **)&psRFReg);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFrameworkCopyCommand: Failed to map firmware render context state (%u)",
+                               eError));
+               return eError;
+       }
+
+       OSMemCopy(psRFReg, pbyGPUFRegisterList, ui32FrameworkRegisterSize);
+       
+       /* Release the CPU mapping */
+       DevmemReleaseCpuVirtAddr(psFWFrameworkMemDesc);
+
+       /*
+        * Dump the FW framework buffer
+        */
+       PDUMPCOMMENT("Dump FWFramework buffer");
+       DevmemPDumpLoadMem(psFWFrameworkMemDesc, 0, ui32FrameworkRegisterSize, PDUMP_FLAGS_CONTINUOUS);
+
+       return PVRSRV_OK;
+}
+
+/*
+ * PVRSRVRGXFrameworkCreateKM
+ */
+PVRSRV_ERROR PVRSRVRGXFrameworkCreateKM(PVRSRV_DEVICE_NODE     *psDeviceNode,
+                                                                               DEVMEM_MEMDESC          **ppsFWFrameworkMemDesc,
+                                                                               IMG_UINT32                      ui32FrameworkCommandSize)
+{
+       PVRSRV_ERROR                    eError;
+       PVRSRV_RGXDEV_INFO              *psDevInfo = psDeviceNode->pvDevice;
+       
+       /*
+               Allocate device memory for the firmware GPU framework state.
+               Sufficient info to kick one or more DMs should be contained in this buffer
+       */
+       PDUMPCOMMENT("Allocate Rogue firmware framework state");
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         ui32FrameworkCommandSize,
+                                                         RGX_FWCOMCTX_ALLOCFLAGS,
+                                                         "FirmwareGPUFrameworkState",
+                                                         ppsFWFrameworkMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFrameworkContextKM: Failed to allocate firmware framework state (%u)",
+                               eError));
+               return eError;
+       }
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RGXWaitForFWOp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                       RGXFWIF_DM eDM,
+                                                       PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                       IMG_BOOL bPDumpContinuous)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
+       RGXFWIF_KCCB_CMD        sCmdSyncPrim;
+
+       /* Ensure Rogue is powered up before kicking MTS */
+       eError = PVRSRVPowerLock();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXWaitForFWOp: failed to acquire powerlock (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               goto _PVRSRVPowerLock_Exit;
+       }
+
+       PDUMPPOWCMDSTART();
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE_ON,
+                                                                                IMG_FALSE);
+       PDUMPPOWCMDEND();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXWaitForFWOp: failed to transition Rogue to ON (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               goto _PVRSRVSetDevicePowerStateKM_Exit;
+       }
+
+
+
+
+       /* Setup sync primitive */
+       SyncPrimSet(psSyncPrim, 0);
+
+       /* prepare a sync command */
+       sCmdSyncPrim.eCmdType = RGXFWIF_KCCB_CMD_SYNC;
+       sCmdSyncPrim.uCmdData.sSyncData.uiSyncObjDevVAddr = SyncPrimGetFirmwareAddr(psSyncPrim);
+       sCmdSyncPrim.uCmdData.sSyncData.uiUpdateVal = 1;
+
+       PDUMPCOMMENT("RGXWaitForFWOp: Submit Kernel SyncPrim [0x%08x] to DM %d ", sCmdSyncPrim.uCmdData.sSyncData.uiSyncObjDevVAddr, eDM);
+
+       /* submit the sync primitive to the kernel CCB */
+       eError = RGXSendCommandRaw(psDevInfo,
+                                                               eDM,
+                                                               &sCmdSyncPrim,
+                                                               sizeof(RGXFWIF_KCCB_CMD),
+                                                               bPDumpContinuous  ? PDUMP_FLAGS_CONTINUOUS:0);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXScheduleCommandAndWait: Failed to schedule Kernel SyncPrim with error (%u)", eError));
+               goto _RGXSendCommandRaw_Exit;
+       }
+
+       /* Wait for sync primitive to be updated */
+#if defined(PDUMP)
+       PDUMPCOMMENT("RGXScheduleCommandAndWait: Poll for Kernel SyncPrim [0x%08x] on DM %d ", sCmdSyncPrim.uCmdData.sSyncData.uiSyncObjDevVAddr, eDM);
+
+       SyncPrimPDumpPol(psSyncPrim,
+                                       1,
+                                       0xffffffff,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       bPDumpContinuous ? PDUMP_FLAGS_CONTINUOUS:0);
+#endif
+
+       {
+               RGXFWIF_CCB_CTL  *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eDM];
+               IMG_UINT32       ui32CurrentQueueLength = (psKCCBCtl->ui32WrapMask+1 +
+                                                                                                  psKCCBCtl->ui32WriteOffset -
+                                                                                                  psKCCBCtl->ui32ReadOffset) & psKCCBCtl->ui32WrapMask;
+               IMG_UINT32       ui32MaxRetries;
+
+               for (ui32MaxRetries = (ui32CurrentQueueLength + 1) * 3;
+                        ui32MaxRetries > 0;
+                        ui32MaxRetries--)
+               {
+                       eError = PVRSRVWaitForValueKMAndHoldBridgeLockKM(psSyncPrim->pui32LinAddr, 1, 0xffffffff);
+
+                       if (eError != PVRSRV_ERROR_TIMEOUT)
+                       {
+                               break;
+                       }
+               }
+
+               if (eError == PVRSRV_ERROR_TIMEOUT)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXScheduleCommandAndWait: PVRSRVWaitForValueKMAndHoldBridgeLock timed out. Dump debug information."));
+                       PVRSRVPowerUnlock();
+
+                       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX,IMG_NULL);
+                       PVR_ASSERT(eError != PVRSRV_ERROR_TIMEOUT);
+                       goto _PVRSRVDebugRequest_Exit;
+               }
+       }
+
+_RGXSendCommandRaw_Exit:
+_PVRSRVSetDevicePowerStateKM_Exit:
+
+       PVRSRVPowerUnlock();
+
+_PVRSRVDebugRequest_Exit:
+_PVRSRVPowerLock_Exit:
+       return eError;
+}
+
+static
+PVRSRV_ERROR RGXScheduleCleanupCommand(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                          RGXFWIF_DM                   eDM,
+                                                                          RGXFWIF_KCCB_CMD             *psKCCBCmd,
+                                                                          IMG_UINT32                   ui32CmdSize,
+                                                                          RGXFWIF_CLEANUP_TYPE eCleanupType,
+                                                                          PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                                          IMG_BOOL                             bPDumpContinuous)
+{
+       PVRSRV_ERROR eError;
+
+       psKCCBCmd->eCmdType = RGXFWIF_KCCB_CMD_CLEANUP;
+
+       psKCCBCmd->uCmdData.sCleanupData.eCleanupType = eCleanupType;
+       psKCCBCmd->uCmdData.sCleanupData.uiSyncObjDevVAddr = SyncPrimGetFirmwareAddr(psSyncPrim);
+
+       SyncPrimSet(psSyncPrim, 0);
+
+       /*
+               Send the cleanup request to the firmware. If the resource is still busy
+               the firmware will tell us and we'll drop out with a retry.
+       */
+       eError = RGXScheduleCommand(psDevInfo,
+                                                               eDM,
+                                                               psKCCBCmd,
+                                                               ui32CmdSize,
+                                                               bPDumpContinuous);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_command;
+       }
+
+       /* Wait for sync primitive to be updated */
+#if defined(PDUMP)
+       PDUMPCOMMENT("Wait for the firmware to reply to the cleanup command");
+       SyncPrimPDumpPol(psSyncPrim,
+                                       RGXFWIF_CLEANUP_RUN,
+                                       RGXFWIF_CLEANUP_RUN,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       bPDumpContinuous ? PDUMP_FLAGS_CONTINUOUS:0);
+
+       /*
+        * The cleanup request to the firmware will tell us if a given resource is busy or not.
+        * If the RGXFWIF_CLEANUP_BUSY flag is set, this means that the resource is still in use.
+        * In this case we return a PVRSRV_ERROR_RETRY error to the client drivers and they will
+        * re-issue the cleanup request until it succeed.
+        *
+        * Since this retry mechanism doesn't work for pdumps, client drivers should ensure
+        * that cleanup requests are only submitted if the resource is unused.
+        * If this is not the case, the following poll will block infinitely, making sure
+        * the issue doesn't go unnoticed.
+        */
+       PDUMPCOMMENT("Cleanup: If this poll fails, the following resource is still in use (DM=%u, type=%u, address=0x%08x), which is incorrect in pdumps",
+                                       eDM,
+                                       psKCCBCmd->uCmdData.sCleanupData.eCleanupType,
+                                       psKCCBCmd->uCmdData.sCleanupData.uCleanupData.psContext.ui32Addr);
+       SyncPrimPDumpPol(psSyncPrim,
+                                       0,
+                                       RGXFWIF_CLEANUP_BUSY,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       bPDumpContinuous ? PDUMP_FLAGS_CONTINUOUS:0);
+#endif
+
+       {
+               RGXFWIF_CCB_CTL  *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eDM];
+               IMG_UINT32       ui32CurrentQueueLength = (psKCCBCtl->ui32WrapMask+1 +
+                                                          psKCCBCtl->ui32WriteOffset -
+                                                          psKCCBCtl->ui32ReadOffset) & psKCCBCtl->ui32WrapMask;
+               IMG_UINT32       ui32MaxRetries;
+
+               for (ui32MaxRetries = ui32CurrentQueueLength + 1;
+                        ui32MaxRetries > 0;
+                        ui32MaxRetries--)
+               {
+                       eError = PVRSRVWaitForValueKMAndHoldBridgeLockKM(psSyncPrim->pui32LinAddr, RGXFWIF_CLEANUP_RUN, RGXFWIF_CLEANUP_RUN);
+
+                       if (eError != PVRSRV_ERROR_TIMEOUT)
+                       {
+                               break;
+                       }
+               }
+
+               /*
+                       If the firmware hasn't got back to us in a timely manner
+                       then bail and let the caller retry the command.
+               */
+               if (eError == PVRSRV_ERROR_TIMEOUT)
+               {
+                       PVR_DPF((PVR_DBG_WARNING,"RGXScheduleCleanupCommand: PVRSRVWaitForValueKMAndHoldBridgeLock timed out. Dump debug information."));
+
+                       eError = PVRSRV_ERROR_RETRY;
+#if defined(DEBUG)
+                           PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX,IMG_NULL);
+#endif
+                       goto fail_poll;
+               }
+               else if (eError != PVRSRV_OK)
+               {
+                       goto fail_poll;
+               }
+       }
+
+       /*
+               If the command has was run but a resource was busy, then the request
+               will need to be retried.
+       */
+       if (*psSyncPrim->pui32LinAddr & RGXFWIF_CLEANUP_BUSY)
+       {
+               eError = PVRSRV_ERROR_RETRY;
+               goto fail_requestbusy;
+       }
+
+       return PVRSRV_OK;
+
+fail_requestbusy:
+fail_poll:
+fail_command:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+/*
+       RGXRequestCommonContextCleanUp
+*/
+PVRSRV_ERROR RGXFWRequestCommonContextCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                         PRGXFWIF_FWCOMMONCONTEXT psFWCommonContextFWAddr,
+                                                                                         PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                                                         RGXFWIF_DM eDM)
+{
+       RGXFWIF_KCCB_CMD                        sRCCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("Common ctx cleanup Request DM%d [context = 0x%08x]", eDM, psFWCommonContextFWAddr.ui32Addr);
+
+       /* Setup our command data, the cleanup call will fill in the rest */
+       sRCCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psContext = psFWCommonContextFWAddr;
+
+       /* Request cleanup of the firmware resource */
+       eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
+                                                                          eDM,
+                                                                          &sRCCleanUpCmd,
+                                                                          sizeof(RGXFWIF_KCCB_CMD),
+                                                                          RGXFWIF_CLEANUP_FWCOMMONCONTEXT,
+                                                                          psSyncPrim,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXRequestCommonContextCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+
+/*
+ * RGXRequestHWRTDataCleanUp
+ */
+
+PVRSRV_ERROR RGXFWRequestHWRTDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                PRGXFWIF_HWRTDATA psHWRTData,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                                RGXFWIF_DM eDM)
+{
+       RGXFWIF_KCCB_CMD                        sHWRTDataCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("HW RTData cleanup Request DM%d [HWRTData = 0x%08x]", eDM, psHWRTData.ui32Addr);
+
+       sHWRTDataCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psHWRTData = psHWRTData;
+
+       eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
+                                                                          eDM,
+                                                                          &sHWRTDataCleanUpCmd,
+                                                                          sizeof(sHWRTDataCleanUpCmd),
+                                                                          RGXFWIF_CLEANUP_HWRTDATA,
+                                                                          psSync,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXRequestHWRTDataCleanUp: Failed to schedule a HWRTData cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+
+/*
+       RGXFWRequestFreeListCleanUp
+*/
+PVRSRV_ERROR RGXFWRequestFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                PRGXFWIF_FREELIST psFWFreeList,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       RGXFWIF_KCCB_CMD                        sFLCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("Free list cleanup Request [FreeList = 0x%08x]", psFWFreeList.ui32Addr);
+
+       /* Setup our command data, the cleanup call will fill in the rest */
+       sFLCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psFreelist = psFWFreeList;
+
+       /* Request cleanup of the firmware resource */
+       eError = RGXScheduleCleanupCommand(psDevInfo,
+                                                                          RGXFWIF_DM_GP,
+                                                                          &sFLCleanUpCmd,
+                                                                          sizeof(RGXFWIF_KCCB_CMD),
+                                                                          RGXFWIF_CLEANUP_FREELIST,
+                                                                          psSync,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestFreeListCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+
+/*
+       RGXFWRequestZSBufferCleanUp
+*/
+PVRSRV_ERROR RGXFWRequestZSBufferCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                PRGXFWIF_ZSBUFFER psFWZSBuffer,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       RGXFWIF_KCCB_CMD                        sZSBufferCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("ZS Buffer cleanup Request [ZS Buffer = 0x%08x]", psFWZSBuffer.ui32Addr);
+
+       /* Setup our command data, the cleanup call will fill in the rest */
+       sZSBufferCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psZSBuffer = psFWZSBuffer;
+
+       /* Request cleanup of the firmware resource */
+       eError = RGXScheduleCleanupCommand(psDevInfo,
+                                                                          RGXFWIF_DM_3D,
+                                                                          &sZSBufferCleanUpCmd,
+                                                                          sizeof(RGXFWIF_KCCB_CMD),
+                                                                          RGXFWIF_CLEANUP_ZSBUFFER,
+                                                                          psSync,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestZSBufferCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+PVRSRV_ERROR RGXFWRequestRayFrameDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                        PRGXFWIF_RAY_FRAME_DATA psHWFrameData,
+                                                                                        PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                                        RGXFWIF_DM eDM)
+{
+       RGXFWIF_KCCB_CMD                        sHWFrameDataCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("HW FrameData cleanup Request DM%d [HWFrameData = 0x%08x]", eDM, psHWFrameData.ui32Addr);
+
+       sHWFrameDataCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psHWFrameData = psHWFrameData;
+
+       eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
+                                                                          eDM,
+                                                                          &sHWFrameDataCleanUpCmd,
+                                                                          sizeof(sHWFrameDataCleanUpCmd),
+                                                                          RGXFWIF_CLEANUP_HWFRAMEDATA,
+                                                                          psSync,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestRayFrameDataCleanUp: Failed to schedule a HWFrameData cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+
+/*
+       RGXFWRequestRPMFreeListCleanUp
+*/
+PVRSRV_ERROR RGXFWRequestRPMFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                       PRGXFWIF_RPM_FREELIST psFWRPMFreeList,
+                                                                                       PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       RGXFWIF_KCCB_CMD                        sFLCleanUpCmd = {0};
+       PVRSRV_ERROR                            eError;
+
+       PDUMPCOMMENT("RPM Free list cleanup Request [RPM FreeList = 0x%08x]", psFWRPMFreeList.ui32Addr);
+
+       /* Setup our command data, the cleanup call will fill in the rest */
+       sFLCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psRPMFreelist = psFWRPMFreeList;
+
+       /* Request cleanup of the firmware resource */
+       eError = RGXScheduleCleanupCommand(psDevInfo,
+                                                                          RGXFWIF_DM_GP,
+                                                                          &sFLCleanUpCmd,
+                                                                          sizeof(RGXFWIF_KCCB_CMD),
+                                                                          RGXFWIF_CLEANUP_RPM_FREELIST,
+                                                                          psSync,
+                                                                          IMG_FALSE);
+
+       if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestRPMFreeListCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
+       }
+
+       return eError;
+}
+#endif
+
+PVRSRV_ERROR ContextSetPriority(RGX_SERVER_COMMON_CONTEXT *psContext,
+                                                               CONNECTION_DATA *psConnection,
+                                                               PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               IMG_UINT32 ui32Priority,
+                                                               RGXFWIF_DM eDM)
+{
+       IMG_UINT32                              ui32CmdSize;
+       IMG_UINT8                               *pui8CmdPtr;
+       RGXFWIF_KCCB_CMD                sPriorityCmd;
+       RGXFWIF_CCB_CMD_HEADER  *psCmdHeader;   
+       RGXFWIF_CMD_PRIORITY    *psCmd;
+       IMG_UINT32                              ui32BeforeWOff = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psContext));
+       IMG_BOOL                                bKickCMD = IMG_TRUE;
+       PVRSRV_ERROR                    eError;
+
+       /*
+               Get space for command
+       */
+       ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CCB_CMD_HEADER) + sizeof(RGXFWIF_CMD_PRIORITY));
+
+       eError = RGXAcquireCCB(FWCommonContextGetClientCCB(psContext),
+                                                  ui32CmdSize,
+                                                  (IMG_PVOID *) &pui8CmdPtr,
+                                                  IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               if (ui32BeforeWOff != RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psContext)))
+               {
+                       bKickCMD = IMG_FALSE;
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire client CCB", __FUNCTION__));
+                       goto fail_ccbacquire;
+               }
+       }
+
+       if (bKickCMD)
+       {
+               /*
+                       Write the command header and command
+               */
+               psCmdHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
+               psCmdHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PRIORITY;
+               psCmdHeader->ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CMD_PRIORITY));
+               pui8CmdPtr += sizeof(*psCmdHeader);
+               
+               psCmd = (RGXFWIF_CMD_PRIORITY *) pui8CmdPtr;
+               psCmd->ui32Priority = ui32Priority;
+               pui8CmdPtr += sizeof(*psCmd);
+       }
+
+       /*
+               We should reserved space in the kernel CCB here and fill in the command
+               directly.
+               This is so if there isn't space in the kernel CCB we can return with
+               retry back to services client before we take any operations
+       */
+
+       if (bKickCMD)
+       {
+               /*
+                       Submit the command
+               */
+               RGXReleaseCCB(FWCommonContextGetClientCCB(psContext),
+                                         ui32CmdSize,
+                                         IMG_TRUE);
+       
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to release space in client CCB", __FUNCTION__));
+                       return eError;
+               }
+       }
+
+       /* Construct the priority command. */
+       sPriorityCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+       sPriorityCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psContext);
+       sPriorityCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psContext));
+       sPriorityCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError = RGXScheduleCommand(psDevInfo,
+                                                                       eDM,
+                                                                       &sPriorityCmd,
+                                                                       sizeof(sPriorityCmd),
+                                                                       IMG_TRUE);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFlushComputeDataKM: Failed to schedule SLC flush command with error (%u)", eError));
+       }
+
+       return PVRSRV_OK;
+
+fail_ccbacquire:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*
+       RGXReadMETAAddr
+*/
+PVRSRV_ERROR RGXReadMETAAddr(PVRSRV_RGXDEV_INFO        *psDevInfo, IMG_UINT32 ui32METAAddr, IMG_UINT32 *pui32Value)
+{
+       IMG_UINT8 *pui8RegBase = (IMG_UINT8*)psDevInfo->pvRegsBaseKM;
+       IMG_UINT32 ui32Value;
+
+       /* Wait for Slave Port to be Ready */
+       if (PVRSRVPollForValueKM(
+               (IMG_UINT32*) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1),
+               RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN,
+               RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN) != PVRSRV_OK)
+       {
+               return PVRSRV_ERROR_TIMEOUT;
+       }
+
+       /* Issue the Read */
+       OSWriteHWReg32(
+           psDevInfo->pvRegsBaseKM,
+           RGX_CR_META_SP_MSLVCTRL0,
+           ui32METAAddr | RGX_CR_META_SP_MSLVCTRL0_RD_EN);
+
+       /* Wait for Slave Port to be Ready: read complete */
+       if (PVRSRVPollForValueKM(
+               (IMG_UINT32*) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1),
+               RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN,
+               RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN) != PVRSRV_OK)
+       {
+               return PVRSRV_ERROR_TIMEOUT;
+       }
+
+       /* Read the value */
+       ui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVDATAX);
+
+       *pui32Value = ui32Value;
+
+       return PVRSRV_OK;
+}
+
+
+/*
+       RGXUpdateHealthStatus
+*/
+PVRSRV_ERROR RGXUpdateHealthStatus(PVRSRV_DEVICE_NODE* psDevNode,
+                                   IMG_BOOL bCheckAfterTimePassed)
+{
+       PVRSRV_DATA*                 psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_HEALTH_STATUS  eNewStatus   = PVRSRV_DEVICE_HEALTH_STATUS_OK;
+       PVRSRV_DEVICE_HEALTH_REASON  eNewReason   = PVRSRV_DEVICE_HEALTH_REASON_NONE;
+       PVRSRV_RGXDEV_INFO*  psDevInfo;
+       RGXFWIF_TRACEBUF*  psRGXFWIfTraceBufCtl;
+       IMG_UINT32  ui32DMCount, ui32ThreadCount;
+       IMG_BOOL  bKCCBCmdsWaiting;
+       
+       PVR_ASSERT(psDevNode != NULL);
+       psDevInfo = psDevNode->pvDevice;
+       psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+       
+       /* If the firmware is not initialised, there is not much point continuing! */
+       if (!psDevInfo->bFirmwareInitialised  ||  psDevInfo->pvRegsBaseKM == IMG_NULL  ||
+           psDevInfo->psDeviceNode == IMG_NULL)
+       {
+               return PVRSRV_OK;
+       }
+
+       /* If Rogue is not powered on, don't continue 
+          (there is a race condition where PVRSRVIsDevicePowered returns TRUE when the GPU is actually powering down. 
+          That's not a problem as this function does not touch the HW except for the RGXScheduleCommand function,
+          which is already powerlock safe. The worst thing that could happen is that Rogue might power back up
+          but the chances of that are very low */
+       if (!PVRSRVIsDevicePowered(psDevNode->sDevId.ui32DeviceIndex))
+       {
+               return PVRSRV_OK;
+       }
+       
+       /* If this is a quick update, then include the last current value... */
+       if (!bCheckAfterTimePassed)
+       {
+               eNewStatus = psDevNode->eHealthStatus;
+               eNewReason = psDevNode->eHealthReason;
+       }
+       
+       /*
+          Firmware thread checks...
+       */
+       for (ui32ThreadCount = 0;  ui32ThreadCount < RGXFW_THREAD_NUM;  ui32ThreadCount++)
+       {
+               if (psRGXFWIfTraceBufCtl != IMG_NULL)
+               {
+                       IMG_CHAR*  pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szInfo;
+
+                       /*
+                       Check if the FW has hit an assert...
+                       */
+                       if (*pszTraceAssertInfo != '\0')
+                       {
+                               PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Firmware thread %d has asserted: %s (%s:%d)",
+                                       ui32ThreadCount, pszTraceAssertInfo,
+                                               psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szPath,
+                                               psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.ui32LineNum));
+                               eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD;
+                               eNewReason = PVRSRV_DEVICE_HEALTH_REASON_ASSERTED;
+                               goto _RGXUpdateHealthStatus_Exit;
+                       }
+
+                       /*
+                          Check the threads to see if they are in the same poll locations as last time...
+                       */
+                       if (bCheckAfterTimePassed)
+                       {       
+                               if (psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] != 0  &&
+                                       psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] == psDevInfo->aui32CrLastPollAddr[ui32ThreadCount])
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Firmware stuck on CR poll: T%u polling %s (reg:0x%08X mask:0x%08X)",
+                                                       ui32ThreadCount,
+                                                       ((psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] & RGXFW_POLL_TYPE_SET)?("set"):("unset")), 
+                                                       psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] & ~RGXFW_POLL_TYPE_SET, 
+                                                       psRGXFWIfTraceBufCtl->aui32CrPollMask[ui32ThreadCount]));
+                                       eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD;
+                                       eNewReason = PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING;
+                                       goto _RGXUpdateHealthStatus_Exit;
+                               }
+                               psDevInfo->aui32CrLastPollAddr[ui32ThreadCount] = psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount];
+                       }
+               }
+       }
+
+       /*
+          Event Object Timeouts check...
+       */
+       if (psDevInfo->ui32GEOTimeoutsLastTime > 1  &&  psPVRSRVData->ui32GEOConsecutiveTimeouts > psDevInfo->ui32GEOTimeoutsLastTime)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Global Event Object Timeouts have risen (from %d to %d)",
+                               psDevInfo->ui32GEOTimeoutsLastTime, psPVRSRVData->ui32GEOConsecutiveTimeouts));
+               eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING;
+               eNewReason = PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS;
+       }
+       psDevInfo->ui32GEOTimeoutsLastTime = psPVRSRVData->ui32GEOConsecutiveTimeouts;
+       
+       /*
+          Check the Kernel CCB pointers are valid. If any commands were waiting last time, then check
+          that some have executed since then.
+       */
+       bKCCBCmdsWaiting = IMG_FALSE;
+       
+       for (ui32DMCount = 0; ui32DMCount < RGXFWIF_DM_MAX; ui32DMCount++)
+       {
+               RGXFWIF_CCB_CTL *psKCCBCtl = ((PVRSRV_RGXDEV_INFO*)psDevNode->pvDevice)->apsKernelCCBCtl[ui32DMCount];
+
+               if (psKCCBCtl != IMG_NULL)
+               {
+                       if (psKCCBCtl->ui32ReadOffset > psKCCBCtl->ui32WrapMask  ||
+                               psKCCBCtl->ui32WriteOffset > psKCCBCtl->ui32WrapMask)
+                       {
+                               PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: KCCB for DM%d has invalid offset (ROFF=%d WOFF=%d)",
+                                       ui32DMCount, psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset));
+                               eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD;
+                               eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT;
+                       }
+
+                       if (psKCCBCtl->ui32ReadOffset != psKCCBCtl->ui32WriteOffset)
+                       {
+                               bKCCBCmdsWaiting = IMG_TRUE;
+                       }
+               }
+       }
+
+       if (bCheckAfterTimePassed && psDevInfo->psRGXFWIfTraceBuf != IMG_NULL)
+       {
+               IMG_UINT32  ui32KCCBCmdsExecuted = psDevInfo->psRGXFWIfTraceBuf->ui32KCCBCmdsExecuted;
+               
+               if (psDevInfo->ui32KCCBCmdsExecutedLastTime == ui32KCCBCmdsExecuted)
+               {
+                       /*
+                          If something was waiting last time then the Firmware has stopped processing commands.
+                       */
+                       if (psDevInfo->bKCCBCmdsWaitingLastTime)
+                       {
+                               PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: No KCCB commands executed since check!"));
+                               eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING;
+                               eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED;
+                       }
+               
+                       /*
+                          If no commands are currently pending and nothing happened since the last poll, then
+                          schedule a dummy command to ping the firmware so we know it is alive and processing.
+                       */
+                       if (!bKCCBCmdsWaiting)
+                       {
+                               RGXFWIF_KCCB_CMD  sCmpKCCBCmd;
+                               PVRSRV_ERROR      eError;
+
+                               sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_HEALTH_CHECK;
+
+                               eError = RGXScheduleCommand(psDevNode->pvDevice,
+                                                                                       RGXFWIF_DM_GP,
+                                                                                       &sCmpKCCBCmd,
+                                                                                       sizeof(sCmpKCCBCmd),
+                                                                                       IMG_TRUE);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Cannot schedule Health Check command! (0x%x)", eError));
+                               }
+                               else
+                               {
+                                       bKCCBCmdsWaiting = IMG_TRUE;
+                               }
+                       }
+               }
+
+               psDevInfo->bKCCBCmdsWaitingLastTime     = bKCCBCmdsWaiting;
+               psDevInfo->ui32KCCBCmdsExecutedLastTime = ui32KCCBCmdsExecuted;
+       }
+
+       if (bCheckAfterTimePassed && (PVRSRV_DEVICE_HEALTH_STATUS_OK==eNewStatus))
+       {
+               /* Attempt to detect and deal with any stalled client contexts */
+               IMG_BOOL bStalledClient = IMG_FALSE;
+               if (CheckForStalledClientTransferCtxt(psDevInfo))
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Detected stalled client transfer context"));
+                       bStalledClient = IMG_TRUE;
+               }
+               if (CheckForStalledClientRenderCtxt(psDevInfo))
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Detected stalled client render context"));
+                       bStalledClient = IMG_TRUE;
+               }
+#if !defined(UNDER_WDDM)
+               if (CheckForStalledClientComputeCtxt(psDevInfo))
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Detected stalled client compute context"));
+                       bStalledClient = IMG_TRUE;
+               }
+#endif
+#if defined(RGX_FEATURE_RAY_TRACING)
+               if (CheckForStalledClientRayCtxt(psDevInfo))
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Detected stalled client raytrace context"));
+                       bStalledClient = IMG_TRUE;
+               }
+#endif
+               /* try the unblock routines only on the transition from OK to stalled */
+               if (!psDevInfo->bStalledClient && bStalledClient)
+               {
+#if defined(SUPPORT_DISPLAY_CLASS)
+                       //DCDisplayContextFlush();
+#endif
+               }
+               psDevInfo->bStalledClient = bStalledClient;
+       }
+
+       /*
+          Finished, save the new status...
+       */
+_RGXUpdateHealthStatus_Exit:
+       psDevNode->eHealthStatus = eNewStatus;
+       psDevNode->eHealthReason = eNewReason;
+
+       return PVRSRV_OK;
+} /* RGXUpdateHealthStatus */
+
+PVRSRV_ERROR CheckStalledClientCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext)
+{
+       RGX_CLIENT_CCB  *psCurrentClientCCB = psCurrentServerCommonContext->psClientCCB;
+
+       return CheckForStalledCCB(psCurrentClientCCB);
+}
+
+IMG_VOID DumpStalledFWCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext,
+                                                                       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       RGX_CLIENT_CCB  *psCurrentClientCCB = psCurrentServerCommonContext->psClientCCB;
+       PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext = psCurrentServerCommonContext->sFWCommonContextFWAddr;
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
+       DumpCCB(sFWCommonContext, psCurrentClientCCB, pfnDumpDebugPrintf);
+#else
+       DumpStalledCCBCommand(sFWCommonContext, psCurrentClientCCB, pfnDumpDebugPrintf);
+#endif
+}
+
+IMG_VOID AttachKickResourcesCleanupCtls(PRGXFWIF_CLEANUP_CTL *apsCleanupCtl,
+                                                                       IMG_UINT32 *pui32NumCleanupCtl,
+                                                                       RGXFWIF_DM eDM,
+                                                                       IMG_BOOL bKick,
+                                                                       RGX_RTDATA_CLEANUP_DATA        *psRTDataCleanup,
+                                                                       RGX_ZSBUFFER_DATA              *psZBuffer,
+                                                                       RGX_ZSBUFFER_DATA              *psSBuffer)
+{
+       PRGXFWIF_CLEANUP_CTL *psCleanupCtlWrite = apsCleanupCtl;
+
+       PVR_ASSERT((eDM == RGXFWIF_DM_TA) || (eDM == RGXFWIF_DM_3D));
+
+       if(bKick)
+       {
+               if(eDM == RGXFWIF_DM_TA)
+               {
+                       if(psRTDataCleanup)
+                       {
+                               PRGXFWIF_CLEANUP_CTL psCleanupCtl;
+
+                               RGXSetFirmwareAddress(&psCleanupCtl, psRTDataCleanup->psFWHWRTDataMemDesc,
+                                                                       offsetof(RGXFWIF_HWRTDATA, sTACleanupState),
+                                                               RFW_FWADDR_NOREF_FLAG);
+
+                               *(psCleanupCtlWrite++) = psCleanupCtl;
+                       }
+               }
+               else
+               {
+                       if(psRTDataCleanup)
+                       {
+                               PRGXFWIF_CLEANUP_CTL psCleanupCtl;
+
+                               RGXSetFirmwareAddress(&psCleanupCtl, psRTDataCleanup->psFWHWRTDataMemDesc,
+                                                                       offsetof(RGXFWIF_HWRTDATA, s3DCleanupState),
+                                                               RFW_FWADDR_NOREF_FLAG);
+
+                               *(psCleanupCtlWrite++) = psCleanupCtl;
+                       }
+
+                       if(psZBuffer)
+                       {
+                               (psCleanupCtlWrite++)->ui32Addr = psZBuffer->sZSBufferFWDevVAddr.ui32Addr +
+                                                               offsetof(RGXFWIF_FWZSBUFFER, sCleanupState);
+                       }
+
+                       if(psSBuffer)
+                       {
+                               (psCleanupCtlWrite++)->ui32Addr = psSBuffer->sZSBufferFWDevVAddr.ui32Addr +
+                                                               offsetof(RGXFWIF_FWZSBUFFER, sCleanupState);
+                       }
+               }
+       }
+
+       *pui32NumCleanupCtl = psCleanupCtlWrite - apsCleanupCtl;
+
+       PVR_ASSERT(*pui32NumCleanupCtl <= RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS);
+}
+
+PVRSRV_ERROR RGXResetHWRLogs(PVRSRV_DEVICE_NODE *psDevNode)
+{
+       PVRSRV_RGXDEV_INFO      *psDevInfo;
+       RGXFWIF_HWRINFOBUF      *psHWRInfoBuf;
+       RGXFWIF_TRACEBUF        *psRGXFWIfTraceBufCtl;
+       IMG_UINT32                      i;
+
+       if(psDevNode->pvDevice == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_DEVINFO;
+       }
+       psDevInfo = psDevNode->pvDevice;
+
+       psHWRInfoBuf = psDevInfo->psRGXFWIfHWRInfoBuf;
+       psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+
+       for(i = 0 ; i < RGXFWIF_DM_MAX ; i++)
+       {
+               /* Reset the HWR numbers */
+               psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[i] = 0;
+               psRGXFWIfTraceBufCtl->aui16HwrDmFalseDetectCount[i] = 0;
+               psRGXFWIfTraceBufCtl->aui16HwrDmRecoveredCount[i] = 0;
+               psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[i] = 0;
+       }
+
+       for(i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++)
+       {
+               psHWRInfoBuf->sHWRInfo[i].ui32HWRNumber = 0;
+       }
+
+       for(i = 0 ; i < RGXFW_THREAD_NUM ; i++)
+       {
+               psHWRInfoBuf->ui32FirstCrPollAddr[i] = 0;
+               psHWRInfoBuf->ui32FirstCrPollMask[i] = 0;
+       }
+
+       psHWRInfoBuf->ui32WriteIndex = 0;
+       psHWRInfoBuf->ui32DDReqCount = 0;
+
+       return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+PVRSRV_ERROR RGXPdumpDrainKCCB(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32WriteOffset, RGXFWIF_DM eKCCBType)
+{
+       RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eKCCBType];
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if (psDevInfo->abDumpedKCCBCtlAlready[eKCCBType])
+       {
+               /* exiting capture range */
+               psDevInfo->abDumpedKCCBCtlAlready[eKCCBType] = IMG_FALSE;
+
+               /* make sure previous cmd is drained in pdump in case we will 'jump' over some future cmds */
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER,
+                                      "kCCB(%p): Draining rgxfw_roff (0x%x) == woff (0x%x)",
+                                      psKCCBCtl,
+                                      ui32WriteOffset,
+                                      ui32WriteOffset);
+               eError = DevmemPDumpDevmemPol32(psDevInfo->apsKernelCCBCtlMemDesc[eKCCBType],
+                                                offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset),
+                                                ui32WriteOffset,
+                                                0xffffffff,
+                                                PDUMP_POLL_OPERATOR_EQUAL,
+                                                PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXPdumpDrainKCCB: problem pdumping POL for kCCBCtl (%d)", eError));
+               }
+       }
+       return eError;
+}
+#endif
+
+/******************************************************************************
+ End of file (rgxfwutils.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxfwutils.h
new file mode 100644 (file)
index 0000000..cd3ca75
--- /dev/null
@@ -0,0 +1,720 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX firmware utility routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX firmware utility routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXFWUTILS_H__)
+#define __RGXFWUTILS_H__
+
+#include "rgxdevice.h"
+#include "rgxccb.h"
+#include "devicemem.h"
+#include "device.h"
+#include "pvrsrv.h"
+#include "connection_server.h"
+#include "rgxta3d.h"
+
+
+
+/*
+ * Firmware-only allocation (which are initialised by the host) must be aligned to the SLC cache line size.
+ * This is because firmware-only allocations are GPU_CACHE_INCOHERENT and this causes problems
+ * if two allocations share the same cache line; e.g. the initialisation of the second allocation won't
+ * make it into the SLC cache because it has been already loaded when accessing the content of the first allocation.
+ */
+static INLINE PVRSRV_ERROR DevmemFwAllocate(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                       IMG_DEVMEM_SIZE_T uiSize,
+                                                                                       DEVMEM_FLAGS_T uiFlags,
+                                                                   IMG_PCHAR pszText,
+                                                                                       DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+       PVRSRV_ERROR eError;
+
+       PVR_DPF_ENTERED;
+
+       eError = DevmemAllocate(psDevInfo->psFirmwareHeap,
+                                                       uiSize,
+                                                       ROGUE_CACHE_LINE_SIZE,
+                                                       uiFlags,
+                                                       pszText,
+                                                       ppsMemDescPtr);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF_RETURN_RC(eError);
+       }
+
+       /*
+               We need to map it so the heap for this allocation
+               is set
+       */
+       eError = DevmemMapToDevice(*ppsMemDescPtr,
+                                                          psDevInfo->psFirmwareHeap,
+                                                          &sTmpDevVAddr);
+       PVR_DPF_RETURN_RC1(eError, *ppsMemDescPtr);
+}
+
+static INLINE PVRSRV_ERROR DevmemFwAllocateExportable(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                                         IMG_DEVMEM_SIZE_T uiSize,
+                                                                                                         DEVMEM_FLAGS_T uiFlags,
+                                                                                         IMG_PCHAR pszText,
+                                                                                                         DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice;
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+       PVRSRV_ERROR eError;
+
+       PVR_DPF_ENTERED;
+
+       eError = DevmemAllocateExportable(IMG_NULL,
+                                                                         (IMG_HANDLE) psDeviceNode,
+                                                                         uiSize,
+                                                                         64,
+                                                                         uiFlags,
+                                                                         pszText,
+                                                                         ppsMemDescPtr);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"FW DevmemAllocateExportable failed (%u)", eError));
+               PVR_DPF_RETURN_RC(eError);
+       }
+
+       /*
+               We need to map it so the heap for this allocation
+               is set
+       */
+       eError = DevmemMapToDevice(*ppsMemDescPtr,
+                                                          psDevInfo->psFirmwareHeap,
+                                                          &sTmpDevVAddr);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"FW DevmemMapToDevice failed (%u)", eError));
+       }
+       PVR_DPF_RETURN_RC1(eError, *ppsMemDescPtr);
+}
+
+static INLINE IMG_VOID DevmemFwFree(DEVMEM_MEMDESC *psMemDesc)
+{
+       PVR_DPF_ENTERED1(psMemDesc);
+
+       DevmemReleaseDevVirtAddr(psMemDesc);
+       DevmemFree(psMemDesc);
+
+       PVR_DPF_RETURN;
+}
+
+/*
+ * This function returns the value of the hardware register RGX_CR_TIMER
+ * which is a timer counting in ticks.
+ */
+
+static INLINE IMG_UINT64 RGXReadHWTimerReg(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+    IMG_UINT64  ui64Time = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TIMER);
+
+    /*
+     *  In order to avoid having to issue three 32-bit reads to detect the
+     *  lower 32-bits wrapping, the MSB of the low 32-bit word is duplicated
+     *  in the MSB of the high 32-bit word. If the wrap happens, we just read
+     *  the register again (it will not wrap again so soon).
+     */
+    if ((ui64Time ^ (ui64Time << 32)) & ~RGX_CR_TIMER_BIT31_CLRMSK)
+    {
+        ui64Time = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TIMER);
+    }
+
+    return ((ui64Time & ~RGX_CR_TIMER_VALUE_CLRMSK)    >> RGX_CR_TIMER_VALUE_SHIFT);
+}
+
+/*
+ * This FW Common Context is only mapped into kernel for initialisation and cleanup purposes.
+ * Otherwise this allocation is only used by the FW.
+ * Therefore the GPU cache doesn't need coherency,
+ * and write-combine is suffice on the CPU side (WC buffer will be flushed at the first kick)
+ */
+#define RGX_FWCOMCTX_ALLOCFLAGS        (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | \
+                                 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) | \
+                                                                PVRSRV_MEMALLOCFLAG_GPU_READABLE | \
+                                                                PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \
+                                                                PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | \
+                                                                PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+                                                                PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+                                                                PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE | \
+                                                                PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \
+                                                                PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+
+/******************************************************************************
+ * RGXSetFirmwareAddress Flags
+ *****************************************************************************/
+#define RFW_FWADDR_FLAG_NONE           (0)                     /*!< Void flag */
+#define RFW_FWADDR_NOREF_FLAG          (1U << 0)       /*!< It is safe to immediately release the reference to the pointer, 
+                                                                                                 otherwise RGXUnsetFirmwareAddress() must be call when finished. */
+
+
+PVRSRV_ERROR RGXSetupFirmware(PVRSRV_DEVICE_NODE       *psDeviceNode, 
+                                                            IMG_BOOL                           bEnableSignatureChecks,
+                                                            IMG_UINT32                 ui32SignatureChecksBufSize,
+                                                            IMG_UINT32                 ui32HWPerfFWBufSizeKB,
+                                                            IMG_UINT64                 ui64HWPerfFilter,
+                                                            IMG_UINT32                 ui32RGXFWAlignChecksSize,
+                                                            IMG_UINT32                 *pui32RGXFWAlignChecks,
+                                                            IMG_UINT32                 ui32ConfigFlags,
+                                                            IMG_UINT32                 ui32LogType,
+                                                            IMG_UINT32            ui32NumTilingCfgs,
+                                                            IMG_UINT32            *pui32BIFTilingXStrides,
+                                                            IMG_UINT32                 ui32FilterMode,
+                                                            IMG_UINT32                 ui32JonesDisableMask,
+                                                            IMG_UINT32                 ui32HWRDebugDumpLimit,
+                                                                IMG_UINT32                     ui32HWPerfCountersDataSize,
+                                                            RGXFWIF_DEV_VIRTADDR       *psRGXFWInitFWAddr,
+                                                            RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandingConf);
+
+
+
+IMG_VOID RGXFreeFirmware(PVRSRV_RGXDEV_INFO    *psDevInfo);
+
+/*************************************************************************/ /*!
+@Function       RGXSetFirmwareAddress
+
+@Description    Sets a pointer in a firmware data structure.
+
+@Input          ppDest          Address of the pointer to set
+@Input          psSrc           MemDesc describing the pointer
+@Input          ui32Flags       Any combination of  RFW_FWADDR_*_FLAG
+
+@Return                        IMG_VOID
+*/ /**************************************************************************/
+IMG_VOID RGXSetFirmwareAddress(RGXFWIF_DEV_VIRTADDR    *ppDest,
+                                                          DEVMEM_MEMDESC               *psSrc,
+                                                          IMG_UINT32                   uiOffset,
+                                                          IMG_UINT32                   ui32Flags);
+
+#if defined(RGX_FEATURE_META_DMA)
+/*************************************************************************/ /*!
+@Function       RGXSetMetaDMAAddress
+
+@Description    Fills a Firmware structure used to setup the Meta DMA with two
+                pointers to the same data, one on 40 bit and one on 32 bit
+                (pointer in the FW memory space).
+
+@Input          ppDest                 Address of the structure to set
+@Input          psSrcMemDesc   MemDesc describing the pointer
+@Input                 psSrcFWDevVAddr Firmware memory space pointer
+
+@Return                        IMG_VOID
+*/ /**************************************************************************/
+IMG_VOID RGXSetMetaDMAAddress(RGXFWIF_DMA_ADDR         *psDest,
+                                                         DEVMEM_MEMDESC                *psSrcMemDesc,
+                                                         RGXFWIF_DEV_VIRTADDR  *psSrcFWDevVAddr,
+                                                         IMG_UINT32                    uiOffset);
+#endif
+
+/*************************************************************************/ /*!
+@Function       RGXUnsetFirmwareAddress
+
+@Description    Unsets a pointer in a firmware data structure
+
+@Input          psSrc           MemDesc describing the pointer
+
+@Return                        IMG_VOID
+*/ /**************************************************************************/
+IMG_VOID RGXUnsetFirmwareAddress(DEVMEM_MEMDESC                        *psSrc);
+
+/*************************************************************************/ /*!
+@Function       FWCommonContextAllocate
+
+@Description    Allocate a FW common coontext. This allocates the HW memory
+                for the context, the CCB and wires it all together.
+
+@Input          psConnection            Connection this context is being created on
+@Input          psDeviceNode               Device node to create the FW context on
+                                        (must be RGX device node)
+@Input          pszContextName          Name of the context
+@Input          psAllocatedMemDesc      Pointer to pre-allocated MemDesc to use
+                                        as the FW context or NULL if this function
+                                        should allocate it
+@Input          ui32AllocatedOffset     Offset into pre-allocate MemDesc to use
+                                        as the FW context. If psAllocatedMemDesc
+                                        is NULL then this parameter is ignored
+@Input          psFWMemContextMemDesc   MemDesc of the FW memory context this
+                                        common context resides on
+@Input          psContextStateMemDesc   FW context state (context switch) MemDesc
+@Input          ui32CCBAllocSize        Size of the CCB for this context
+@Input          ui32Priority            Priority of the context
+@Input          psInfo                  Structure that contains extra info
+                                        required for the creation of the context
+                                        (elements might change from core to core)
+@Return                        PVRSRV_OK if the context was successfully created
+*/ /**************************************************************************/
+PVRSRV_ERROR FWCommonContextAllocate(CONNECTION_DATA *psConnection,
+                                                                        PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                        const IMG_CHAR *pszContextName,
+                                                                        DEVMEM_MEMDESC *psAllocatedMemDesc,
+                                                                        IMG_UINT32 ui32AllocatedOffset,
+                                                                        DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                                        DEVMEM_MEMDESC *psContextStateMemDesc,
+                                                                        IMG_UINT32 ui32CCBAllocSize,
+                                                                        IMG_UINT32 ui32Priority,
+                                                                        RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                                        RGX_SERVER_COMMON_CONTEXT **ppsServerCommonContext);
+
+                                                                        
+
+IMG_VOID FWCommonContextFree(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext);
+
+PRGXFWIF_FWCOMMONCONTEXT FWCommonContextGetFWAddress(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext);
+
+RGX_CLIENT_CCB *FWCommonContextGetClientCCB(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext);
+
+RGXFWIF_CONTEXT_RESET_REASON FWCommonContextGetLastResetReason(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext);
+
+PVRSRV_ERROR RGXStartFirmware(PVRSRV_RGXDEV_INFO       *psDevInfo);
+
+/*!
+******************************************************************************
+
+ @Function     RGXScheduleProcessQueuesKM
+
+ @Description - Software command complete handler
+                               (sends uncounted kicks for all the DMs through the MISR)
+
+ @Input hCmdCompHandle - RGX device node
+
+******************************************************************************/
+IMG_IMPORT
+IMG_VOID RGXScheduleProcessQueuesKM(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle);
+
+/*!
+******************************************************************************
+
+ @Function     RGXInstallProcessQueuesMISR
+
+ @Description - Installs the MISR to handle Process Queues operations
+
+ @Input phMISR - Pointer to the MISR handler
+
+ @Input psDeviceNode - RGX Device node
+
+******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR RGXInstallProcessQueuesMISR(IMG_HANDLE *phMISR, PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/*************************************************************************/ /*!
+@Function       RGXSendCommandWithPowLock
+
+@Description    Sends a command to a particular DM without honouring
+                               pending cache operations but taking the power lock.
+
+@Input          psDevInfo                      Device Info
+@Input          eDM                                    To which DM the cmd is sent.
+@Input          psKCCBCmd                      The cmd to send.
+@Input          ui32CmdSize                    The cmd size.
+@Input          bPDumpContinuous
+
+@Return                        PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR RGXSendCommandWithPowLock(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                               RGXFWIF_DM                      eKCCBType,
+                                                                               RGXFWIF_KCCB_CMD        *psKCCBCmd,
+                                                                               IMG_UINT32                      ui32CmdSize,
+                                                                               IMG_BOOL                        bPDumpContinuous);
+
+/*************************************************************************/ /*!
+@Function       RGXSendCommandRaw
+
+@Description    Sends a command to a particular DM without honouring
+                               pending cache operations or the power lock.
+
+@Input          psDevInfo                      Device Info
+@Input          eDM                                    To which DM the cmd is sent.
+@Input          psKCCBCmd                      The cmd to send.
+@Input          ui32CmdSize                    The cmd size.
+@Input          bPDumpContinuous
+
+@Return                        PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR RGXSendCommandRaw(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                RGXFWIF_DM                     eKCCBType,
+                                                                RGXFWIF_KCCB_CMD       *psKCCBCmd,
+                                                                IMG_UINT32                     ui32CmdSize,
+                                                                PDUMP_FLAGS_T          uiPdumpFlags);
+
+
+/*************************************************************************/ /*!
+@Function       RGXScheduleCommand
+
+@Description    Sends a command to a particular DM
+
+@Input          psDevInfo                      Device Info
+@Input          eDM                                    To which DM the cmd is sent.
+@Input          psKCCBCmd                      The cmd to send.
+@Input          ui32CmdSize                    The cmd size.
+@Input          bPDumpContinuous
+
+@Return                        PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR RGXScheduleCommand(PVRSRV_RGXDEV_INFO     *psDevInfo,
+                                                               RGXFWIF_DM                      eKCCBType,
+                                                               RGXFWIF_KCCB_CMD        *psKCCBCmd,
+                                                               IMG_UINT32                      ui32CmdSize,
+                                                               IMG_BOOL                        bPDumpContinuous);
+
+/*************************************************************************/ /*!
+@Function       RGXScheduleCommandAndWait
+
+@Description    Schedules the command with RGXScheduleCommand and then waits 
+                               for the FW to update a sync. The sync must be piggy backed on
+                               the cmd, either by passing a sync cmd or a cmd that contains the
+                               sync which the FW will eventually update. The sync is created in
+                               the function, therefore the function provides a FWAddr and 
+                               UpdateValue for that cmd.
+
+@Input          psDevInfo                      Device Info
+@Input          eDM                                    To which DM the cmd is sent.
+@Input          psKCCBCmd                      The cmd to send.
+@Input          ui32CmdSize                    The cmd size.
+@Input          puiSyncObjFWAddr       Pointer to the location with the FWAddr of 
+                                                                       the sync.
+@Input          puiUpdateValue         Pointer to the location with the update 
+                                                                       value of the sync.
+@Input          bPDumpContinuous
+
+@Return                        PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR RGXScheduleCommandAndWait(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                          RGXFWIF_DM                   eDM,
+                                                                          RGXFWIF_KCCB_CMD             *psKCCBCmd,
+                                                                          IMG_UINT32                   ui32CmdSize,
+                                                                          IMG_UINT32                   *puiSyncObjDevVAddr,
+                                                                          IMG_UINT32                   *puiUpdateValue,
+                                                                          PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                                          IMG_BOOL                             bPDumpContinuous);
+
+PVRSRV_ERROR RGXFirmwareUnittests(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+
+/*! ***********************************************************************//**
+@brief          Copy framework command into FW addressable buffer
+
+@param          psFWFrameworkMemDesc
+@param          pbyGPUFRegisterList
+@param          ui32FrameworkRegisterSize
+
+@returns        PVRSRV_ERROR 
+*/ /**************************************************************************/
+PVRSRV_ERROR PVRSRVRGXFrameworkCopyCommand(DEVMEM_MEMDESC      *psFWFrameworkMemDesc,
+                                                                                  IMG_PBYTE            pbyGPUFRegisterList,
+                                                                                  IMG_UINT32           ui32FrameworkRegisterSize);
+
+
+/*! ***********************************************************************//**
+@brief          Create FW addressable buffer for framework
+
+@param          psDeviceNode
+@param          ppsFWFrameworkMemDesc
+@param          ui32FrameworkRegisterSize
+
+@returns        PVRSRV_ERROR 
+*/ /**************************************************************************/
+PVRSRV_ERROR PVRSRVRGXFrameworkCreateKM(PVRSRV_DEVICE_NODE * psDeviceNode,
+                                                                               DEVMEM_MEMDESC     ** ppsFWFrameworkMemDesc,
+                                                                               IMG_UINT32         ui32FrameworkRegisterSize);
+
+/*************************************************************************/ /*!
+@Function       RGXWaitForFWOp
+
+@Description    Send a sync command and wait to be signaled.
+
+@Input          psDevInfo                      Device Info
+@Input          eDM                                    To which DM the cmd is sent.
+@Input          bPDumpContinuous       
+
+@Return                        IMG_VOID
+*/ /**************************************************************************/
+PVRSRV_ERROR RGXWaitForFWOp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                       RGXFWIF_DM      eDM,
+                                                                       PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                                       IMG_BOOL        bPDumpContinuous);
+
+/*!
+******************************************************************************
+
+ @Function     RGXFWRequestCommonContextCleanUp
+
+ @Description Schedules a FW common context cleanup. The firmware will doesn't
+              block waiting for the resource to become idle but rather notifies
+              the host that the resources is busy.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Input psFWContext - firmware address of the context to be cleaned up
+
+ @Input eDM - Data master, to which the cleanup command should be send
+
+******************************************************************************/
+PVRSRV_ERROR RGXFWRequestCommonContextCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                         PRGXFWIF_FWCOMMONCONTEXT psFWContext,
+                                                                                         PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
+                                                                                         RGXFWIF_DM eDM);
+
+/*!
+******************************************************************************
+
+ @Function     RGXFWRequestHWRTDataCleanUp
+
+ @Description Schedules a FW HWRTData memory cleanup. The firmware will doesn't
+              block waiting for the resource to become idle but rather notifies
+              the host that the resources is busy.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Input psHWRTData - firmware address of the HWRTData to be cleaned up
+
+ @Input eDM - Data master, to which the cleanup command should be send
+
+ ******************************************************************************/
+PVRSRV_ERROR RGXFWRequestHWRTDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                PRGXFWIF_HWRTDATA psHWRTData,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                                RGXFWIF_DM eDM);
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+
+PVRSRV_ERROR RGXFWRequestRayFrameDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                        PRGXFWIF_RAY_FRAME_DATA psHWFrameData,
+                                                                                        PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                                        RGXFWIF_DM eDM);
+
+/*!
+******************************************************************************
+
+ @Function     RGXFWRequestRPMFreeListCleanUp
+
+ @Description Schedules a FW RPM FreeList cleanup. The firmware will doesn't block
+              waiting for the resource to become idle but rather notifies the
+              host that the resources is busy.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Input psFWRPMFreeList - firmware address of the RPM freelist to be cleaned up
+
+ @Input psSync - Sync object associated with cleanup
+
+ ******************************************************************************/
+PVRSRV_ERROR RGXFWRequestRPMFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                       PRGXFWIF_RPM_FREELIST psFWRPMFreeList,
+                                                                                       PVRSRV_CLIENT_SYNC_PRIM *psSync);
+#endif
+
+/*!
+******************************************************************************
+
+ @Function     RGXFWRequestFreeListCleanUp
+
+ @Description Schedules a FW FreeList cleanup. The firmware will doesn't block
+              waiting for the resource to become idle but rather notifies the
+              host that the resources is busy.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Input psHWRTData - firmware address of the HWRTData to be cleaned up
+
+ @Input eDM - Data master, to which the cleanup command should be send
+
+ ******************************************************************************/
+PVRSRV_ERROR RGXFWRequestFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDeviceNode,
+                                                                                PRGXFWIF_FREELIST psFWFreeList,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+/*!
+******************************************************************************
+
+ @Function     RGXFWRequestZSBufferCleanUp
+
+ @Description Schedules a FW ZS Buffer cleanup. The firmware will doesn't block
+              waiting for the resource to become idle but rather notifies the
+              host that the resources is busy.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Input psFWZSBuffer - firmware address of the ZS Buffer to be cleaned up
+
+ @Input eDM - Data master, to which the cleanup command should be send
+
+ ******************************************************************************/
+
+PVRSRV_ERROR RGXFWRequestZSBufferCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                PRGXFWIF_ZSBUFFER psFWZSBuffer,
+                                                                                PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+PVRSRV_ERROR ContextSetPriority(RGX_SERVER_COMMON_CONTEXT *psContext,
+                                                               CONNECTION_DATA *psConnection,
+                                                               PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               IMG_UINT32 ui32Priority,
+                                                               RGXFWIF_DM eDM);
+
+/*!
+******************************************************************************
+
+ @Function     RGXReadMETAAddr
+
+ @Description Reads a value at given address in META memory space
+              (it can be either a memory location or a META register)
+
+ @Input psDevInfo - pointer to device info
+
+ @Input ui32METAAddr - address in META memory space
+
+ @Output pui32Value - value
+
+ ******************************************************************************/
+
+PVRSRV_ERROR RGXReadMETAAddr(PVRSRV_RGXDEV_INFO        *psDevInfo,
+                             IMG_UINT32 ui32METAAddr,
+                             IMG_UINT32 *pui32Value);
+
+/*!
+******************************************************************************
+
+ @Function     RGXCheckFirmwareCCBs
+
+ @Description Processes all commands that are found in any firmware CCB.
+
+ @Input psDevInfo - pointer to device
+
+ ******************************************************************************/
+IMG_VOID RGXCheckFirmwareCCBs(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+/*!
+******************************************************************************
+
+ @Function        RGXUpdateHealthStatus
+
+ @Description  Tests a number of conditions which might indicate a fatal error has
+               occurred in the firmware. The result is stored in the device node
+               eheathStatus.
+
+ @Input        psDevNode              Pointer to device node structure.
+ @Input        bCheckAfterTimePassed  When TRUE, the function will also test for
+                                      firmware queues and polls not changing
+                                      since the previous test.
+                                      
+                                      Note: if not enough time has passed since
+                                      the last call, false positives may occur.
+
+ @returns      PVRSRV_ERROR 
+ ******************************************************************************/
+PVRSRV_ERROR RGXUpdateHealthStatus(PVRSRV_DEVICE_NODE* psDevNode,
+                                   IMG_BOOL bCheckAfterTimePassed);
+
+
+PVRSRV_ERROR CheckStalledClientCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext);
+
+IMG_VOID DumpStalledFWCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext,
+                                                                       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/*!
+******************************************************************************
+
+ @Function        AttachKickResourcesCleanupCtls
+
+ @Description  Attaches the cleanup structures to a kick command so that
+               submission reference counting can be performed when the
+               firmware processes the command
+
+ @Output        apsCleanupCtl          Array of CleanupCtl structure pointers to populate.
+ @Output        pui32NumCleanupCtl     Number of CleanupCtl structure pointers written out.
+ @Input         eDM                    Which data master is the subject of the command.
+ @Input         bKick                  TRUE if the client originally wanted to kick this DM.
+ @Input         psRTDataCleanup        Optional RTData cleanup associated with the command.
+ @Input         psZBuffer              Optional ZBuffer associated with the command.
+ @Input         psSBuffer              Optional SBuffer associated with the command.
+ ******************************************************************************/
+IMG_VOID AttachKickResourcesCleanupCtls(PRGXFWIF_CLEANUP_CTL *apsCleanupCtl,
+                                                                       IMG_UINT32 *pui32NumCleanupCtl,
+                                                                       RGXFWIF_DM eDM,
+                                                                       IMG_BOOL bKick,
+                                                                       RGX_RTDATA_CLEANUP_DATA        *psRTDataCleanup,
+                                                                       RGX_ZSBUFFER_DATA              *psZBuffer,
+                                                                       RGX_ZSBUFFER_DATA              *psSBuffer);
+
+/*!
+******************************************************************************
+
+ @Function                     RGXResetHWRLogs
+
+ @Description          Resets the HWR Logs buffer (the hardware recovery count is not reset)
+
+ @Input                        psDevInfo       Pointer to the device
+
+ @Return                       PVRSRV_ERROR    PVRSRV_OK on success. Otherwise, a PVRSRV_
+                                       error code
+ ******************************************************************************/
+PVRSRV_ERROR RGXResetHWRLogs(PVRSRV_DEVICE_NODE *psDevNode);
+
+
+#if defined(PDUMP)
+/*!
+******************************************************************************
+
+ @Function                      RGXPdumpDrainKCCB
+
+ @Description                   Wait for the firmware to execute all the commands in the kCCB
+
+ @Input                         psDevInfo      Pointer to the device
+
+ @Input                         ui32WriteOffset          Woff we have to POL for the Roff to be equal to
+
+ @Input                         eKCCBType        Data Master of the KCCB
+
+ @Return                        PVRSRV_ERROR   PVRSRV_OK on success. Otherwise, an
+                                                error code
+ ******************************************************************************/
+PVRSRV_ERROR RGXPdumpDrainKCCB(PVRSRV_RGXDEV_INFO *psDevInfo,
+                               IMG_UINT32 ui32WriteOffset,
+                               RGXFWIF_DM eKCCBType);
+#endif /* PDUMP */
+
+
+#endif /* __RGXFWUTILS_H__ */
+/******************************************************************************
+ End of file (rgxfwutils.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxheapconfig.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxheapconfig.h
new file mode 100644 (file)
index 0000000..f29f999
--- /dev/null
@@ -0,0 +1,181 @@
+/*************************************************************************/ /*!
+@File
+@Title          device configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Memory heaps device specific configuration
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+//#warning FIXME:  add the MMU specialisation defines here (or in hwdefs, perhaps?)
+
+#ifndef __RGXHEAPCONFIG_H__
+#define __RGXHEAPCONFIG_H__
+
+#include "rgxdefs_km.h"
+
+#define DEV_DEVICE_TYPE                        PVRSRV_DEVICE_TYPE_RGX
+#define DEV_DEVICE_CLASS               PVRSRV_DEVICE_CLASS_3D
+
+#define DEV_MAJOR_VERSION              1
+#define DEV_MINOR_VERSION              0
+
+/*      
+       RGX Device Virtual Address Space Definitions:
+
+       Notes:
+       Base addresses have to be a multiple of 4MiB
+       
+       RGX_PDSCODEDATA_HEAP_BASE and RGX_USCCODE_HEAP_BASE will be programmed, on a
+       global basis, into RGX_CR_PDS_EXEC_BASE and RGX_CR_USC_CODE_BASE_*
+       respectively.
+       Therefore if clients use multiple configs they must still be consistent with
+       their definitions for these heaps.
+*/
+
+#if RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS == 40
+
+       /* Start at 128 Kb. Size of 256 Mb */
+//     #define RGX_3DPARAMETERS_HEAP_BASE                      IMG_UINT64_C(0x0000020000)
+//  #define RGX_3DPARAMETERS_HEAP_SIZE                 IMG_UINT64_C(0x0010000000)
+
+       /* Start at 4GiB. Size of 512 GiB */
+       #define RGX_GENERAL_HEAP_BASE                           IMG_UINT64_C(0x0100000000)
+    #define RGX_GENERAL_HEAP_SIZE                              IMG_UINT64_C(0x8000000000)
+
+       /* start at 516 GiB. Size of 32 GiB */
+       #define RGX_BIF_TILING_NUM_HEAPS            4
+       #define RGX_BIF_TILING_HEAP_SIZE            IMG_UINT64_C(0x0200000000)
+       #define RGX_BIF_TILING_HEAP_1_BASE          IMG_UINT64_C(0x8100000000)
+       #define RGX_BIF_TILING_HEAP_2_BASE          (RGX_BIF_TILING_HEAP_1_BASE + RGX_BIF_TILING_HEAP_SIZE)
+       #define RGX_BIF_TILING_HEAP_3_BASE          (RGX_BIF_TILING_HEAP_2_BASE + RGX_BIF_TILING_HEAP_SIZE)
+       #define RGX_BIF_TILING_HEAP_4_BASE          (RGX_BIF_TILING_HEAP_3_BASE + RGX_BIF_TILING_HEAP_SIZE)
+
+       /* Start at 600GiB. Size of 4 GiB */
+       #define RGX_PDSCODEDATA_HEAP_BASE                       IMG_UINT64_C(0x9600000000)
+    #define RGX_PDSCODEDATA_HEAP_SIZE                  IMG_UINT64_C(0x0100000000)
+       /* Start at 800GiB. Size of 4 GiB */
+       #define RGX_USCCODE_HEAP_BASE                           IMG_UINT64_C(0xC800000000)
+    #define RGX_USCCODE_HEAP_SIZE                              IMG_UINT64_C(0x0100000000)
+       /* Start at 903GiB. Size of 4 GiB */
+       #define RGX_FIRMWARE_HEAP_BASE                          IMG_UINT64_C(0xE1C0000000)
+    #define RGX_FIRMWARE_HEAP_SIZE                             IMG_UINT64_C(0x0100000000)
+
+       /* Start at 912GiB. Size of 16 GiB. 16GB aligned to match RGX_CR_ISP_PIXEL_BASE */
+    #define RGX_TQ3DPARAMETERS_HEAP_BASE               IMG_UINT64_C(0xE400000000)
+    #define RGX_TQ3DPARAMETERS_HEAP_SIZE               IMG_UINT64_C(0x0400000000)
+
+       /* Size of 16 * 4 KB (think about large page systems .. */
+#if defined(FIX_HW_BRN_37200)
+    #define RGX_HWBRN37200_HEAP_BASE                           IMG_UINT64_C(0xFFFFF00000)
+    #define RGX_HWBRN37200_HEAP_SIZE                           IMG_UINT64_C(0x0000100000)
+#endif
+
+       /* Start at 928GiB. Size of 4 GiB */
+       #define RGX_DOPPLER_HEAP_BASE                           IMG_UINT64_C(0xE800000000)
+       #define RGX_DOPPLER_HEAP_SIZE                           IMG_UINT64_C(0x0100000000)
+
+       /* Start at 932GiB. Size of 4 GiB */
+       #define RGX_DOPPLER_OVERFLOW_HEAP_BASE          IMG_UINT64_C(0xE900000000)
+       #define RGX_DOPPLER_OVERFLOW_HEAP_SIZE          IMG_UINT64_C(0x0100000000)
+       
+       /* signal we've identified the core by the build */
+       #define RGX_CORE_IDENTIFIED
+#endif /* RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS == 40 */
+
+#if !defined(RGX_CORE_IDENTIFIED)
+       #error "rgxheapconfig.h: ERROR: unspecified RGX Core version"
+#endif
+
+/* /\********************************************************************************* */
+/*  * */
+/*  * Heap overlap check */
+/*  * */
+/*  ********************************************************************************\/ */
+/* #if defined(SUPPORT_RGX_GENERAL_MAPPING_HEAP) */
+/*     #if ((RGX_GENERAL_MAPPING_HEAP_BASE + RGX_GENERAL_MAPPING_HEAP_SIZE) >= RGX_GENERAL_HEAP_BASE) */
+/*             #error "rgxheapconfig.h: ERROR: RGX_GENERAL_MAPPING_HEAP overlaps RGX_GENERAL_HEAP" */
+/*     #endif */
+/* #endif */
+
+/* #if ((RGX_GENERAL_HEAP_BASE + RGX_GENERAL_HEAP_SIZE) >= RGX_3DPARAMETERS_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_GENERAL_HEAP overlaps RGX_3DPARAMETERS_HEAP" */
+/* #endif */
+
+/* #if ((RGX_3DPARAMETERS_HEAP_BASE + RGX_3DPARAMETERS_HEAP_SIZE) >= RGX_TADATA_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_3DPARAMETERS_HEAP overlaps RGX_TADATA_HEAP" */
+/* #endif */
+
+/* #if ((RGX_TADATA_HEAP_BASE + RGX_TADATA_HEAP_SIZE) >= RGX_SYNCINFO_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_TADATA_HEAP overlaps RGX_SYNCINFO_HEAP" */
+/* #endif */
+
+/* #if ((RGX_SYNCINFO_HEAP_BASE + RGX_SYNCINFO_HEAP_SIZE) >= RGX_PDSPIXEL_CODEDATA_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_SYNCINFO_HEAP overlaps RGX_PDSPIXEL_CODEDATA_HEAP" */
+/* #endif */
+
+/* #if ((RGX_PDSPIXEL_CODEDATA_HEAP_BASE + RGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= RGX_KERNEL_CODE_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_PDSPIXEL_CODEDATA_HEAP overlaps RGX_KERNEL_CODE_HEAP" */
+/* #endif */
+
+/* #if ((RGX_KERNEL_CODE_HEAP_BASE + RGX_KERNEL_CODE_HEAP_SIZE) >= RGX_PDSVERTEX_CODEDATA_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_KERNEL_CODE_HEAP overlaps RGX_PDSVERTEX_CODEDATA_HEAP" */
+/* #endif */
+
+/* #if ((RGX_PDSVERTEX_CODEDATA_HEAP_BASE + RGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= RGX_KERNEL_DATA_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_PDSVERTEX_CODEDATA_HEAP overlaps RGX_KERNEL_DATA_HEAP" */
+/* #endif */
+
+/* #if ((RGX_KERNEL_DATA_HEAP_BASE + RGX_KERNEL_DATA_HEAP_SIZE) >= RGX_PIXELSHADER_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_KERNEL_DATA_HEAP overlaps RGX_PIXELSHADER_HEAP" */
+/* #endif */
+
+/* #if ((RGX_PIXELSHADER_HEAP_BASE + RGX_PIXELSHADER_HEAP_SIZE) >= RGX_VERTEXSHADER_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_PIXELSHADER_HEAP overlaps RGX_VERTEXSHADER_HEAP" */
+/* #endif */
+
+/* #if ((RGX_VERTEXSHADER_HEAP_BASE + RGX_VERTEXSHADER_HEAP_SIZE) < RGX_VERTEXSHADER_HEAP_BASE) */
+/*     #error "rgxheapconfig.h: ERROR: RGX_VERTEXSHADER_HEAP_BASE size cause wraparound" */
+/* #endif */
+
+#endif /* __RGXHEAPCONFIG_H__ */
+
+/*****************************************************************************
+ End of file (rgxheapconfig.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.c
new file mode 100644 (file)
index 0000000..b87122e
--- /dev/null
@@ -0,0 +1,1760 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX HW Performance implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX HW Performance implementation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+//#define PVR_DPF_FUNCTION_TRACE_ON 1
+#undef PVR_DPF_FUNCTION_TRACE_ON
+
+#include "pvr_debug.h"
+#include "osfunc.h"
+#include "allocmem.h"
+
+#include "pvrsrv.h"
+#include "tlclient.h"
+#include "tlstream.h"
+
+#include "rgx_hwperf_km.h"
+#include "rgxhwperf.h"
+#include "rgxapi_km.h"
+#include "rgxfwutils.h"
+#include "devicemem_pdump.h"
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+#include "pvr_gputrace.h"
+#endif
+
+#define HWPERF_TL_STREAM_NAME  "hwperf"
+
+/* Defined to ensure HWPerf packets are not delayed */
+#define SUPPORT_TL_PROODUCER_CALLBACK 1
+
+
+/******************************************************************************
+ *
+ *****************************************************************************/
+
+
+/*
+       RGXHWPerfCopyDataL1toL2
+*/
+static IMG_UINT32 RGXHWPerfCopyDataL1toL2(IMG_HANDLE hHWPerfStream,
+                                                                                 IMG_BYTE   *pbFwBuffer, 
+                                                                                 IMG_UINT32 ui32BytesExp)
+{
+       IMG_BYTE         *pbL2Buffer;
+       IMG_UINT32   ui32L2BufFree;
+       IMG_UINT32   ui32BytesCopied = 0;
+       IMG_UINT32   ui32BytesExpMin = RGX_HWPERF_GET_SIZE(RGX_HWPERF_GET_PACKET(pbFwBuffer));
+       PVRSRV_ERROR eError;
+
+/* HWPERF_MISR_FUNC_DEBUG enables debug code for investigating HWPerf issues */
+#ifdef HWPERF_MISR_FUNC_DEBUG
+       static IMG_UINT32 gui32Ordinal = IMG_UINT32_MAX;
+#endif
+
+       PVR_DPF_ENTERED;
+
+#ifdef HWPERF_MISR_FUNC_DEBUG
+       PVR_DPF((PVR_DBG_VERBOSE, "EVENTS to copy from 0x%p length:%05d",
+                                                         pbFwBuffer, ui32BytesExp));
+#endif
+
+#ifdef HWPERF_MISR_FUNC_DEBUG
+       {
+               /* Check the incoming buffer of data has not lost any packets */
+               IMG_BYTE *pbFwBufferIter = pbFwBuffer;
+               IMG_BYTE *pbFwBufferEnd = pbFwBuffer+ui32BytesExp;
+               do
+               {
+                       RGX_HWPERF_V2_PACKET_HDR *asCurPos = RGX_HWPERF_GET_PACKET(pbFwBufferIter);
+                       IMG_UINT32 ui32CurOrdinal = asCurPos->ui32Ordinal;
+                       if (gui32Ordinal != IMG_UINT32_MAX)
+                       {
+                               if ((gui32Ordinal+1) != ui32CurOrdinal)
+                               {
+                                       if (gui32Ordinal < ui32CurOrdinal)
+                                       {
+                                               PVR_DPF((PVR_DBG_WARNING,
+                                                                "HWPerf [%p] packets lost (%u packets) between ordinal %u...%u",
+                                                                pbFwBufferIter,
+                                                                ui32CurOrdinal - gui32Ordinal - 1,
+                                                                gui32Ordinal,
+                                                                ui32CurOrdinal));
+                                       }
+                                       else
+                                       {
+                                               PVR_DPF((PVR_DBG_WARNING,
+                                                                "HWPerf [%p] packet ordinal out of sequence last: %u, current: %u",
+                                                                 pbFwBufferIter,
+                                                                 gui32Ordinal,
+                                                                 ui32CurOrdinal));
+                                       }
+                               }
+                       }
+                       gui32Ordinal = asCurPos->ui32Ordinal;
+                       pbFwBufferIter += RGX_HWPERF_GET_SIZE(asCurPos);
+               } while( pbFwBufferIter < pbFwBufferEnd );
+       }
+#endif
+
+       /* Try submitting all data in one TL packet. */
+       eError = TLStreamReserve2( hHWPerfStream, 
+                                                          &pbL2Buffer, 
+                                                          (IMG_SIZE_T)ui32BytesExp, ui32BytesExpMin,
+                                                          &ui32L2BufFree);
+       if ( eError == PVRSRV_OK )
+       {
+               OSMemCopy( pbL2Buffer, pbFwBuffer, (IMG_SIZE_T)ui32BytesExp );
+               eError = TLStreamCommit(hHWPerfStream, (IMG_SIZE_T)ui32BytesExp);
+               if ( eError != PVRSRV_OK )
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "TLStreamCommit() failed (%d) in %s(), unable to copy packet from L1 to L2 buffer",
+                                        eError, __func__));
+                       goto e0;
+               }
+               /* Data were successfully written */
+               ui32BytesCopied = ui32BytesExp;
+       }
+       else if (eError == PVRSRV_ERROR_STREAM_FULL)
+       {
+               /* There was not enough space for all data, copy as much as possible */
+               IMG_UINT32                sizeSum  = 0;
+               RGX_PHWPERF_V2_PACKET_HDR psCurPkt = RGX_HWPERF_GET_PACKET(pbFwBuffer);
+
+               PVR_DPF((PVR_DBG_MESSAGE, "Unable to reserve space (%d) in host buffer on first attempt, remaining free space: %d", ui32BytesExp, ui32L2BufFree));
+
+               /* Traverse the array to find how many packets will fit in the available space. */
+               while ( sizeSum < ui32BytesExp  &&
+                               sizeSum + RGX_HWPERF_GET_SIZE(psCurPkt) < ui32L2BufFree )
+               {
+                       sizeSum += RGX_HWPERF_GET_SIZE(psCurPkt);
+                       psCurPkt = RGX_HWPERF_GET_NEXT_PACKET(psCurPkt);
+               }
+
+               if ( 0 != sizeSum )
+               {
+                       eError = TLStreamReserve( hHWPerfStream, &pbL2Buffer, (IMG_SIZE_T)sizeSum);
+
+                       if ( eError == PVRSRV_OK )
+                       {
+                               OSMemCopy( pbL2Buffer, pbFwBuffer, (IMG_SIZE_T)sizeSum );
+                               eError = TLStreamCommit(hHWPerfStream, (IMG_SIZE_T)sizeSum);
+                               if ( eError != PVRSRV_OK )
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,
+                                                        "TLStreamCommit() failed (%d) in %s(), unable to copy packet from L1 to L2 buffer",
+                                                        eError, __func__));
+                                       goto e0;
+                               }
+                               /* sizeSum bytes of hwperf packets have been successfully written */
+                               ui32BytesCopied = sizeSum;
+                       }
+                       else if ( PVRSRV_ERROR_STREAM_FULL == eError )
+                       {
+                               PVR_DPF((PVR_DBG_WARNING, "Can not write HWPerf packet into host buffer, check data in case of packet loss, remaining free space: %d", ui32L2BufFree));
+                       }
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE, "Can not find space in host buffer, check data in case of packet loss, remaining free space: %d", ui32L2BufFree));
+               }
+       }
+       if ( PVRSRV_OK != eError && /*  Some other error occurred */
+            PVRSRV_ERROR_STREAM_FULL != eError ) /* Full error handled by caller, we returning the copied bytes count to caller*/
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                                "HWPerf enabled: Unexpected Error ( %d ) while copying FW buffer to TL buffer.",
+                                eError));
+       }
+
+e0:
+       /* Return the remaining packets left to be transported. */
+       PVR_DPF_RETURN_VAL(ui32BytesCopied);
+}
+
+
+static INLINE IMG_UINT32 RGXHWPerfAdvanceRIdx(
+               const IMG_UINT32 ui32BufSize,
+               const IMG_UINT32 ui32Pos,
+               const IMG_UINT32 ui32Size)
+{
+       return (  ui32Pos + ui32Size < ui32BufSize ? ui32Pos + ui32Size : 0 );
+}
+
+
+/*
+       RGXHWPerfDataStore
+*/
+static IMG_UINT32 RGXHWPerfDataStore(PVRSRV_RGXDEV_INFO        *psDevInfo)
+{
+       RGXFWIF_TRACEBUF    *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+       IMG_BYTE*           psHwPerfInfo = psDevInfo->psRGXFWIfHWPerfBuf;
+       IMG_UINT32                      ui32SrcRIdx, ui32SrcWIdx, ui32SrcWrapCount;
+       IMG_UINT32                      ui32BytesExp = 0, ui32BytesCopied = 0, ui32BytesCopiedSum = 0;
+#ifdef HWPERF_MISR_FUNC_DEBUG
+       IMG_UINT32                      ui32BytesExpSum = 0;
+#endif
+       
+       PVR_DPF_ENTERED;
+
+       /* Caller should check this member is valid before calling */
+       PVR_ASSERT(psDevInfo->hHWPerfStream);
+       
+       /* Get a copy of the current
+        *   read (first packet to read) 
+        *   write (empty location for the next write to be inserted) 
+        *   WrapCount (size in bytes of the buffer at or past end)
+        * indexes of the FW buffer */
+       ui32SrcRIdx = psRGXFWIfTraceBufCtl->ui32HWPerfRIdx;
+       ui32SrcWIdx = psRGXFWIfTraceBufCtl->ui32HWPerfWIdx;
+       OSMemoryBarrier();
+       ui32SrcWrapCount = psRGXFWIfTraceBufCtl->ui32HWPerfWrapCount;
+
+       /* Is there any data in the buffer not yet retrieved? */
+       if ( ui32SrcRIdx != ui32SrcWIdx )
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfDataStore EVENTS found srcRIdx:%d srcWIdx: %d ", ui32SrcRIdx, ui32SrcWIdx));
+
+               /* Is the write position higher than the read position? */
+               if ( ui32SrcWIdx > ui32SrcRIdx )
+               {
+                       /* Yes, buffer has not wrapped */
+                       ui32BytesExp  = ui32SrcWIdx - ui32SrcRIdx;
+#ifdef HWPERF_MISR_FUNC_DEBUG
+                       ui32BytesExpSum += ui32BytesExp;
+#endif
+                       ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo->hHWPerfStream,
+                                                                                                         psHwPerfInfo + ui32SrcRIdx,
+                                                                                                         ui32BytesExp);
+                       ui32BytesCopiedSum += ui32BytesCopied;
+
+                       /* Advance the read index and the free bytes counter by the number
+                        * of bytes transported. Items will be left in buffer if not all data
+                        * could be transported. Exit to allow buffer to drain. */
+                       psRGXFWIfTraceBufCtl->ui32HWPerfRIdx = RGXHWPerfAdvanceRIdx(
+                                       psDevInfo->ui32RGXFWIfHWPerfBufSize, ui32SrcRIdx,
+                                       ui32BytesCopied);
+               }
+               /* No, buffer has wrapped and write position is behind read position */
+               else
+               {
+                       /* Byte count equal to 
+                        *     number of bytes from read position to the end of the buffer, 
+                        *   + data in the extra space in the end of the buffer. */
+                       ui32BytesExp = ui32SrcWrapCount - ui32SrcRIdx;
+
+#ifdef HWPERF_MISR_FUNC_DEBUG
+                       ui32BytesExpSum += ui32BytesExp;
+#endif
+                       /* Attempt to transfer the packets to the TL stream buffer */
+                       ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo->hHWPerfStream,
+                                                                                                         psHwPerfInfo + ui32SrcRIdx,
+                                                                                                         ui32BytesExp);
+                       ui32BytesCopiedSum += ui32BytesCopied;
+
+                       /* Advance read index as before and Update the local copy of the
+                        * read index as it might be used in the last if branch*/
+                       ui32SrcRIdx = RGXHWPerfAdvanceRIdx(
+                                       psDevInfo->ui32RGXFWIfHWPerfBufSize, ui32SrcRIdx,
+                                       ui32BytesCopied);
+
+                       /* Update Wrap Count */
+                       if ( ui32SrcRIdx == 0)
+                       {
+                               psRGXFWIfTraceBufCtl->ui32HWPerfWrapCount = psDevInfo->ui32RGXFWIfHWPerfBufSize;
+                       }
+                       psRGXFWIfTraceBufCtl->ui32HWPerfRIdx = ui32SrcRIdx;
+                       
+                       /* If all the data in the end of the array was copied, try copying
+                        * wrapped data in the beginning of the array, assuming there is
+                        * any and the RIdx was wrapped. */
+                       if (   (ui32BytesCopied == ui32BytesExp)
+                           && (ui32SrcWIdx > 0) 
+                               && (ui32SrcRIdx == 0) )
+                       {
+                               ui32BytesExp = ui32SrcWIdx;
+#ifdef HWPERF_MISR_FUNC_DEBUG
+                               ui32BytesExpSum += ui32BytesExp;
+#endif
+                               ui32BytesCopied = RGXHWPerfCopyDataL1toL2(psDevInfo->hHWPerfStream,
+                                                                                                                 psHwPerfInfo,
+                                                                                                                 ui32BytesExp);
+                               ui32BytesCopiedSum += ui32BytesCopied;
+                               /* Advance the FW buffer read position. */
+                               psRGXFWIfTraceBufCtl->ui32HWPerfRIdx = RGXHWPerfAdvanceRIdx(
+                                               psDevInfo->ui32RGXFWIfHWPerfBufSize, ui32SrcRIdx,
+                                               ui32BytesCopied);
+                       }
+               }
+#ifdef HWPERF_MISR_FUNC_DEBUG
+               if (ui32BytesCopiedSum != ui32BytesExpSum)
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXHWPerfDataStore: FW L1 RIdx:%u. Not all bytes copied to L2: %u bytes out of %u expected", psRGXFWIfTraceBufCtl->ui32HWPerfRIdx, ui32BytesCopiedSum, ui32BytesExpSum));
+               }
+#endif
+
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfDataStore NO EVENTS to transport"));
+       }
+
+       PVR_DPF_RETURN_VAL(ui32BytesCopiedSum);
+}
+
+
+PVRSRV_ERROR RGXHWPerfDataStoreCB(PVRSRV_DEVICE_NODE *psDevInfo)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_RGXDEV_INFO* psRgxDevInfo;
+       IMG_UINT32          ui32BytesCopied;
+
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDevInfo);
+       psRgxDevInfo = psDevInfo->pvDevice;
+
+       if (psRgxDevInfo->hHWPerfStream != 0)
+       {
+               OSLockAcquire(psRgxDevInfo->hLockHWPerfStream);
+               ui32BytesCopied = RGXHWPerfDataStore(psRgxDevInfo);
+               OSLockRelease(psRgxDevInfo->hLockHWPerfStream);
+
+               if ( ui32BytesCopied )
+               {       /* Signal consumers that packets may be available to read when
+                    * running from a HW kick, not when called by client APP thread
+                        * via the transport layer CB as this can lead to stream
+                        * corruption.*/
+                       eError = TLStreamSync(psRgxDevInfo->hHWPerfStream);
+                       PVR_ASSERT(eError == PVRSRV_OK);
+               }
+        else
+        {
+            PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfDataStoreCB: Zero bytes copied from FW L1 to L2."));
+        }
+       }
+
+       PVR_DPF_RETURN_OK;
+}
+
+
+/* Not currently supported by default */
+#if defined(SUPPORT_TL_PROODUCER_CALLBACK)
+static PVRSRV_ERROR RGXHWPerfTLCB(IMG_HANDLE hStream,
+               IMG_UINT32 ui32ReqOp, IMG_UINT32* ui32Resp, IMG_VOID* pvUser)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVRSRV_RGXDEV_INFO* psRgxDevInfo = (PVRSRV_RGXDEV_INFO*)pvUser;
+
+       PVR_UNREFERENCED_PARAMETER(hStream);
+       PVR_UNREFERENCED_PARAMETER(ui32Resp);
+
+       PVR_ASSERT(psRgxDevInfo);
+
+       switch (ui32ReqOp)
+       {
+       case TL_SOURCECB_OP_CLIENT_EOS:
+               if (psRgxDevInfo->hHWPerfStream != 0)
+               {
+                       OSLockAcquire(psRgxDevInfo->hLockHWPerfStream);
+                       (void) RGXHWPerfDataStore(psRgxDevInfo);
+                       OSLockRelease(psRgxDevInfo->hLockHWPerfStream);
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return eError;
+}
+#endif
+
+
+/* References to key objects to allow kernel-side behaviour to function
+ * e.g. FTrace and KM interface to HWPerf.
+ */
+static PVRSRV_DEVICE_NODE* gpsRgxDevNode = IMG_NULL;
+static PVRSRV_RGXDEV_INFO* gpsRgxDevInfo = IMG_NULL;
+
+
+PVRSRV_ERROR RGXHWPerfInit(PVRSRV_DEVICE_NODE *psRgxDevNode, IMG_BOOL bEnable)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 ui32L2BufferSize;
+
+       PVR_DPF_ENTERED;
+
+       /* On first call at driver initialisation we get the RGX device,
+        * in later on-demand calls this parameter is optional. */
+       if (psRgxDevNode)
+       {
+               gpsRgxDevNode = psRgxDevNode;
+               gpsRgxDevInfo = psRgxDevNode->pvDevice;
+       }
+
+       /* Before proper initialisation make sure we have a valid RGX device. */
+       if (!gpsRgxDevInfo)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "HWPerf module not initialised"));
+               PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_DEVICE);
+       }
+
+       /* Initialise first in case of an error condition or if it is not enabled
+        */
+       gpsRgxDevInfo->hLockHWPerfStream = IMG_NULL;
+       gpsRgxDevInfo->hHWPerfStream = IMG_NULL;
+
+       /* Does the caller want to enable data collection resources? */
+       if (!bEnable)
+       {
+               PVR_DPF_RETURN_OK;
+       }
+
+       /* Create the HWPerf stream lock used for multiple stream writers when
+        * configured e.g. TL producer callback
+        */
+       eError = OSLockCreate(&gpsRgxDevInfo->hLockHWPerfStream, LOCK_TYPE_PASSIVE);
+       PVR_LOGR_IF_ERROR(eError, "OSLockCreate");
+
+       /* Host L2 HWPERF buffer size in bytes must be bigger than the L1 buffer
+        * accessed by the FW. The MISR may try to write one packet the size of the L1
+        * buffer in some scenarios. When logging is enabled in the MISR, it can be seen
+        * if the L2 buffer hits a full condition. The closer in size the L2 and L1 buffers
+        * are the more chance of this happening.
+        * Size chosen to allow MISR to write an L1 sized packet and for the client
+        * application/daemon to drain a L1 sized packet e.g. ~ 2xL1+64 working space.
+        * 
+        * However in the case of NO_HARDWARE the L2 buffer will not be used.
+        * By reducing the size of the L2 buffer we can support a larger L1 buffer size
+        * since on a 32-bit system, vmalloc memory is limited.
+        */
+#if defined(NO_HARDWARE)
+       ui32L2BufferSize = 0;
+#else
+       ui32L2BufferSize = gpsRgxDevInfo->ui32RGXFWIfHWPerfBufSize<<1;
+#endif
+       eError = TLStreamCreate(&gpsRgxDevInfo->hHWPerfStream, HWPERF_TL_STREAM_NAME,
+                                       ui32L2BufferSize+RGXFW_HWPERF_L1_PADDING_DEFAULT,
+                                       TL_FLAG_DROP_DATA | TL_FLAG_NO_SIGNAL_ON_COMMIT,
+#if !defined(SUPPORT_TL_PROODUCER_CALLBACK)
+                                       IMG_NULL, IMG_NULL
+#else
+                    /* Not enabled  by default */
+                                       RGXHWPerfTLCB, gpsRgxDevInfo
+#endif
+                                       );
+
+       PVR_LOGG_IF_ERROR(eError, "TLStreamCreate", e1);
+
+       PVR_DPF_RETURN_OK;
+
+e1:
+       OSLockDestroy(gpsRgxDevInfo->hLockHWPerfStream);
+       gpsRgxDevInfo->hLockHWPerfStream = IMG_NULL;
+       gpsRgxDevInfo->hHWPerfStream = IMG_NULL;
+/* e0: */
+       PVR_DPF_RETURN_RC(eError);
+}
+
+
+IMG_VOID RGXHWPerfDeinit(void)
+{
+       PVR_DPF_ENTERED;
+
+       /* Clean up the stream and lock objects if allocated
+        */
+       if (gpsRgxDevInfo && gpsRgxDevInfo->hHWPerfStream)
+       {
+               TLStreamClose(gpsRgxDevInfo->hHWPerfStream);
+               gpsRgxDevInfo->hHWPerfStream = IMG_NULL;
+       }
+       if (gpsRgxDevInfo && gpsRgxDevInfo->hLockHWPerfStream)
+       {
+               OSLockDestroy(gpsRgxDevInfo->hLockHWPerfStream);
+               gpsRgxDevInfo->hLockHWPerfStream = IMG_NULL;
+       }
+
+       /* Clear global RGX device reference
+        */
+       gpsRgxDevInfo = IMG_NULL;
+       gpsRgxDevNode = IMG_NULL;
+
+       PVR_DPF_RETURN;
+}
+
+
+/******************************************************************************
+ * RGX HW Performance Profiling Server API(s)
+ *****************************************************************************/
+/*
+       PVRSRVRGXCtrlHWPerfKM
+*/
+PVRSRV_ERROR PVRSRVRGXCtrlHWPerfKM(
+               PVRSRV_DEVICE_NODE*     psDeviceNode,
+               IMG_BOOL                        bToggle,
+               IMG_UINT64                      ui64Mask)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_RGXDEV_INFO* psDevice;
+       RGXFWIF_KCCB_CMD        sKccbCmd;
+
+       PVR_DPF_ENTERED;
+       PVR_ASSERT(psDeviceNode);
+       psDevice = psDeviceNode->pvDevice;
+
+       /* If this method is being used whether to enable or disable
+        * then the hwperf stream is likely to be needed eventually so create it,
+        * also helps unit testing.
+        * Stream allocated on demand to reduce RAM foot print on systems not
+        * needing HWPerf resources.
+        */
+       if (psDevice->hHWPerfStream == IMG_NULL)
+       {
+               eError = RGXHWPerfInit(psDeviceNode, IMG_TRUE);
+               PVR_LOGR_IF_ERROR(eError, "RGXHWPerfInit");
+       }
+
+       /* Prepare command parameters ...
+        */
+       sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CTRL_EVENTS;
+       sKccbCmd.uCmdData.sHWPerfCtrl.bToggle = bToggle;
+       sKccbCmd.uCmdData.sHWPerfCtrl.ui64Mask = ui64Mask;
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfKM parameters set, calling FW")); */
+
+       /* Ask the FW to carry out the HWPerf configuration command
+        */
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,     RGXFWIF_DM_GP, 
+                                                               &sKccbCmd, sizeof(sKccbCmd), IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGR_IF_ERROR(eError, "RGXScheduleCommand");
+       }
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfKM command scheduled for FW")); */
+
+       /* Wait for FW to complete
+        */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGR_IF_ERROR(eError, "RGXWaitForFWOp");
+       }
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfKM firmware completed")); */
+
+       /* If it was being asked to disable then don't delete the stream as the FW
+        * will continue to generate events during the disabling phase. Clean up
+        * will be done when the driver is unloaded.
+        * The increase in extra memory used by the stream would only occur on a
+        * developer system and not a production device as a user would never
+        * enable HWPerf. If this is not the case then a deferred clean system will
+        * need to be implemented.
+        */
+       /*if ((!bEnable) && (psDevice->hHWPerfStream))
+       {
+               TLStreamDestroy(psDevice->hHWPerfStream);
+               psDevice->hHWPerfStream = 0;
+       }*/
+
+#if defined(DEBUG)
+       if (bToggle)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "HWPerf events (%llx) have been TOGGLED", ui64Mask));
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_WARNING, "HWPerf mask has been SET to (%llx)", ui64Mask));
+       }
+#endif
+
+       PVR_DPF_RETURN_OK;
+}
+
+
+/*
+       PVRSRVRGXEnableHWPerfCountersKM
+*/
+PVRSRV_ERROR PVRSRVRGXConfigEnableHWPerfCountersKM(
+               PVRSRV_DEVICE_NODE*             psDeviceNode,
+               IMG_UINT32                                      ui32ArrayLen,
+               RGX_HWPERF_CONFIG_CNTBLK*       psBlockConfigs)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sKccbCmd;
+       DEVMEM_MEMDESC*         psFwBlkConfigsMemDesc;
+       RGX_HWPERF_CONFIG_CNTBLK* psFwArray;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDeviceNode);
+       PVR_ASSERT(ui32ArrayLen>0);
+       PVR_ASSERT(psBlockConfigs);
+
+       /* Fill in the command structure with the parameters needed
+        */
+       sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS;
+       sKccbCmd.uCmdData.sHWPerfCfgEnableBlks.ui32NumBlocks = ui32ArrayLen;
+
+       eError = DevmemFwAllocate(psDeviceNode->pvDevice,
+                       sizeof(RGX_HWPERF_CONFIG_CNTBLK)*ui32ArrayLen, 
+                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                                         PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                                                         PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                         PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                                         PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | 
+                                                                         PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                                         PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC,
+                       "HWPerfCountersConfigBlock",
+                       &psFwBlkConfigsMemDesc);
+       if (eError != PVRSRV_OK)
+               PVR_LOGR_IF_ERROR(eError, "DevmemFwAllocate");
+
+       RGXSetFirmwareAddress(&sKccbCmd.uCmdData.sHWPerfCfgEnableBlks.pasBlockConfigs,
+                       psFwBlkConfigsMemDesc, 0, 0);
+
+       eError = DevmemAcquireCpuVirtAddr(psFwBlkConfigsMemDesc, (IMG_VOID **)&psFwArray);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGG_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", fail1);
+       }
+
+       OSMemCopy(psFwArray, psBlockConfigs, sizeof(RGX_HWPERF_CONFIG_CNTBLK)*ui32ArrayLen);
+       DevmemPDumpLoadMem(psFwBlkConfigsMemDesc,
+                                               0,
+                                               sizeof(RGX_HWPERF_CONFIG_CNTBLK)*ui32ArrayLen,
+                                               0);
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigEnableHWPerfCountersKM parameters set, calling FW")); */
+
+       /* Ask the FW to carry out the HWPerf configuration command
+        */
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                       RGXFWIF_DM_GP, &sKccbCmd, sizeof(sKccbCmd), IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGG_IF_ERROR(eError, "RGXScheduleCommand", fail2);
+       }
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigEnableHWPerfCountersKM command scheduled for FW")); */
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGG_IF_ERROR(eError, "RGXWaitForFWOp", fail2);
+       }
+
+       /* Release temporary memory used for block configuration
+        */
+       RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc);
+       DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc);
+       DevmemFwFree(psFwBlkConfigsMemDesc);
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXConfigEnableHWPerfCountersKM firmware completed")); */
+
+       PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks configured and ENABLED",  ui32ArrayLen));
+
+       PVR_DPF_RETURN_OK;
+
+fail2:
+       DevmemReleaseCpuVirtAddr(psFwBlkConfigsMemDesc);
+fail1:
+       RGXUnsetFirmwareAddress(psFwBlkConfigsMemDesc);
+       DevmemFwFree(psFwBlkConfigsMemDesc);
+
+       PVR_DPF_RETURN_RC(eError);
+}
+
+
+/*
+       PVRSRVRGXConfigCustomCountersReadingHWPerfKM
+ */
+PVRSRV_ERROR PVRSRVRGXConfigCustomCountersKM(
+               PVRSRV_DEVICE_NODE*     psDeviceNode,
+               IMG_UINT16              ui16CustomBlockID,
+               IMG_UINT16              ui16NumCustomCounters,
+               IMG_UINT32*             pui32CustomCounterIDs)
+{
+       PVRSRV_ERROR        eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD    sKccbCmd;
+       DEVMEM_MEMDESC*     psFwSelectCntrsMemDesc = IMG_NULL;
+       IMG_UINT32*         psFwArray;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDeviceNode);
+
+       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVRGXSelectCustomCountersKM: configure block %u to read %u counters", ui16CustomBlockID, ui16NumCustomCounters));
+
+       /* Fill in the command structure with the parameters needed */
+       sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS;
+       sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.ui16NumCounters = ui16NumCustomCounters;
+       sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.ui16CustomBlock = ui16CustomBlockID;
+
+       if (ui16NumCustomCounters > 0)
+       {
+               PVR_ASSERT(pui32CustomCounterIDs);
+
+               eError = DevmemFwAllocate(psDeviceNode->pvDevice,
+                               sizeof(IMG_UINT32) * ui16NumCustomCounters,
+                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC,
+                               "HWPerfConfigCustomCounters",
+                               &psFwSelectCntrsMemDesc);
+               if (eError != PVRSRV_OK)
+                       PVR_LOGR_IF_ERROR(eError, "DevmemFwAllocate");
+
+               RGXSetFirmwareAddress(&sKccbCmd.uCmdData.sHWPerfSelectCstmCntrs.pui32CustomCounterIDs,
+                               psFwSelectCntrsMemDesc, 0, 0);
+
+               eError = DevmemAcquireCpuVirtAddr(psFwSelectCntrsMemDesc, (IMG_VOID **)&psFwArray);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_LOGG_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", fail1);
+               }
+
+               OSMemCopy(psFwArray, pui32CustomCounterIDs, sizeof(IMG_UINT32) * ui16NumCustomCounters);
+               DevmemPDumpLoadMem(psFwSelectCntrsMemDesc,
+                               0,
+                               sizeof(IMG_UINT32) * ui16NumCustomCounters,
+                               0);
+       }
+
+       /* Push in the KCCB the command to configure the custom counters block */
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                       RGXFWIF_DM_GP, &sKccbCmd, sizeof(sKccbCmd), IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGG_IF_ERROR(eError, "RGXScheduleCommand", fail2);
+       }
+       PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXSelectCustomCountersKM: Command scheduled"));
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOGG_IF_ERROR(eError, "RGXWaitForFWOp", fail2);
+       }
+       PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXSelectCustomCountersKM: FW operation completed"));
+
+       if (ui16NumCustomCounters > 0)
+       {
+               /* Release temporary memory used for block configuration */
+               RGXUnsetFirmwareAddress(psFwSelectCntrsMemDesc);
+               DevmemReleaseCpuVirtAddr(psFwSelectCntrsMemDesc);
+               DevmemFwFree(psFwSelectCntrsMemDesc);
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE, "HWPerf custom counters %u reading will be sent with the next HW events", ui16NumCustomCounters));
+
+       PVR_DPF_RETURN_OK;
+
+       fail2:
+       if (psFwSelectCntrsMemDesc) DevmemReleaseCpuVirtAddr(psFwSelectCntrsMemDesc);
+
+       fail1:
+       if (psFwSelectCntrsMemDesc) 
+       {
+               RGXUnsetFirmwareAddress(psFwSelectCntrsMemDesc);
+               DevmemFwFree(psFwSelectCntrsMemDesc);
+       }
+       
+       PVR_DPF_RETURN_RC(eError);
+}
+/*
+       PVRSRVRGXDisableHWPerfcountersKM
+*/
+PVRSRV_ERROR PVRSRVRGXCtrlHWPerfCountersKM(
+               PVRSRV_DEVICE_NODE*             psDeviceNode,
+               IMG_BOOL                                bEnable,
+           IMG_UINT32                          ui32ArrayLen,
+           IMG_UINT16*                         psBlockIDs)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sKccbCmd;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDeviceNode);
+       PVR_ASSERT(ui32ArrayLen>0);
+       PVR_ASSERT(ui32ArrayLen<=RGXFWIF_HWPERF_CTRL_BLKS_MAX);
+       PVR_ASSERT(psBlockIDs);
+
+       /* Fill in the command structure with the parameters needed
+        */
+       sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS;
+       sKccbCmd.uCmdData.sHWPerfCtrlBlks.bEnable = bEnable;
+       sKccbCmd.uCmdData.sHWPerfCtrlBlks.ui32NumBlocks = ui32ArrayLen;
+       OSMemCopy(sKccbCmd.uCmdData.sHWPerfCtrlBlks.aeBlockIDs, psBlockIDs, sizeof(IMG_UINT16)*ui32ArrayLen);
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfCountersKM parameters set, calling FW")); */
+
+       /* Ask the FW to carry out the HWPerf configuration command
+        */
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                       RGXFWIF_DM_GP, &sKccbCmd, sizeof(sKccbCmd), IMG_TRUE);
+       if (eError != PVRSRV_OK)
+               PVR_LOGR_IF_ERROR(eError, "RGXScheduleCommand");
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfCountersKM command scheduled for FW")); */
+
+       /* Wait for FW to complete */
+       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+       if (eError != PVRSRV_OK)
+               PVR_LOGR_IF_ERROR(eError, "RGXWaitForFWOp");
+
+       /* PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVRGXCtrlHWPerfCountersKM firmware completed")); */
+
+#if defined(DEBUG)
+       if (bEnable)
+               PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks have been ENABLED",  ui32ArrayLen));
+       else
+               PVR_DPF((PVR_DBG_WARNING, "HWPerf %d counter blocks have been DISABLED",  ui32ArrayLen));
+#endif
+
+       PVR_DPF_RETURN_OK;
+}
+
+
+/******************************************************************************
+ * SUPPORT_GPUTRACE_EVENTS
+ *
+ * Currently only implemented on Linux and Android. Feature can be enabled on
+ * Android builds but can also be enabled on Linux builds for testing
+ * but requires the gpu.h FTrace event header file to be present.
+ *****************************************************************************/
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+
+
+static POS_LOCK hFTraceLock;
+static IMG_VOID RGXHWPerfFTraceCmdCompleteNotify(PVRSRV_CMDCOMP_HANDLE);
+
+static PVRSRV_ERROR RGXHWPerfFTraceGPUEnable(void)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(gpsRgxDevNode && gpsRgxDevInfo);
+
+       /* In the case where the AppHint has not been set we need to
+        * initialise the host driver HWPerf resources here. Allocated on
+        * demand to reduce RAM foot print on systems not needing HWPerf.
+        * Signal FW to enable event generation.
+        */
+       if (gpsRgxDevNode->psSyncPrim)
+       {
+               eError = PVRSRVRGXCtrlHWPerfKM(gpsRgxDevNode, IMG_FALSE, RGX_HWPERF_EVENT_MASK_HW_KICKFINISH);
+               PVR_LOGG_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM", err_out);
+       }
+
+       /* Connect to the TL Stream for HWPerf data consumption */
+       eError = TLClientConnect(&gpsRgxDevInfo->hGPUTraceTLConnection);
+       PVR_LOGG_IF_ERROR(eError, "TLClientConnect", err_out);
+
+       eError = TLClientOpenStream(gpsRgxDevInfo->hGPUTraceTLConnection,
+                                                               HWPERF_TL_STREAM_NAME,
+                                                               PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING,
+                                                               &gpsRgxDevInfo->hGPUTraceTLStream);
+       PVR_LOGG_IF_ERROR(eError, "TLClientOpenStream", err_disconnect);
+
+       /* Register a notifier to collect HWPerf data whenever the HW completes
+        * an operation.
+        */
+       eError = PVRSRVRegisterCmdCompleteNotify(
+               &gpsRgxDevInfo->hGPUTraceCmdCompleteHandle,
+               &RGXHWPerfFTraceCmdCompleteNotify,
+               gpsRgxDevInfo);
+       PVR_LOGG_IF_ERROR(eError, "PVRSRVRegisterCmdCompleteNotify", err_close_stream);
+
+       /* Reset the OS timestamp coming from the timer correlation data
+        * associated with the latest HWPerf event we processed.
+        */
+       gpsRgxDevInfo->ui64LastSampledTimeCorrOSTimeStamp = 0;
+
+       gpsRgxDevInfo->bFTraceGPUEventsEnabled = IMG_TRUE;
+
+err_out:
+    PVR_DPF_RETURN_RC(eError);
+
+err_close_stream:
+       TLClientCloseStream(gpsRgxDevInfo->hGPUTraceTLConnection,
+                                               gpsRgxDevInfo->hGPUTraceTLStream);
+err_disconnect:
+       TLClientDisconnect(gpsRgxDevInfo->hGPUTraceTLConnection);
+       goto err_out;
+}
+
+static PVRSRV_ERROR RGXHWPerfFTraceGPUDisable(IMG_BOOL bDeInit)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(gpsRgxDevNode && gpsRgxDevInfo);
+
+       OSLockAcquire(hFTraceLock);
+
+       if (!bDeInit)
+       {
+               eError = PVRSRVRGXCtrlHWPerfKM(gpsRgxDevNode, IMG_FALSE, (RGX_HWPERF_EVENT_MASK_NONE));
+               PVR_LOG_IF_ERROR(eError, "PVRSRVRGXCtrlHWPerfKM");
+       }
+
+
+       if (gpsRgxDevInfo->hGPUTraceCmdCompleteHandle)
+       {
+               /* Tracing is being turned off. Unregister the notifier. */
+               eError = PVRSRVUnregisterCmdCompleteNotify(
+                               gpsRgxDevInfo->hGPUTraceCmdCompleteHandle);
+               PVR_LOG_IF_ERROR(eError, "PVRSRVUnregisterCmdCompleteNotify");
+               gpsRgxDevInfo->hGPUTraceCmdCompleteHandle = IMG_NULL;
+       }
+
+       if (gpsRgxDevInfo->hGPUTraceTLStream)
+       {
+               IMG_PBYTE pbTmp = NULL;
+               IMG_UINT32 ui32Tmp = 0;
+
+               /* We have to flush both the L1 (FW) and L2 (Host) buffers in case there
+                * are some events left unprocessed in this FTrace/systrace "session"
+                * (note that even if we have just disabled HWPerf on the FW some packets
+                * could have been generated and already copied to L2 by the MISR handler).
+                *
+                * With the following calls we will both copy new data to the Host buffer
+                * (done by the producer callback in TLClientAcquireData) and advance
+                * the read offset in the buffer to catch up with the latest events.
+                */
+               eError = TLClientAcquireData(gpsRgxDevInfo->hGPUTraceTLConnection,
+                                            gpsRgxDevInfo->hGPUTraceTLStream,
+                                            &pbTmp, &ui32Tmp);
+               PVR_LOG_IF_ERROR(eError, "TLClientCloseStream");
+
+               /* Let close stream perform the release data on the outstanding acquired data */
+               eError = TLClientCloseStream(gpsRgxDevInfo->hGPUTraceTLConnection,
+                                            gpsRgxDevInfo->hGPUTraceTLStream);
+               PVR_LOG_IF_ERROR(eError, "TLClientCloseStream");
+
+               gpsRgxDevInfo->hGPUTraceTLStream = IMG_NULL;
+       }
+
+       if (gpsRgxDevInfo->hGPUTraceTLConnection)
+       {
+               eError = TLClientDisconnect(gpsRgxDevInfo->hGPUTraceTLConnection);
+               PVR_LOG_IF_ERROR(eError, "TLClientDisconnect");
+               gpsRgxDevInfo->hGPUTraceTLConnection = IMG_NULL;
+       }
+
+       gpsRgxDevInfo->bFTraceGPUEventsEnabled = IMG_FALSE;
+
+       OSLockRelease(hFTraceLock);
+
+    PVR_DPF_RETURN_RC(eError);
+}
+
+PVRSRV_ERROR RGXHWPerfFTraceGPUEventsEnabledSet(IMG_BOOL bNewValue)
+{
+       IMG_BOOL bOldValue;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_DPF_ENTERED;
+
+       if (!gpsRgxDevInfo)
+       {
+               /* RGXHWPerfFTraceGPUInit hasn't been called yet -- it's too early
+                * to enable tracing.
+                */
+        eError = PVRSRV_ERROR_NO_DEVICEDATA_FOUND;
+        PVR_DPF_RETURN_RC(eError);
+    }
+
+       bOldValue = gpsRgxDevInfo->bFTraceGPUEventsEnabled;
+
+       if (bOldValue != bNewValue)
+       {
+               if (bNewValue)
+               {
+            eError = RGXHWPerfFTraceGPUEnable();
+               }
+               else
+               {
+            eError = RGXHWPerfFTraceGPUDisable(IMG_FALSE);
+               }
+       }
+
+    PVR_DPF_RETURN_RC(eError);
+}
+
+PVRSRV_ERROR PVRGpuTraceEnabledSet(IMG_BOOL bNewValue)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+       /* Lock down because we need to protect
+        * RGXHWPerfFTraceGPUDisable()/RGXHWPerfFTraceGPUEnable()
+        */
+       OSAcquireBridgeLock();
+    eError = RGXHWPerfFTraceGPUEventsEnabledSet(bNewValue);
+       OSReleaseBridgeLock();
+
+    PVR_DPF_RETURN_RC(eError);
+}
+
+IMG_BOOL RGXHWPerfFTraceGPUEventsEnabled(IMG_VOID)
+{
+       return(gpsRgxDevInfo->bFTraceGPUEventsEnabled);
+}
+
+IMG_BOOL PVRGpuTraceEnabled(IMG_VOID)
+{
+       return (RGXHWPerfFTraceGPUEventsEnabled());
+}
+
+IMG_VOID RGXHWPerfFTraceGPUEnqueueEvent(PVRSRV_RGXDEV_INFO *psDevInfo,
+               IMG_UINT32 ui32ExternalJobRef, IMG_UINT32 ui32InternalJobRef,
+               const IMG_CHAR* pszJobType)
+{
+       IMG_UINT32   ui32PID = OSGetCurrentProcessID();
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(pszJobType);
+
+       PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfFTraceGPUEnqueueEvent: PID %u, external jobRef %u, internal jobRef %u", ui32PID, ui32ExternalJobRef, ui32InternalJobRef));
+
+       PVRGpuTraceClientWork(ui32PID, ui32ExternalJobRef, ui32InternalJobRef, pszJobType);
+
+       PVR_DPF_RETURN;
+}
+
+
+static IMG_VOID RGXHWPerfFTraceGPUSwitchEvent(PVRSRV_RGXDEV_INFO *psDevInfo,
+               RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt, const IMG_CHAR* pszWorkName,
+               PVR_GPUTRACE_SWITCH_TYPE eSwType)
+{
+       IMG_UINT64 ui64Timestamp;
+       RGX_HWPERF_HW_DATA_FIELDS* psHWPerfPktData;
+       RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb;
+       RGXFWIF_TIME_CORR *psTimeCorr;
+       IMG_UINT32 ui32CRDeltaToOSDeltaKNs;
+       IMG_UINT64 ui64CRTimeStamp;
+       IMG_UINT64 ui64OSTimeStamp;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psHWPerfPkt);
+       PVR_ASSERT(pszWorkName);
+
+       psHWPerfPktData = (RGX_HWPERF_HW_DATA_FIELDS*) RGX_HWPERF_GET_PACKET_DATA_BYTES(psHWPerfPkt);
+
+       /* Filter out 3DFINISH events for 3DTQKICKs which have already been
+        * filtered by ValidFTraceEvent() */
+
+       /* Calculate the OS timestamp given an RGX timestamp in the HWPerf event */
+       psTimeCorr              = &psGpuUtilFWCB->sTimeCorr[psHWPerfPktData->ui32TimeCorrIndex];
+       ui64CRTimeStamp         = psTimeCorr->ui64CRTimeStamp;
+       ui64OSTimeStamp         = psTimeCorr->ui64OSTimeStamp;
+       ui32CRDeltaToOSDeltaKNs = psTimeCorr->ui32CRDeltaToOSDeltaKNs;
+
+       if(psDevInfo->ui64LastSampledTimeCorrOSTimeStamp > ui64OSTimeStamp)
+       {
+               /* The previous packet had a time reference (time correlation data) more recent
+                * than the one in the current packet, it means the timer correlation array wrapped
+                * too quickly (buffer too small) and in the previous call to RGXHWPerfFTraceGPUSwitchEvent
+                * we read one of the newest timer correlations rather than one of the oldest ones.
+                */
+               PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfFTraceGPUSwitchEvent: The timestamps computed so far could be wrong! "
+                                       "The time correlation array size should be increased to avoid this."));
+       }
+       psDevInfo->ui64LastSampledTimeCorrOSTimeStamp = ui64OSTimeStamp;
+
+       {
+               IMG_UINT64 deltaRgxTimer = psHWPerfPkt->ui64RGXTimer - ui64CRTimeStamp;  /* RGX CR timer ticks delta */
+               IMG_UINT64 delta_nS =
+                   RGXFWIF_GET_DELTA_OSTIME_NS(deltaRgxTimer, ui32CRDeltaToOSDeltaKNs); /* RGX time delta in nS */
+               ui64Timestamp = ui64OSTimeStamp + delta_nS;                              /* Calculate OS time of HWPerf event */
+
+               PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfFTraceGPUSwitchEvent: psCurrentDvfs RGX %llu, OS %llu, DVFSCLK %u",
+                        ui64CRTimeStamp, ui64OSTimeStamp, psTimeCorr->ui32CoreClockSpeed ));
+       }
+
+       PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfFTraceGPUSwitchEvent: %s ui32ExtJobRef=%d, ui32IntJobRef=%d, eSwType=%d",
+                       pszWorkName, psHWPerfPktData->ui32ExtJobRef, psHWPerfPktData->ui32IntJobRef, eSwType));
+
+       PVRGpuTraceWorkSwitch(ui64Timestamp, psHWPerfPktData->ui32PID,
+                       psHWPerfPktData->ui32ExtJobRef, psHWPerfPktData->ui32IntJobRef,
+                       pszWorkName, eSwType);
+
+       PVR_DPF_RETURN;
+}
+
+
+static IMG_BOOL ValidFTraceEvent(RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt,
+               IMG_PCHAR* ppszWorkName, PVR_GPUTRACE_SWITCH_TYPE* peSwType)
+{
+       RGX_HWPERF_EVENT_TYPE eType;
+       static const struct {
+               IMG_CHAR* pszName;
+               PVR_GPUTRACE_SWITCH_TYPE eSwType;
+       } aszEventTypeMap[] = {
+                       { /* RGX_HWPERF_HW_TAKICK */       "TA",     PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_TAFINISHED */   "TA",     PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_3DTQKICK */     "TQ3D",   PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_3DKICK */       "3D",     PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_3DFINISHED */   "3D",     PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_CDMKICK */      "CDM",    PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_CDMFINISHED */  "CDM",    PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_TLAKICK */      "TQ2D",   PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_TLAFINISHED */  "TQ2D",   PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_3DSPMKICK */    "3DSPM",  PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_PERIODIC */     IMG_NULL, 0 }, /* PERIODIC not supported */
+                       { /* RGX_HWPERF_HW_RTUKICK */      "RTU",    PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_RTUFINISHED */  "RTU",    PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_SHGKICK */      "SHG",    PVR_GPUTRACE_SWITCH_TYPE_BEGIN },
+                       { /* RGX_HWPERF_HW_SHGFINISHED */  "SHG",    PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_3DTQFINISHED */ "TQ3D",   PVR_GPUTRACE_SWITCH_TYPE_END },
+                       { /* RGX_HWPERF_HW_3DSPMFINISHED */ "3DSPM", PVR_GPUTRACE_SWITCH_TYPE_END },
+       };
+
+       PVR_ASSERT(psHWPerfPkt);
+
+       eType = RGX_HWPERF_GET_TYPE(psHWPerfPkt);
+       if ((eType < RGX_HWPERF_HW_TAKICK) || (eType > RGX_HWPERF_HW_3DSPMFINISHED))
+       {
+               /* No map entry, ignore event */
+               PVR_DPF((PVR_DBG_VERBOSE, "ValidFTraceEvent: Unsupported event type %d %02d",
+                       eType, eType+RGX_HWPERF_HW_TAKICK)); 
+               return IMG_FALSE;
+       }
+       eType-=RGX_HWPERF_HW_TAKICK;
+
+       if (aszEventTypeMap[eType].pszName == IMG_NULL)
+       {
+               /* Not supported map entry, ignore event */
+               PVR_DPF((PVR_DBG_VERBOSE, "ValidFTraceEventl: Unsupported event type %d %02d",
+                       eType, eType+RGX_HWPERF_HW_TAKICK)); 
+               return IMG_FALSE;
+       }
+
+       *ppszWorkName = aszEventTypeMap[eType].pszName;
+       *peSwType = aszEventTypeMap[eType].eSwType;
+
+       return IMG_TRUE;
+}
+
+
+static IMG_VOID RGXHWPerfFTraceGPUThreadProcessPackets(PVRSRV_RGXDEV_INFO *psDevInfo,
+               IMG_PBYTE pBuffer, IMG_UINT32 ui32ReadLen)
+{
+       IMG_UINT32                      ui32TlPackets = 0;
+       IMG_UINT32          ui32HWPerfPackets = 0;
+       IMG_UINT32          ui32HWPerfPacketsSent = 0;
+       IMG_PBYTE                       pBufferEnd;
+       PVRSRVTL_PPACKETHDR psHDRptr;
+       PVRSRVTL_PACKETTYPE ui16TlType;
+
+       PVR_DPF_ENTERED;
+
+       PVR_ASSERT(psDevInfo);
+       PVR_ASSERT(pBuffer);
+       PVR_ASSERT(ui32ReadLen);
+
+       /* Process the TL Packets
+        */
+       pBufferEnd = pBuffer+ui32ReadLen;
+       psHDRptr = GET_PACKET_HDR(pBuffer);
+       while ( psHDRptr < (PVRSRVTL_PPACKETHDR)pBufferEnd )
+       {
+               ui16TlType = GET_PACKET_TYPE(psHDRptr);
+               if (ui16TlType == PVRSRVTL_PACKETTYPE_DATA)
+               {
+                       IMG_UINT16 ui16DataLen = GET_PACKET_DATA_LEN(psHDRptr);
+                       if (0 == ui16DataLen)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfFTraceGPUThreadProcessPackets: ZERO Data in TL data packet: %p", psHDRptr));
+                       }
+                       else
+                       {
+                               RGX_HWPERF_V2_PACKET_HDR* psHWPerfPkt;
+                               RGX_HWPERF_V2_PACKET_HDR* psHWPerfEnd;
+                               IMG_CHAR* pszWorkName;
+                               PVR_GPUTRACE_SWITCH_TYPE eSwType;
+
+                               /* Check for lost hwperf data packets */
+                               psHWPerfEnd = RGX_HWPERF_GET_PACKET(GET_PACKET_DATA_PTR(psHDRptr)+ui16DataLen);
+                               psHWPerfPkt = RGX_HWPERF_GET_PACKET(GET_PACKET_DATA_PTR(psHDRptr));
+                               do
+                               {
+                                       if (ValidFTraceEvent(psHWPerfPkt, &pszWorkName, &eSwType))
+                                       {
+                                               RGXHWPerfFTraceGPUSwitchEvent(psDevInfo, psHWPerfPkt, pszWorkName, eSwType);
+                                               ui32HWPerfPacketsSent++;
+                                       }
+                                       ui32HWPerfPackets++;
+                                       psHWPerfPkt = RGX_HWPERF_GET_NEXT_PACKET(psHWPerfPkt);
+                               }
+                               while (psHWPerfPkt < psHWPerfEnd);
+                       }
+               }
+               else if (ui16TlType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfFTraceGPUThreadProcessPackets: Indication that the transport buffer was full"));
+               }
+               else
+               {
+                       /* else Ignore padding packet type and others */
+                       PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfFTraceGPUThreadProcessPackets: Ignoring TL packet, type %d", ui16TlType ));
+               }
+
+               psHDRptr = GET_NEXT_PACKET_ADDR(psHDRptr);
+               ui32TlPackets++;
+       }
+
+       PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfFTraceGPUThreadProcessPackets: TL "
+                       "Packets processed %03d, HWPerf packets %03d, sent %03d",
+                       ui32TlPackets, ui32HWPerfPackets, ui32HWPerfPacketsSent));
+
+       PVR_DPF_RETURN;
+}
+
+
+static
+IMG_VOID RGXHWPerfFTraceCmdCompleteNotify(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle)
+{
+       PVRSRV_DATA*        psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_RGXDEV_INFO* psDeviceInfo = hCmdCompHandle;
+       IMG_HANDLE                      hUnusedByTL;
+       PVRSRV_ERROR        eError;
+       IMG_HANDLE          hStream;
+       IMG_PBYTE           pBuffer;
+       IMG_UINT32          ui32ReadLen;
+
+       PVR_DPF_ENTERED;
+
+       /* Command-complete notifiers can run concurrently. If this is
+        * happening, just bail out and let the previous call finish.
+        * This is ok because we can process the queued packets on the next call.
+        */
+       if (!(OSTryLockAcquire(hFTraceLock)))
+       {
+               PVR_DPF_RETURN;
+       }
+
+       /* Exit if no HWPerf enabled device exits */
+       PVR_ASSERT(psDeviceInfo != IMG_NULL &&
+                  psPVRSRVData != IMG_NULL &&
+                  gpsRgxDevInfo != NULL);
+
+
+       hUnusedByTL = psDeviceInfo->hGPUTraceTLConnection;
+       hStream = psDeviceInfo->hGPUTraceTLStream;
+
+       if (hStream)
+       {
+               /* If we have a valid stream attempt to acquire some data */
+               eError = TLClientAcquireData(hUnusedByTL, hStream, &pBuffer, &ui32ReadLen);
+               if (eError == PVRSRV_OK)
+               {
+                       /* Process the HWPerf packets and release the data */
+                       if (ui32ReadLen > 0)
+                       {
+                               PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfFTraceGPUThread: DATA AVAILABLE offset=%p, length=%d", pBuffer, ui32ReadLen));
+
+                               /* Process the transport layer data for HWPerf packets... */
+                               RGXHWPerfFTraceGPUThreadProcessPackets (psDeviceInfo, pBuffer, ui32ReadLen);
+
+                               eError = TLClientReleaseData(hUnusedByTL, hStream);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_LOG_ERROR(eError, "TLClientReleaseData");
+
+                                       /* Serious error, disable FTrace GPU events */
+
+                                       /* Release TraceLock so we always have the locking
+                                        * order BridgeLock->TraceLock to prevent AB-BA deadlocks*/
+                                       OSLockRelease(hFTraceLock);
+                                       OSAcquireBridgeLock();
+                                       RGXHWPerfFTraceGPUDisable(IMG_FALSE);
+                                       OSReleaseBridgeLock();
+                                       goto out;
+
+                               }
+                       } /* else no data, ignore */
+               }
+               else if (eError != PVRSRV_ERROR_TIMEOUT)
+               {
+                       PVR_LOG_ERROR(eError, "TLClientAcquireData");
+               }
+       }
+
+       OSLockRelease(hFTraceLock);
+out:
+       PVR_DPF_RETURN;
+}
+
+
+PVRSRV_ERROR RGXHWPerfFTraceGPUInit(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_DPF_ENTERED;
+
+    /* Must be setup already by the general HWPerf module initialisation.
+        * DevInfo object needed by FTrace event generation code */
+       PVR_ASSERT(gpsRgxDevInfo);
+       gpsRgxDevInfo->bFTraceGPUEventsEnabled = IMG_FALSE;
+
+       eError = OSLockCreate(&hFTraceLock, LOCK_TYPE_DISPATCH);
+
+       PVR_DPF_RETURN_RC(eError);
+}
+
+
+IMG_VOID RGXHWPerfFTraceGPUDeInit(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVR_DPF_ENTERED;
+
+       if (gpsRgxDevInfo->bFTraceGPUEventsEnabled)
+       {
+               RGXHWPerfFTraceGPUDisable(IMG_TRUE);
+               gpsRgxDevInfo->bFTraceGPUEventsEnabled = IMG_FALSE;
+       }
+
+       OSLockDestroy(hFTraceLock);
+
+       PVR_DPF_RETURN;
+}
+
+
+#endif /* SUPPORT_GPUTRACE_EVENTS */
+
+
+/******************************************************************************
+ * SUPPORT_KERNEL_HWPERF
+ *
+ * Currently only implemented on Linux. Feature can be enabled on Linux builds
+ * to provide an interface to 3rd-party kernel modules that wish to access the
+ * HWPerf data. The API is documented in the rgxapi_km.h header and
+ * the rgx_hwperf* headers.
+ *****************************************************************************/
+#if defined(SUPPORT_KERNEL_HWPERF)
+
+/* Internal HWPerf kernel connection/device data object to track the state
+ * of a client session.
+ */
+typedef struct
+{
+       PVRSRV_DEVICE_NODE* psRgxDevNode;
+
+       /* TL Connect/disconnect state */
+       IMG_HANDLE          hTLConnection;
+
+       /* TL Open/close state */
+       IMG_HANDLE          hSD;
+
+       /* TL Acquire/release state */
+       IMG_PBYTE                       pHwpBuf;
+       IMG_UINT32          ui32HwpBufLen;
+
+} RGX_KM_HWPERF_DEVDATA;
+
+
+PVRSRV_ERROR RGXHWPerfConnect(
+               IMG_HANDLE* phDevData)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData;
+
+       /* Valid input argument values supplied by the caller */
+       if (!phDevData)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Clear the handle to aid error checking by caller */
+       *phDevData = IMG_NULL;
+
+       /* Check the HWPerf module is initialised before we allow a connection */
+       if (!gpsRgxDevNode || !gpsRgxDevInfo)
+       {
+               return PVRSRV_ERROR_INVALID_DEVICE;
+       }
+
+       /* In the case where the AppHint has not been set we need to
+        * initialise the host driver HWPerf resources here. Allocated on
+        * demand to reduce RAM foot print on systems not needing HWPerf.
+        */
+       if (gpsRgxDevInfo->hHWPerfStream == IMG_NULL)
+       {
+               eError = RGXHWPerfInit(IMG_NULL, IMG_TRUE);
+               PVR_LOGR_IF_ERROR(eError, "RGXHWPerfInit");
+       }
+
+       /* Allocation the session object for this connection */
+       psDevData = OSAllocZMem(sizeof(*psDevData));
+       if (psDevData == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       psDevData->psRgxDevNode = gpsRgxDevNode;
+
+
+       /* Open a TL connection and store it in the session object */
+       eError = TLClientConnect(&psDevData->hTLConnection);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       /* Open the 'hwperf' TL stream for reading in this session */
+       eError = TLClientOpenStream(psDevData->hTLConnection,
+                                           HWPERF_TL_STREAM_NAME,
+                                           PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING,
+                                           &psDevData->hSD);
+       if (eError != PVRSRV_OK)
+       {
+               goto e2;
+       }
+
+       *phDevData = psDevData;
+       return PVRSRV_OK;
+
+       /* Error path... */
+e2:
+       TLClientDisconnect(psDevData->hTLConnection);
+e1:
+       OSFREEMEM(psDevData);
+// e0:
+       return eError;
+}
+
+
+
+PVRSRV_ERROR RGXHWPerfControl(
+               IMG_HANDLE  hDevData,
+               IMG_BOOL    bToggle,
+               IMG_UINT64  ui64Mask)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+
+       /* Valid input argument values supplied by the caller */
+       if (!psDevData)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Ensure we are initialised and have a valid device node */
+       if (!psDevData->psRgxDevNode)
+       {
+               return PVRSRV_ERROR_INVALID_DEVICE;
+       }
+
+       /* Call the internal server API */
+       eError = PVRSRVRGXCtrlHWPerfKM(psDevData->psRgxDevNode, bToggle, ui64Mask);
+       return eError;
+}
+
+
+PVRSRV_ERROR RGXHWPerfConfigureAndEnableCounters(
+               IMG_HANDLE                 hDevData,
+               IMG_UINT32                 ui32NumBlocks,
+               RGX_HWPERF_CONFIG_CNTBLK*  asBlockConfigs)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+
+       /* Valid input argument values supplied by the caller */
+       if (!psDevData || ui32NumBlocks==0 || !asBlockConfigs)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       if (ui32NumBlocks > RGXFWIF_HWPERF_CTRL_BLKS_MAX)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Ensure we are initialised and have a valid device node */
+       if (!psDevData->psRgxDevNode)
+       {
+               return PVRSRV_ERROR_INVALID_DEVICE;
+       }
+
+       /* Call the internal server API */
+       eError = PVRSRVRGXConfigEnableHWPerfCountersKM(
+                       psDevData->psRgxDevNode, ui32NumBlocks, asBlockConfigs);
+       return eError;
+}
+
+
+PVRSRV_ERROR RGXHWPerfDisableCounters(
+               IMG_HANDLE   hDevData,
+               IMG_UINT32   ui32NumBlocks,
+               IMG_UINT16*   aeBlockIDs)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+
+       /* Valid input argument values supplied by the caller */
+       if (!psDevData || ui32NumBlocks==0 || !aeBlockIDs)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       if (ui32NumBlocks > RGXFWIF_HWPERF_CTRL_BLKS_MAX)
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+       /* Ensure we are initialised and have a valid device node */
+       if (!psDevData->psRgxDevNode)
+       {
+               return PVRSRV_ERROR_INVALID_DEVICE;
+       }
+
+       /* Call the internal server API */
+       eError = PVRSRVRGXCtrlHWPerfCountersKM(
+                       psDevData->psRgxDevNode, IMG_FALSE, ui32NumBlocks, aeBlockIDs);
+       return eError;
+}
+
+
+PVRSRV_ERROR RGXHWPerfAcquireData(
+               IMG_HANDLE  hDevData,
+               IMG_PBYTE*  ppBuf,
+               IMG_UINT32* pui32BufLen)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+       IMG_PBYTE              pTlBuf = IMG_NULL;
+       IMG_UINT32             ui32TlBufLen = 0;
+       IMG_PBYTE              pDataDest;
+       IMG_UINT32                      ui32TlPackets = 0;
+       IMG_PBYTE                       pBufferEnd;
+       PVRSRVTL_PPACKETHDR psHDRptr;
+       PVRSRVTL_PACKETTYPE ui16TlType;
+
+       /* Reset the output arguments in case we discover an error */
+       *ppBuf = IMG_NULL;
+       *pui32BufLen = 0;
+
+       /* Valid input argument values supplied by the caller */
+       if (!psDevData)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Acquire some data to read from the HWPerf TL stream */
+       eError = TLClientAcquireData(psDevData->hTLConnection,
+                                    psDevData->hSD,
+                                    &pTlBuf,
+                                    &ui32TlBufLen);
+       PVR_LOGR_IF_ERROR(eError, "TLClientAcquireData");
+
+       /* TL indicates no data exists so return OK and zero. */
+       if ((pTlBuf == IMG_NULL) || (ui32TlBufLen == 0))
+       {
+               return PVRSRV_OK;
+       }
+
+       /* Is the client buffer allocated and too small? */
+       if (psDevData->pHwpBuf && (psDevData->ui32HwpBufLen < ui32TlBufLen))
+       {
+               OSFREEMEM(psDevData->pHwpBuf);
+       }
+
+       /* Do we need to allocate a new client buffer? */
+       if (!psDevData->pHwpBuf)
+       {
+               psDevData->pHwpBuf = OSAllocMem(ui32TlBufLen);
+               if (psDevData->pHwpBuf  == IMG_NULL)
+               {
+                       (void) TLClientReleaseData(psDevData->hTLConnection, psDevData->hSD);
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+               psDevData->ui32HwpBufLen = ui32TlBufLen;
+       }
+
+       /* Process each TL packet in the data buffer we have acquired */
+       pBufferEnd = pTlBuf+ui32TlBufLen;
+       pDataDest = psDevData->pHwpBuf;
+       psHDRptr = GET_PACKET_HDR(pTlBuf);
+       while ( psHDRptr < (PVRSRVTL_PPACKETHDR)pBufferEnd )
+       {
+               ui16TlType = GET_PACKET_TYPE(psHDRptr);
+               if (ui16TlType == PVRSRVTL_PACKETTYPE_DATA)
+               {
+                       IMG_UINT16 ui16DataLen = GET_PACKET_DATA_LEN(psHDRptr);
+                       if (0 == ui16DataLen)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfAcquireData: ZERO Data in TL data packet: %p", psHDRptr));
+                       }
+                       else
+                       {
+                               /* For valid data copy it into the client buffer and move
+                                * the write position on */
+                               OSMemCopy(pDataDest, GET_PACKET_DATA_PTR(psHDRptr), ui16DataLen);
+                               pDataDest += ui16DataLen;
+                       }
+               }
+               else if (ui16TlType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED)
+               {
+                       PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfAcquireData: Indication that the transport buffer was full"));
+               }
+               else
+               {
+                       /* else Ignore padding packet type and others */
+                       PVR_DPF((PVR_DBG_MESSAGE, "RGXHWPerfAcquireData: Ignoring TL packet, type %d", ui16TlType ));
+               }
+
+               /* Update loop variable to the next packet and increment counts */
+               psHDRptr = GET_NEXT_PACKET_ADDR(psHDRptr);
+               ui32TlPackets++;
+       }
+
+       PVR_DPF((PVR_DBG_VERBOSE, "RGXHWPerfAcquireData: TL Packets processed %03d", ui32TlPackets));
+
+       /* Update output arguments with client buffer details and true length */
+       *ppBuf = psDevData->pHwpBuf;
+       *pui32BufLen = pDataDest - psDevData->pHwpBuf;
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR RGXHWPerfReleaseData(
+               IMG_HANDLE hDevData)
+{
+       PVRSRV_ERROR           eError;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+
+       /* Valid input argument values supplied by the caller */
+       if (!psDevData)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Free the client buffer if allocated and reset length */
+       if (psDevData->pHwpBuf)
+       {
+               OSFREEMEM(psDevData->pHwpBuf);
+       }
+       psDevData->ui32HwpBufLen = 0;
+
+       /* Inform the TL that we are done with reading the data. Could perform this
+        * in the acquire call but felt it worth keeping it symmetrical */
+       eError = TLClientReleaseData(psDevData->hTLConnection, psDevData->hSD);
+       return eError;
+}
+
+
+PVRSRV_ERROR RGXHWPerfDisconnect(
+               IMG_HANDLE hDevData)
+{
+       PVRSRV_ERROR           eError = PVRSRV_OK;
+       RGX_KM_HWPERF_DEVDATA* psDevData = (RGX_KM_HWPERF_DEVDATA*)hDevData;
+
+       /* Check session handle is not zero */
+       if (!psDevData)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* If the client buffer exists they have not called ReleaseData
+        * before disconnecting so clean it up */
+       if (psDevData->pHwpBuf)
+       {
+               eError = RGXHWPerfReleaseData(hDevData);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfDisconnect: Failed to release data (%d)", eError));
+               }
+               /* RGXHWPerfReleaseData call above will null out the buffer 
+                * fields and length */
+       }
+
+       /* Close the TL stream, ignore the error if it occurs as we
+        * are disconnecting */
+       if (psDevData->hSD)
+       {
+               eError = TLClientCloseStream(psDevData->hTLConnection,
+                                                                        psDevData->hSD);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfDisconnect: Failed to close handle on HWPerf stream (%d)", eError));
+               }
+               psDevData->hSD = IMG_NULL;
+       }
+
+       /* End the TL connection as we don't require it anymore */
+       if (psDevData->hTLConnection)
+       {
+               eError = TLClientDisconnect(psDevData->hTLConnection);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXHWPerfDisconnect: Failed to disconnect from the Transport (%d)", eError));
+               }
+               psDevData->hTLConnection = IMG_NULL;
+       }
+
+       /* Free the session memory */
+       psDevData->psRgxDevNode = IMG_NULL;
+       OSFREEMEM(psDevData);
+       return eError;
+}
+
+
+#endif /* SUPPORT_KERNEL_HWPERF */
+
+
+/******************************************************************************
+ End of file (rgxdebug.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxhwperf.h
new file mode 100644 (file)
index 0000000..5383988
--- /dev/null
@@ -0,0 +1,114 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX HW Performance header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX HWPerf functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXHWPERF_H_
+#define RGXHWPERF_H_
+  
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#include "device.h"
+#include "rgxdevice.h"
+#include "rgx_hwperf_km.h"
+
+
+/******************************************************************************
+ * RGX HW Performance Data Transport Routines
+ *****************************************************************************/
+
+PVRSRV_ERROR RGXHWPerfDataStoreCB(PVRSRV_DEVICE_NODE* psDevInfo);
+
+PVRSRV_ERROR RGXHWPerfInit(PVRSRV_DEVICE_NODE *psRgxDevInfo, IMG_BOOL bEnable);
+IMG_VOID RGXHWPerfDeinit(void);
+
+
+/******************************************************************************
+ * RGX HW Performance Profiling API(s)
+ *****************************************************************************/
+
+PVRSRV_ERROR PVRSRVRGXCtrlHWPerfKM(
+               PVRSRV_DEVICE_NODE*     psDeviceNode,
+               IMG_BOOL                        bToggle,
+               IMG_UINT64                      ui64Mask);
+
+
+PVRSRV_ERROR PVRSRVRGXConfigEnableHWPerfCountersKM(
+               PVRSRV_DEVICE_NODE*             psDeviceNode,
+               IMG_UINT32                                      ui32ArrayLen,
+               RGX_HWPERF_CONFIG_CNTBLK*       psBlockConfigs);
+
+PVRSRV_ERROR PVRSRVRGXCtrlHWPerfCountersKM(
+               PVRSRV_DEVICE_NODE*             psDeviceNode,
+               IMG_BOOL                        bEnable,
+           IMG_UINT32                  ui32ArrayLen,
+           IMG_UINT16*                 psBlockIDs);
+
+PVRSRV_ERROR PVRSRVRGXConfigCustomCountersKM(
+               PVRSRV_DEVICE_NODE*     psDeviceNode,
+               IMG_UINT16              ui16CustomBlockID,
+               IMG_UINT16              ui16NumCustomCounters,
+               IMG_UINT32*             pui32CustomCounterIDs);
+
+/******************************************************************************
+ * RGX HW Performance To FTrace Profiling API(s)
+ *****************************************************************************/
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+
+PVRSRV_ERROR RGXHWPerfFTraceGPUInit(PVRSRV_RGXDEV_INFO *psDevInfo);
+IMG_VOID RGXHWPerfFTraceGPUDeInit(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+IMG_VOID RGXHWPerfFTraceGPUEnqueueEvent(PVRSRV_RGXDEV_INFO *psDevInfo,
+               IMG_UINT32 ui32ExternalJobRef, IMG_UINT32 ui32InternalJobRef,
+               const IMG_CHAR* pszJobType);
+
+PVRSRV_ERROR RGXHWPerfFTraceGPUEventsEnabledSet(IMG_BOOL bNewValue);
+IMG_BOOL RGXHWPerfFTraceGPUEventsEnabled(IMG_VOID);
+
+IMG_VOID RGXHWPerfFTraceGPUThread(IMG_PVOID pvData);
+
+#endif
+
+
+#endif /* RGXHWPERF_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.c
new file mode 100644 (file)
index 0000000..ac96cff
--- /dev/null
@@ -0,0 +1,3189 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific initialisation routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "pvrsrv.h"
+#include "rgxheapconfig.h"
+#include "rgxpower.h"
+
+#include "rgxinit.h"
+
+#include "pdump_km.h"
+#include "handle.h"
+#include "allocmem.h"
+#include "devicemem_pdump.h"
+#include "rgxmem.h"
+#include "sync_internal.h"
+
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_km.h"
+
+#include "rgxmmuinit.h"
+#include "devicemem_utils.h"
+#include "devicemem_server.h"
+#include "physmem_osmem.h"
+
+#include "rgxdebug.h"
+#include "rgxhwperf.h"
+
+#include "rgx_options_km.h"
+#include "pvrversion.h"
+
+#include "rgx_compat_bvnc.h"
+
+#include "rgx_heaps.h"
+
+#include "rgxta3d.h"
+#include "debug_request_ids.h"
+#include "rgxtimecorr.h"
+
+static PVRSRV_ERROR RGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32ClientBuildOptions);
+static PVRSRV_ERROR RGXDevVersionString(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_CHAR **ppszVersionString);
+static PVRSRV_ERROR RGXDevClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_PUINT32  pui32RGXClockSpeed);
+static PVRSRV_ERROR RGXSoftReset(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT64  ui64ResetValue1, IMG_UINT64  ui64ResetValue2);
+
+#define RGX_MMU_LOG2_PAGE_SIZE_4KB   (12)
+#define RGX_MMU_LOG2_PAGE_SIZE_16KB  (14)
+#define RGX_MMU_LOG2_PAGE_SIZE_64KB  (16)
+#define RGX_MMU_LOG2_PAGE_SIZE_256KB (18)
+#define RGX_MMU_LOG2_PAGE_SIZE_1MB   (20)
+#define RGX_MMU_LOG2_PAGE_SIZE_2MB   (21)
+
+#define RGX_MMU_PAGE_SIZE_4KB   (   4 * 1024)
+#define RGX_MMU_PAGE_SIZE_16KB  (  16 * 1024)
+#define RGX_MMU_PAGE_SIZE_64KB  (  64 * 1024)
+#define RGX_MMU_PAGE_SIZE_256KB ( 256 * 1024)
+#define RGX_MMU_PAGE_SIZE_1MB   (1024 * 1024)
+#define RGX_MMU_PAGE_SIZE_2MB   (2048 * 1024)
+#define RGX_MMU_PAGE_SIZE_MIN RGX_MMU_PAGE_SIZE_4KB
+#define RGX_MMU_PAGE_SIZE_MAX RGX_MMU_PAGE_SIZE_2MB
+
+#define VAR(x) #x
+
+/* FIXME: This is a workaround due to having 2 inits but only 1 deinit */
+static IMG_BOOL g_bDevInit2Done = IMG_FALSE;
+
+
+static IMG_VOID RGX_DeInitHeaps(DEVICE_MEMORY_INFO *psDevMemoryInfo);
+
+IMG_UINT32 g_ui32HostSampleIRQCount = 0;
+
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+
+/* bits used by the LISR to provide a trace of its last execution */
+#define RGX_LISR_IGNORED       (1 << 0)
+#define RGX_LISR_EVENT_EN              (1 << 2)
+#define RGX_LISR_PROCESSED             (1 << 4)
+
+typedef struct _LISR_EXECUTION_INFO_
+{
+       /* bit mask showing execution flow of last LISR invocation */
+       IMG_UINT32 ui32State;
+       /* snapshot from the last LISR invocation, regardless of
+        * whether an interrupt was handled
+        */
+       IMG_UINT32 ui32InterruptCountSnapshot;
+       /* time of the last LISR invocation */
+       IMG_UINT64 ui64Clockns;
+} LISR_EXECUTION_INFO;
+
+/* information about the last execution of the LISR */
+static LISR_EXECUTION_INFO g_sLISRExecutionInfo;
+
+#endif
+
+#if !defined(NO_HARDWARE)
+
+void RGX_WaitForInterruptsTimeout(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVR_DPF((PVR_DBG_ERROR, "_WaitForInterruptsTimeout: FW Count: 0x%X Host Count: 0x%X",
+                                               psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount,
+                                                                       g_ui32HostSampleIRQCount));
+
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+
+       PVR_DPF((PVR_DBG_ERROR, "Last RGX_LISRHandler State: 0x%08X InterruptCountSnapshot: 0x%X Clock: %llu",
+                                                                       g_sLISRExecutionInfo.ui32State,
+                                                                       g_sLISRExecutionInfo.ui32InterruptCountSnapshot,
+                                                                       g_sLISRExecutionInfo.ui64Clockns));
+#else
+       PVR_DPF((PVR_DBG_ERROR, "No further information available. Please enable PVRSRV_DEBUG_LISR_EXECUTION"));
+#endif
+
+
+       if(psDevInfo->psRGXFWIfTraceBuf->ePowState != RGXFWIF_POW_OFF)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_WaitForInterruptsTimeout: FW pow state is not OFF (is %u)",
+                                               (unsigned int) psDevInfo->psRGXFWIfTraceBuf->ePowState));
+       }
+
+       if(g_ui32HostSampleIRQCount != psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount)
+       {
+               /* we are handling any unhandled interrupts here so align the host
+                * count with the FW count
+                */
+               g_ui32HostSampleIRQCount = psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount;
+
+               OSScheduleMISR(psDevInfo->pvMISRData);
+
+               if(psDevInfo->pvAPMISRData != NULL)
+               {
+                       OSScheduleMISR(psDevInfo->pvAPMISRData);
+               }
+       }
+}
+
+/*
+       RGX LISR Handler
+*/
+static IMG_BOOL RGX_LISRHandler (IMG_VOID *pvData)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode;
+       PVRSRV_DEVICE_CONFIG *psDevConfig;
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+       IMG_UINT32 ui32IRQStatus;
+       IMG_BOOL bInterruptProcessed = IMG_FALSE;
+
+       psDeviceNode = pvData;
+       psDevConfig = psDeviceNode->psDevConfig;
+       psDevInfo = psDeviceNode->pvDevice;
+
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+       g_sLISRExecutionInfo.ui32InterruptCountSnapshot = psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount;
+       g_sLISRExecutionInfo.ui32State = 0;
+       g_sLISRExecutionInfo.ui64Clockns = OSClockns64();
+#endif
+
+       if (psDevInfo->bIgnoreFurtherIRQs)
+       {
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+               g_sLISRExecutionInfo.ui32State |= RGX_LISR_IGNORED;
+#endif
+               return IMG_FALSE;
+       }
+
+       ui32IRQStatus = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVIRQSTATUS);
+
+       if (ui32IRQStatus & RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN)
+       {
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+               g_sLISRExecutionInfo.ui32State |= RGX_LISR_EVENT_EN;
+#endif
+               OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVIRQSTATUS, RGX_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK);
+               
+#if defined(RGX_FEATURE_OCPBUS)
+               OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_OCP_IRQSTATUS_2, RGX_CR_OCP_IRQSTATUS_2_RGX_IRQ_STATUS_EN);
+#endif
+
+               if (psDevConfig->pfnInterruptHandled)
+               {
+                       psDevConfig->pfnInterruptHandled(psDevConfig);
+               }
+
+               bInterruptProcessed = IMG_TRUE;
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+               g_sLISRExecutionInfo.ui32State |= RGX_LISR_PROCESSED;
+#endif
+               
+               /* Sample the current count from the FW _after_ we've cleared the interrupt. */
+               g_ui32HostSampleIRQCount = psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount;
+
+               OSScheduleMISR(psDevInfo->pvMISRData);
+
+               if (psDevInfo->pvAPMISRData != IMG_NULL)
+               {
+                       OSScheduleMISR(psDevInfo->pvAPMISRData);
+               }
+       }
+       return bInterruptProcessed;
+}
+
+static IMG_VOID RGXCheckFWActivePowerState(IMG_VOID *psDevice)
+{
+       PVRSRV_DEVICE_NODE      *psDeviceNode = psDevice;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       
+       if (psFWTraceBuf->ePowState == RGXFWIF_POW_IDLE)
+       {
+               /* The FW is IDLE and therefore could be shut down */
+               eError = RGXActivePowerRequest(psDeviceNode);
+
+               if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED))
+               {
+                       PVR_DPF((PVR_DBG_WARNING,"RGXCheckFWActivePowerState: Failed RGXActivePowerRequest call (device index: %d) with %s", 
+                                               psDeviceNode->sDevId.ui32DeviceIndex,
+                                               PVRSRVGetErrorStringKM(eError)));
+                       
+                       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
+               }
+       }
+
+}
+
+
+PVRSRV_ERROR RGXRegisterGpuUtilStats(IMG_HANDLE *phGpuUtilUser)
+{
+       RGXFWIF_GPU_UTIL_STATS *psAggregateStats;
+
+       psAggregateStats = OSAllocMem(sizeof(RGXFWIF_GPU_UTIL_STATS));
+       if(psAggregateStats == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psAggregateStats->ui64GpuStatActiveLow  = 0;
+       psAggregateStats->ui64GpuStatIdle       = 0;
+       psAggregateStats->ui64GpuStatActiveHigh = 0;
+       psAggregateStats->ui64GpuStatBlocked    = 0;
+
+       /* Not used */
+       psAggregateStats->bValid = IMG_FALSE;
+       psAggregateStats->ui64GpuStatCumulative = 0;
+
+       *phGpuUtilUser = psAggregateStats;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RGXUnregisterGpuUtilStats(IMG_HANDLE hGpuUtilUser)
+{
+       RGXFWIF_GPU_UTIL_STATS *psAggregateStats;
+
+       if(hGpuUtilUser == NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psAggregateStats = hGpuUtilUser;
+       OSFreeMem(psAggregateStats);
+
+       return PVRSRV_OK;
+}
+
+/* Shorter defines to keep the code a bit shorter */
+#define GPU_ACTIVE_LOW   RGXFWIF_GPU_UTIL_STATE_ACTIVE_LOW
+#define GPU_IDLE         RGXFWIF_GPU_UTIL_STATE_IDLE
+#define GPU_ACTIVE_HIGH  RGXFWIF_GPU_UTIL_STATE_ACTIVE_HIGH
+#define GPU_BLOCKED      RGXFWIF_GPU_UTIL_STATE_BLOCKED
+#define MAX_ITERATIONS   64
+
+static PVRSRV_ERROR RGXGetGpuUtilStats(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                       IMG_HANDLE hGpuUtilUser,
+                                       RGXFWIF_GPU_UTIL_STATS *psReturnStats)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       volatile RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb;
+       RGXFWIF_GPU_UTIL_STATS *psAggregateStats;
+       IMG_UINT64 aui64TmpCounters[RGXFWIF_GPU_UTIL_STATE_NUM] = {0};
+       IMG_UINT64 ui64TimeNow;
+       IMG_UINT64 ui64LastPeriod;
+       IMG_UINT64 ui64LastWord = 0, ui64LastState = 0, ui64LastTime = 0;
+       IMG_UINT32 i = 0;
+
+
+       /***** (1) Initialise return stats *****/
+
+       psReturnStats->bValid = IMG_FALSE;
+       psReturnStats->ui64GpuStatActiveLow  = 0;
+       psReturnStats->ui64GpuStatIdle       = 0;
+       psReturnStats->ui64GpuStatActiveHigh = 0;
+       psReturnStats->ui64GpuStatBlocked    = 0;
+       psReturnStats->ui64GpuStatCumulative = 0;
+
+       if (hGpuUtilUser == NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       psAggregateStats = hGpuUtilUser;
+
+
+       /***** (2) Get latest data from shared area *****/
+
+       OSLockAcquire(psDevInfo->hGPUUtilLock);
+
+       /* Read the timer before reading the latest stats from the shared
+        * area, discard it later in case of state updates after this point.
+        */
+       ui64TimeNow = RGXFWIF_GPU_UTIL_GET_TIME(OSClockns64());
+       OSMemoryBarrier();
+
+       /* Keep reading the counters until the values stabilise as the FW
+        * might be updating them at the same time.
+        */
+       while(((ui64LastWord != psUtilFWCb->ui64LastWord) ||
+              (aui64TmpCounters[ui64LastState] !=
+               psUtilFWCb->aui64StatsCounters[ui64LastState])) &&
+             (i < MAX_ITERATIONS))
+       {
+               ui64LastWord  = psUtilFWCb->ui64LastWord;
+               ui64LastState = RGXFWIF_GPU_UTIL_GET_STATE(ui64LastWord);
+               aui64TmpCounters[GPU_ACTIVE_LOW]  = psUtilFWCb->aui64StatsCounters[GPU_ACTIVE_LOW];
+               aui64TmpCounters[GPU_IDLE]        = psUtilFWCb->aui64StatsCounters[GPU_IDLE];
+               aui64TmpCounters[GPU_ACTIVE_HIGH] = psUtilFWCb->aui64StatsCounters[GPU_ACTIVE_HIGH];
+               aui64TmpCounters[GPU_BLOCKED]     = psUtilFWCb->aui64StatsCounters[GPU_BLOCKED];
+               i++;
+       }
+
+#if defined(PVR_POWER_ACTOR) && defined(PVR_DVFS)
+       /* Power actor enabled */
+       psReturnStats->ui32GpuEnergy = psDevInfo->psRGXFWIfTraceBuf->ui32PowMonEnergy;
+#endif
+
+       OSLockRelease(psDevInfo->hGPUUtilLock);
+
+       if (i == MAX_ITERATIONS)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXGetGpuUtilStats could not get reliable data within a short time."));
+               return PVRSRV_ERROR_TIMEOUT;
+       }
+
+
+       /***** (3) Compute return stats and update aggregate stats *****/
+
+       /* Update temp counters to account for the time since the last update to the shared ones */
+       ui64LastTime   = RGXFWIF_GPU_UTIL_GET_TIME(ui64LastWord);
+       ui64LastPeriod = RGXFWIF_GPU_UTIL_GET_PERIOD(ui64TimeNow, ui64LastTime);
+       aui64TmpCounters[ui64LastState] += ui64LastPeriod;
+
+       /* Get statistics for a user since its last request */
+       psReturnStats->ui64GpuStatActiveLow = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_ACTIVE_LOW],
+                                                                         psAggregateStats->ui64GpuStatActiveLow);
+       psReturnStats->ui64GpuStatIdle = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_IDLE],
+                                                                    psAggregateStats->ui64GpuStatIdle);
+       psReturnStats->ui64GpuStatActiveHigh = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_ACTIVE_HIGH],
+                                                                          psAggregateStats->ui64GpuStatActiveHigh);
+       psReturnStats->ui64GpuStatBlocked = RGXFWIF_GPU_UTIL_GET_PERIOD(aui64TmpCounters[GPU_BLOCKED],
+                                                                       psAggregateStats->ui64GpuStatBlocked);
+       psReturnStats->ui64GpuStatCumulative = psReturnStats->ui64GpuStatActiveLow + psReturnStats->ui64GpuStatIdle +
+                                              psReturnStats->ui64GpuStatActiveHigh + psReturnStats->ui64GpuStatBlocked;
+
+       /* Update aggregate stats for the current user */
+       psAggregateStats->ui64GpuStatActiveLow  += psReturnStats->ui64GpuStatActiveLow;
+       psAggregateStats->ui64GpuStatIdle       += psReturnStats->ui64GpuStatIdle;
+       psAggregateStats->ui64GpuStatActiveHigh += psReturnStats->ui64GpuStatActiveHigh;
+       psAggregateStats->ui64GpuStatBlocked    += psReturnStats->ui64GpuStatBlocked;
+
+
+       /***** (4) Convert return stats to microseconds *****/
+
+       psReturnStats->ui64GpuStatActiveLow  = OSDivide64(psReturnStats->ui64GpuStatActiveLow, 1000, &i);
+       psReturnStats->ui64GpuStatIdle       = OSDivide64(psReturnStats->ui64GpuStatIdle, 1000, &i);
+       psReturnStats->ui64GpuStatActiveHigh = OSDivide64(psReturnStats->ui64GpuStatActiveHigh, 1000, &i);
+       psReturnStats->ui64GpuStatBlocked    = OSDivide64(psReturnStats->ui64GpuStatBlocked, 1000, &i);
+       psReturnStats->ui64GpuStatCumulative = OSDivide64(psReturnStats->ui64GpuStatCumulative, 1000, &i);
+
+       /* Check that the return stats make sense */
+       if(psReturnStats->ui64GpuStatCumulative == 0)
+       {
+               /* We can enter here only if all the RGXFWIF_GPU_UTIL_GET_PERIOD
+                * returned 0. This could happen if the GPU frequency value
+                * is not well calibrated and the FW is updating the GPU state
+                * while the Host is reading it.
+                * When such an event happens frequently, timers or the aggregate
+                * stats might not be accurate...
+                */
+               PVR_DPF((PVR_DBG_WARNING, "RGXGetGpuUtilStats could not get reliable data."));
+               return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+       }
+
+       psReturnStats->bValid = IMG_TRUE;
+
+       return PVRSRV_OK;
+}
+
+
+/*
+       RGX MISR Handler
+*/
+static IMG_VOID RGX_MISRHandler (IMG_VOID *pvData)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
+
+       /* Give the HWPerf service a chance to transfer some data from the FW
+        * buffer to the host driver transport layer buffer.
+        */
+       RGXHWPerfDataStoreCB(psDeviceNode);
+
+       /* Inform other services devices that we have finished an operation */
+       PVRSRVCheckStatus(psDeviceNode);
+
+       /* Process all firmware CCBs for pending commands */
+       RGXCheckFirmwareCCBs(psDeviceNode->pvDevice);
+
+       /* Calibrate the GPU frequency and recorrelate Host and FW timers (done every few seconds) */
+       RGXGPUFreqCalibrateCorrelatePeriodic(psDeviceNode);
+}
+#endif
+
+
+PVRSRV_ERROR PVRSRVGPUVIRTPopulateLMASubArenasKM(PVRSRV_DEVICE_NODE    *psDeviceNode, IMG_UINT32 ui32NumElements, IMG_UINT32 aui32Elements[])
+{
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+       IMG_UINT32      ui32OS, ui32Region, ui32Counter=0;
+       IMG_UINT32      aui32OSidMin[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS];
+       IMG_UINT32      aui32OSidMax[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS];
+
+       PVR_UNREFERENCED_PARAMETER(ui32NumElements);
+
+       for (ui32OS = 0; ui32OS < GPUVIRT_VALIDATION_NUM_OS; ui32OS++)
+       {
+               for (ui32Region = 0; ui32Region < GPUVIRT_VALIDATION_NUM_REGIONS; ui32Region++)
+               {
+                       aui32OSidMin[ui32OS][ui32Region] = aui32Elements[ui32Counter++];
+                       aui32OSidMax[ui32OS][ui32Region] = aui32Elements[ui32Counter++];
+
+                       PVR_DPF((PVR_DBG_MESSAGE,"OS=%u, Region=%u, Min=%u, Max=%u", ui32OS, ui32Region, aui32OSidMin[ui32OS][ui32Region], aui32OSidMax[ui32OS][ui32Region]));
+               }
+       }
+
+       PopulateLMASubArenas(psDeviceNode, aui32OSidMin, aui32OSidMax);
+}
+#else
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+       PVR_UNREFERENCED_PARAMETER(ui32NumElements);
+       PVR_UNREFERENCED_PARAMETER(aui32Elements);
+}
+#endif
+
+       return PVRSRV_OK;
+}
+
+/*
+ * PVRSRVRGXInitDevPart2KM
+ */ 
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitDevPart2KM (PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                         RGX_INIT_COMMAND              *psInitScript,
+                                                                         RGX_INIT_COMMAND              *psDbgScript,
+                                                                         RGX_INIT_COMMAND              *psDbgBusScript,
+                                                                         RGX_INIT_COMMAND              *psDeinitScript,
+                                                                         IMG_UINT32                    ui32KernelCatBaseIdReg,
+                                                                         IMG_UINT32                    ui32KernelCatBaseId,
+                                                                         IMG_UINT32                    ui32KernelCatBaseReg,
+                                                                         IMG_UINT32                    ui32KernelCatBaseWordSize,
+                                                                         IMG_UINT32                    ui32KernelCatBaseAlignShift,
+                                                                         IMG_UINT32                    ui32KernelCatBaseShift,
+                                                                         IMG_UINT64                    ui64KernelCatBaseMask,
+                                                                         IMG_UINT32                    ui32DeviceFlags,
+                                                                         RGX_ACTIVEPM_CONF             eActivePMConf,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWCodeAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWDataAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWCorememAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psHWPerfDataAllocServerExportCookie)
+{
+       PVRSRV_ERROR                    eError;
+       PVRSRV_RGXDEV_INFO              *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_DEV_POWER_STATE  eDefaultPowerState;
+       PVRSRV_DEVICE_CONFIG    *psDevConfig = psDeviceNode->psDevConfig;
+
+       PDUMPCOMMENT("RGX Initialisation Part 2");
+
+       psDevInfo->ui32KernelCatBaseIdReg = ui32KernelCatBaseIdReg;
+       psDevInfo->ui32KernelCatBaseId = ui32KernelCatBaseId;
+       psDevInfo->ui32KernelCatBaseReg = ui32KernelCatBaseReg;
+       psDevInfo->ui32KernelCatBaseAlignShift = ui32KernelCatBaseAlignShift;
+       psDevInfo->ui32KernelCatBaseShift = ui32KernelCatBaseShift;
+       psDevInfo->ui32KernelCatBaseWordSize = ui32KernelCatBaseWordSize;
+       psDevInfo->ui64KernelCatBaseMask = ui64KernelCatBaseMask;
+
+       /*
+        * Map RGX Registers
+        */
+#if !defined(NO_HARDWARE)
+       psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psDevConfig->sRegsCpuPBase,
+                                                                                    psDevConfig->ui32RegsSize,
+                                                                                    0);
+
+       if (psDevInfo->pvRegsBaseKM == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitDevPart2KM: Failed to create RGX register mapping"));
+               return PVRSRV_ERROR_BAD_MAPPING;
+       }
+#else
+       psDevInfo->pvRegsBaseKM = IMG_NULL;
+#endif /* !NO_HARDWARE */
+
+       /* free the export cookies provided to srvinit */
+       DevmemUnexport(psDevInfo->psRGXFWCodeMemDesc, psFWCodeAllocServerExportCookie);
+       DevmemUnexport(psDevInfo->psRGXFWDataMemDesc, psFWDataAllocServerExportCookie);
+       if (DevmemIsValidExportCookie(psFWCorememAllocServerExportCookie))
+       {
+               DevmemUnexport(psDevInfo->psRGXFWCorememMemDesc, psFWCorememAllocServerExportCookie);
+       }
+       DevmemUnexport(psDevInfo->psRGXFWIfHWPerfCountersMemDesc, psHWPerfDataAllocServerExportCookie);
+       /*
+        * Copy scripts
+        */
+       OSMemCopy(psDevInfo->psScripts->asInitCommands, psInitScript,
+                         RGX_MAX_INIT_COMMANDS * sizeof(*psInitScript));
+
+       OSMemCopy(psDevInfo->psScripts->asDbgCommands, psDbgScript,
+                         RGX_MAX_DEBUG_COMMANDS * sizeof(*psDbgScript));
+
+       OSMemCopy(psDevInfo->psScripts->asDbgBusCommands, psDbgBusScript,
+                         RGX_MAX_DBGBUS_COMMANDS * sizeof(*psDbgBusScript));
+
+       OSMemCopy(psDevInfo->psScripts->asDeinitCommands, psDeinitScript,
+                         RGX_MAX_DEINIT_COMMANDS * sizeof(*psDeinitScript));
+
+#if defined(PDUMP)
+       /* Run the deinit script to feed the last-frame deinit buffer */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_DEINIT, "RGX deinitialisation script");
+       RGXRunScript(psDevInfo, psDevInfo->psScripts->asDeinitCommands, RGX_MAX_DEINIT_COMMANDS, PDUMP_FLAGS_DEINIT | PDUMP_FLAGS_NOHW, IMG_NULL);
+#endif
+
+
+       psDevInfo->ui32RegSize = psDevConfig->ui32RegsSize;
+       psDevInfo->sRegsPhysBase = psDevConfig->sRegsCpuPBase;
+
+       /* Initialise Device Flags */
+       psDevInfo->ui32DeviceFlags = 0;
+       if (ui32DeviceFlags & RGXKMIF_DEVICE_STATE_ZERO_FREELIST)
+       {
+               psDevInfo->ui32DeviceFlags |= RGXKM_DEVICE_STATE_ZERO_FREELIST;
+       }
+
+       if (ui32DeviceFlags & RGXKMIF_DEVICE_STATE_DISABLE_DW_LOGGING_EN)
+       {
+               psDevInfo->ui32DeviceFlags |= RGXKM_DEVICE_STATE_DISABLE_DW_LOGGING_EN;
+       }
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+       /* If built, always setup FTrace consumer thread. */
+       RGXHWPerfFTraceGPUInit(psDeviceNode->pvDevice);
+
+       RGXHWPerfFTraceGPUEventsEnabledSet((ui32DeviceFlags & RGXKMIF_DEVICE_STATE_FTRACE_EN) ? IMG_TRUE: IMG_FALSE);
+#endif
+
+       /* Initialise lists of ZSBuffers */
+       eError = OSLockCreate(&psDevInfo->hLockZSBuffer,LOCK_TYPE_PASSIVE);
+       PVR_ASSERT(eError == PVRSRV_OK);
+       dllist_init(&psDevInfo->sZSBufferHead);
+       psDevInfo->ui32ZSBufferCurrID = 1;
+
+       /* Initialise lists of growable Freelists */
+       eError = OSLockCreate(&psDevInfo->hLockFreeList,LOCK_TYPE_PASSIVE);
+       PVR_ASSERT(eError == PVRSRV_OK);
+       dllist_init(&psDevInfo->sFreeListHead);
+       psDevInfo->ui32FreelistCurrID = 1;
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       eError = OSLockCreate(&psDevInfo->hDebugFaultInfoLock, LOCK_TYPE_PASSIVE);
+
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = OSLockCreate(&psDevInfo->hMMUCtxUnregLock, LOCK_TYPE_PASSIVE);
+
+       if(eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       /* Allocate DVFS Table */
+       psDevInfo->psGpuDVFSTable = OSAllocZMem(sizeof(*(psDevInfo->psGpuDVFSTable)));
+       if (psDevInfo->psGpuDVFSTable == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitDevPart2KM: failed to allocate gpu dvfs table storage"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* Reset DVFS Table */
+       psDevInfo->psGpuDVFSTable->ui32CurrentDVFSId = 0;
+       psDevInfo->psGpuDVFSTable->aui32DVFSClock[0] = 0;
+
+       /* Setup GPU utilisation stats update callback */
+#if !defined(NO_HARDWARE)
+       psDevInfo->pfnRegisterGpuUtilStats = RGXRegisterGpuUtilStats;
+       psDevInfo->pfnGetGpuUtilStats = RGXGetGpuUtilStats;
+       psDevInfo->pfnUnregisterGpuUtilStats = RGXUnregisterGpuUtilStats;
+#endif
+
+       eError = OSLockCreate(&psDevInfo->hGPUUtilLock, LOCK_TYPE_PASSIVE);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+
+       eDefaultPowerState = PVRSRV_DEV_POWER_STATE_ON;
+
+       /* set-up the Active Power Mgmt callback */
+#if !defined(NO_HARDWARE)
+       {
+               RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
+               IMG_BOOL bSysEnableAPM = psRGXData->psRGXTimingInfo->bEnableActivePM;
+               IMG_BOOL bEnableAPM = ((eActivePMConf == RGX_ACTIVEPM_DEFAULT) && bSysEnableAPM) ||
+                                                          (eActivePMConf == RGX_ACTIVEPM_FORCE_ON);
+
+               if (bEnableAPM)
+               {
+                       eError = OSInstallMISR(&psDevInfo->pvAPMISRData, RGXCheckFWActivePowerState, psDeviceNode);
+                       if (eError != PVRSRV_OK)
+                       {
+                               return eError;
+                       }
+
+                       /* Prevent the device being woken up before there is something to do. */
+                       eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
+               }
+       }
+#endif
+
+       /* Register the device with the power manager. */
+       eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                               &RGXPrePowerState, &RGXPostPowerState,
+                                                                               psDevConfig->pfnPrePowerState, psDevConfig->pfnPostPowerState,
+                                                                               &RGXPreClockSpeedChange, &RGXPostClockSpeedChange,
+                                                                               &RGXForcedIdleRequest, &RGXCancelForcedIdleRequest,
+                                                                               &RGXDustCountChange,
+                                                                               (IMG_HANDLE)psDeviceNode,
+                                                                               PVRSRV_DEV_POWER_STATE_OFF,
+                                                                               eDefaultPowerState);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitDevPart2KM: failed to register device with power manager"));
+               return eError;
+       }
+
+#if !defined(NO_HARDWARE)
+       eError = RGXInstallProcessQueuesMISR(&psDevInfo->hProcessQueuesMISR, psDeviceNode);
+       if (eError != PVRSRV_OK)
+       {
+               if (psDevInfo->pvAPMISRData != IMG_NULL)
+               {
+                       (IMG_VOID) OSUninstallMISR(psDevInfo->pvAPMISRData);
+               }
+               return eError;
+       }
+
+       /* Register the interrupt handlers */
+       eError = OSInstallMISR(&psDevInfo->pvMISRData,
+                                                                       RGX_MISRHandler, psDeviceNode);
+       if (eError != PVRSRV_OK)
+       {
+               if (psDevInfo->pvAPMISRData != IMG_NULL)
+               {
+                       (IMG_VOID) OSUninstallMISR(psDevInfo->pvAPMISRData);
+               }
+               (IMG_VOID) OSUninstallMISR(psDevInfo->hProcessQueuesMISR);
+               return eError;
+       }
+
+       eError = OSInstallDeviceLISR(psDevConfig, &psDevInfo->pvLISRData,
+                                                                RGX_LISRHandler, psDeviceNode);
+       if (eError != PVRSRV_OK)
+       {
+               if (psDevInfo->pvAPMISRData != IMG_NULL)
+               {
+                       (IMG_VOID) OSUninstallMISR(psDevInfo->pvAPMISRData);
+               }
+               (IMG_VOID) OSUninstallMISR(psDevInfo->hProcessQueuesMISR);
+               (IMG_VOID) OSUninstallMISR(psDevInfo->pvMISRData);
+               return eError;
+       }
+
+#endif
+       g_bDevInit2Done = IMG_TRUE;
+
+       return PVRSRV_OK;
+}
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitHWPerfCountersKM(PVRSRV_DEVICE_NODE  *psDeviceNode)
+{
+
+       PVRSRV_ERROR                    eError;
+       RGXFWIF_KCCB_CMD                sKccbCmd;
+
+       /* Fill in the command structure with the parameters needed
+        */
+       sKccbCmd.eCmdType = RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS_DIRECT;
+
+       eError = RGXSendCommandWithPowLock(psDeviceNode->pvDevice,
+                                                                                       RGXFWIF_DM_GP,
+                                                                                       &sKccbCmd,
+                                                                                       sizeof(sKccbCmd),
+                                                                                       IMG_TRUE);
+
+       return PVRSRV_OK;
+
+}
+
+static
+PVRSRV_ERROR RGXAllocateFWCodeRegion(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                                     IMG_DEVMEM_SIZE_T ui32FWCodeAllocSize,
+                                     IMG_UINT32 uiMemAllocFlags)
+{
+       PVRSRV_ERROR eError;
+
+#if ! defined(TDMETACODE)
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+
+       uiMemAllocFlags |= PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                          PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate and export code memory for fw");
+
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               ui32FWCodeAllocSize,
+                                                                               uiMemAllocFlags,
+                                                                               "FirmwareCodeRegion",
+                                           &psDevInfo->psRGXFWCodeMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DevmemFwAllocateExportable failed (%u)",
+                               eError));
+       }
+
+       return eError;
+
+#else
+       PMR *psTDMetaCodePMR;
+       IMG_DEVMEM_SIZE_T uiMemDescSize;
+       IMG_DEV_VIRTADDR sTmpDevVAddr;
+       PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice;
+
+       PDUMPCOMMENT("Allocate TD META code memory for fw");
+
+       eError = PhysmemNewTDMetaCodePMR(psDeviceNode,
+                                        ui32FWCodeAllocSize,
+                                        12,
+                                        uiMemAllocFlags,
+                                        &psTDMetaCodePMR);
+       if(eError != PVRSRV_OK)
+       {
+               goto PMRCreateError;
+       }
+
+       PDUMPCOMMENT("Import TD META code memory for fw");
+
+       /* NB: psTDMetaCodePMR refcount: 1 -> 2 */
+       eError = DevmemLocalImport(IMG_NULL, /* bridge handle not applicable here */
+                                  psTDMetaCodePMR,
+                                  uiMemAllocFlags,
+                                  &psDevInfo->psRGXFWCodeMemDesc,
+                                  &uiMemDescSize);
+       if(eError != PVRSRV_OK)
+       {
+               goto ImportError;
+       }
+
+       eError = DevmemMapToDevice(psDevInfo->psRGXFWCodeMemDesc,
+                                                          psDevInfo->psFirmwareHeap,
+                                                          &sTmpDevVAddr);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to map TD META code PMR (%u)", eError));
+               goto MapError;
+       }
+
+       /* Caution, oddball code follows:
+          When doing the DevmemLocalImport above, we wrap the PMR in a memdesc and increment
+          the PMR's refcount. We would like to implicitly say now, that memdesc is our
+          tracking mechanism for the PMR, and no longer the original pointer to it. The call
+          to PMRUnimportPMR below does that. For reasons explained below, this is only done
+          if this function will return successfully.
+
+          NB: i.e., psTDMetaCodePMR refcount: 2 -> 1
+       */
+       PMRUnimportPMR(psTDMetaCodePMR);
+
+       return eError;
+
+MapError:
+       DevmemFree(psDevInfo->psRGXFWCodeMemDesc);
+
+ImportError:
+       /* This is done even after the DevmemFree above because as a result of the PMRUnimportPMR
+          at the end of the function never getting hit on an error condition, the PMR must be
+          unreferenced "again" as part of the cleanup */
+       PMRUnimportPMR(psTDMetaCodePMR);
+
+PMRCreateError:
+
+       return eError;
+#endif
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitAllocFWImgMemKM(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                                                 IMG_DEVMEM_SIZE_T     uiFWCodeLen,
+                                                                                 IMG_DEVMEM_SIZE_T     uiFWDataLen,
+                                                                                 IMG_DEVMEM_SIZE_T     uiFWCorememLen,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWCodeAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR              *psFWCodeDevVAddrBase,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWDataAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR              *psFWDataDevVAddrBase,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWCorememAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR              *psFWCorememDevVAddrBase,
+                                                                                 RGXFWIF_DEV_VIRTADDR  *psFWCorememMetaVAddrBase)
+{
+       DEVMEM_FLAGS_T          uiMemAllocFlags;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_ERROR        eError;
+
+       /* set up memory contexts */
+
+       /* Register callbacks for creation of device memory contexts */
+       psDeviceNode->pfnRegisterMemoryContext = RGXRegisterMemoryContext;
+       psDeviceNode->pfnUnregisterMemoryContext = RGXUnregisterMemoryContext;
+
+       /* Create the memory context for the firmware. */
+       eError = DevmemCreateContext(IMG_NULL, psDeviceNode,
+                                                                DEVMEM_HEAPCFG_META,
+                                                                &psDevInfo->psKernelDevmemCtx);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitAllocFWImgMemKM: Failed DevmemCreateContext (%u)", eError));
+               goto failed_to_create_ctx;
+       }
+       
+       eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx,
+                                                                 "Firmware", /* FIXME: We need to create an IDENT macro for this string.
+                                                                                Make sure the IDENT macro is not accessible to userland */
+                                                                 &psDevInfo->psFirmwareHeap);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitAllocFWImgMemKM: Failed DevmemFindHeapByName (%u)", eError));
+               goto failed_to_find_heap;
+       }
+
+       /* 
+        * Set up Allocation for FW code section 
+        */
+       uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                         PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                         PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                         PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                         PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                         PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                         PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE;
+
+
+       eError = RGXAllocateFWCodeRegion(psDeviceNode,
+                                     uiFWCodeLen,
+                                        uiMemAllocFlags);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to allocate fw code mem (%u)",
+                               eError));
+               goto failFWCodeMemDescAlloc;
+       }
+
+       eError = DevmemExport(psDevInfo->psRGXFWCodeMemDesc,
+                             &psDevInfo->sRGXFWCodeExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to export fw code mem (%u)",
+                               eError));
+               goto failFWCodeMemDescExport;
+       }
+
+       eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWCodeMemDesc,
+                                         psFWCodeDevVAddrBase);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to acquire devVAddr for fw code mem (%u)",
+                               eError));
+               goto failFWCodeMemDescAqDevVirt;
+       }
+
+       /*
+       * The FW code must be the first allocation in the firmware heap, otherwise
+       * the bootloader will not work (META will not be able to find the bootloader).
+       */
+       PVR_ASSERT(psFWCodeDevVAddrBase->uiAddr == RGX_FIRMWARE_HEAP_BASE);
+
+       /* 
+        * Set up Allocation for FW data section 
+        */
+       uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                         PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                         PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                         PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                         PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                         PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                         PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                         PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                         PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+       PDUMPCOMMENT("Allocate and export data memory for fw");
+
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               uiFWDataLen,
+                                                                               uiMemAllocFlags,
+                                                                               "FirmwareDataRegion",
+                                           &psDevInfo->psRGXFWDataMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to allocate fw data mem (%u)",
+                               eError));
+               goto failFWDataMemDescAlloc;
+       }
+
+       eError = DevmemExport(psDevInfo->psRGXFWDataMemDesc,
+                             &psDevInfo->sRGXFWDataExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to export fw data mem (%u)",
+                               eError));
+               goto failFWDataMemDescExport;
+       }
+
+       eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWDataMemDesc,
+                                         psFWDataDevVAddrBase);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed to acquire devVAddr for fw data mem (%u)",
+                               eError));
+               goto failFWDataMemDescAqDevVirt;
+       }
+
+       if (uiFWCorememLen != 0)
+       {
+               /* 
+                * Set up Allocation for FW coremem section 
+                */
+               uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                       PVRSRV_MEMALLOCFLAG_GPU_READABLE | 
+                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                       PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                       PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                       PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+
+               PDUMPCOMMENT("Allocate and export coremem memory for fw");
+
+               eError = DevmemFwAllocateExportable(psDeviceNode,
+                               uiFWCorememLen,
+                               uiMemAllocFlags,
+                               "FirmwareCorememRegion",
+                               &psDevInfo->psRGXFWCorememMemDesc);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"Failed to allocate fw coremem mem, size: %lld, flags: %x (%u)",
+                                               uiFWCorememLen, uiMemAllocFlags, eError));
+                       goto failFWCorememMemDescAlloc;
+               }
+
+               eError = DevmemExport(psDevInfo->psRGXFWCorememMemDesc,
+                               &psDevInfo->sRGXFWCorememExportCookie);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"Failed to export fw coremem mem (%u)",
+                                               eError));
+                       goto failFWCorememMemDescExport;
+               }
+
+               eError = DevmemAcquireDevVirtAddr(psDevInfo->psRGXFWCorememMemDesc,
+                               psFWCorememDevVAddrBase);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"Failed to acquire devVAddr for fw coremem mem (%u)",
+                                               eError));
+                       goto failFWCorememMemDescAqDevVirt;
+               }
+
+               RGXSetFirmwareAddress(psFWCorememMetaVAddrBase,
+                               psDevInfo->psRGXFWCorememMemDesc,
+                               0, RFW_FWADDR_NOREF_FLAG);
+
+#if defined(HW_ERN_45914)
+               /* temporarily make sure the coremem is init using the SLC */
+               psFWCorememMetaVAddrBase->ui32Addr &= ~RGXFW_SEGMMU_DMAP_ADDR_START;
+               psFWCorememMetaVAddrBase->ui32Addr |= RGXFW_BOOTLDR_META_ADDR;
+#endif
+
+       }
+
+       *ppsFWCodeAllocServerExportCookie = &psDevInfo->sRGXFWCodeExportCookie;
+       *ppsFWDataAllocServerExportCookie = &psDevInfo->sRGXFWDataExportCookie;
+       /* Set all output arguments to ensure safe use in Part2 initialisation */
+       *ppsFWCorememAllocServerExportCookie = &psDevInfo->sRGXFWCorememExportCookie;
+
+       return PVRSRV_OK;
+
+
+failFWCorememMemDescAqDevVirt:
+
+       if (uiFWCorememLen != 0)
+       {
+               DevmemUnexport(psDevInfo->psRGXFWCorememMemDesc, &psDevInfo->sRGXFWCorememExportCookie);
+       }
+failFWCorememMemDescExport:
+
+       if (uiFWCorememLen != 0)
+       {
+               DevmemFwFree(psDevInfo->psRGXFWCorememMemDesc);
+               psDevInfo->psRGXFWCorememMemDesc = IMG_NULL;
+       }
+failFWCorememMemDescAlloc:
+
+       DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWDataMemDesc);
+failFWDataMemDescAqDevVirt:
+
+       DevmemUnexport(psDevInfo->psRGXFWDataMemDesc, &psDevInfo->sRGXFWDataExportCookie);
+failFWDataMemDescExport:
+
+       DevmemFwFree(psDevInfo->psRGXFWDataMemDesc);
+       psDevInfo->psRGXFWDataMemDesc = IMG_NULL;
+failFWDataMemDescAlloc:
+
+       DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWCodeMemDesc);
+failFWCodeMemDescAqDevVirt:
+
+       DevmemUnexport(psDevInfo->psRGXFWCodeMemDesc, &psDevInfo->sRGXFWCodeExportCookie);
+failFWCodeMemDescExport:
+
+       DevmemFwFree(psDevInfo->psRGXFWCodeMemDesc);
+       psDevInfo->psRGXFWCodeMemDesc = IMG_NULL;
+failFWCodeMemDescAlloc:
+
+failed_to_find_heap:
+       /*
+        * Clear the mem context create callbacks before destroying the RGX firmware
+        * context to avoid a spurious callback.
+        */
+       psDeviceNode->pfnRegisterMemoryContext = IMG_NULL;
+       psDeviceNode->pfnUnregisterMemoryContext = IMG_NULL;
+       DevmemDestroyContext(psDevInfo->psKernelDevmemCtx);
+       psDevInfo->psKernelDevmemCtx = IMG_NULL;
+failed_to_create_ctx:
+
+       return eError;
+}
+
+/*
+ * PVRSRVRGXInitFirmwareKM
+ */ 
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitFirmwareKM(PVRSRV_DEVICE_NODE                        *psDeviceNode, 
+                                                                           RGXFWIF_DEV_VIRTADDR                *psRGXFwInit,
+                                                                           IMG_BOOL                                    bEnableSignatureChecks,
+                                                                           IMG_UINT32                                  ui32SignatureChecksBufSize,
+                                                                           IMG_UINT32                                  ui32HWPerfFWBufSizeKB,
+                                                                           IMG_UINT64                                  ui64HWPerfFilter,
+                                                                           IMG_UINT32                                  ui32RGXFWAlignChecksSize,
+                                                                           IMG_UINT32                                  *pui32RGXFWAlignChecks,
+                                                                           IMG_UINT32                                  ui32ConfigFlags,
+                                                                           IMG_UINT32                                  ui32LogType,
+                                                                           IMG_UINT32                                  ui32FilterFlags,
+                                                                           IMG_UINT32                                  ui32JonesDisableMask,
+                                                                           IMG_UINT32                                  ui32HWRDebugDumpLimit,
+                                                                           RGXFWIF_COMPCHECKS_BVNC     *psClientBVNC,
+                                                                               IMG_UINT32                                      ui32HWPerfCountersDataSize,
+                                                                               DEVMEM_EXPORTCOOKIE     **ppsHWPerfDataAllocServerExportCookie,
+                                                                           RGX_RD_POWER_ISLAND_CONF                    eRGXRDPowerIslandingConf)
+{
+       PVRSRV_ERROR                            eError;
+       RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sBVNC);
+       IMG_BOOL bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV;
+       IMG_UINT32 ui32NumBIFTilingConfigs, *pui32BIFTilingXStrides, i;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+
+       /* Check if BVNC numbers of client and driver are compatible */
+       rgx_bvnc_packed(&sBVNC.ui32BNC, sBVNC.aszV, sBVNC.ui32VLenMax, RGX_BVNC_KM_B, RGX_BVNC_KM_V_ST, RGX_BVNC_KM_N, RGX_BVNC_KM_C);
+
+       RGX_BVNC_EQUAL(sBVNC, *psClientBVNC, bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV);
+
+       if (!bCompatibleAll)
+       {
+               if (!bCompatibleVersion)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible compatibility struct version of driver (%d) and client (%d).",
+                                       __FUNCTION__, 
+                                       sBVNC.ui32LayoutVersion, 
+                                       psClientBVNC->ui32LayoutVersion));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       PVR_DBG_BREAK;
+                       goto failed_to_pass_compatibility_check;
+               }
+
+               if (!bCompatibleLenMax)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible V maxlen of driver (%d) and client (%d).",
+                                       __FUNCTION__, 
+                                       sBVNC.ui32VLenMax, 
+                                       psClientBVNC->ui32VLenMax));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       PVR_DBG_BREAK;
+                       goto failed_to_pass_compatibility_check;
+               }
+
+               if (!bCompatibleBNC)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible driver BNC (%d._.%d.%d) / client BNC (%d._.%d.%d).",
+                                       __FUNCTION__, 
+                                       RGX_BVNC_PACKED_EXTR_B(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(*psClientBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(*psClientBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(*psClientBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       PVR_DBG_BREAK;
+                       goto failed_to_pass_compatibility_check;
+               }
+               
+               if (!bCompatibleV)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible driver BVNC (%d.%s.%d.%d) / client BVNC (%d.%s.%d.%d).",
+                                       __FUNCTION__, 
+                                       RGX_BVNC_PACKED_EXTR_B(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(*psClientBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(*psClientBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(*psClientBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(*psClientBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       PVR_DBG_BREAK;
+                       goto failed_to_pass_compatibility_check;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: COMPAT_TEST: driver BVNC (%d.%s.%d.%d) and client BVNC (%d.%s.%d.%d) match. [ OK ]",
+                               __FUNCTION__, 
+                               RGX_BVNC_PACKED_EXTR_B(sBVNC), 
+                               RGX_BVNC_PACKED_EXTR_V(sBVNC), 
+                               RGX_BVNC_PACKED_EXTR_N(sBVNC), 
+                               RGX_BVNC_PACKED_EXTR_C(sBVNC), 
+                               RGX_BVNC_PACKED_EXTR_B(*psClientBVNC), 
+                               RGX_BVNC_PACKED_EXTR_V(*psClientBVNC), 
+                               RGX_BVNC_PACKED_EXTR_N(*psClientBVNC), 
+                               RGX_BVNC_PACKED_EXTR_C(*psClientBVNC)));
+       }
+
+       GetNumBifTilingHeapConfigs(&ui32NumBIFTilingConfigs);
+       pui32BIFTilingXStrides = OSAllocMem(sizeof(IMG_UINT32) * ui32NumBIFTilingConfigs);
+       if(pui32BIFTilingXStrides == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitFirmwareKM: OSAllocMem failed (%u)", eError));
+               goto failed_BIF_tiling_alloc;
+       }
+       for(i = 0; i < ui32NumBIFTilingConfigs; i++)
+       {
+               eError = GetBIFTilingHeapXStride(i+1, &pui32BIFTilingXStrides[i]);
+               if(eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitFirmwareKM: GetBIFTilingHeapXStride for heap %u failed (%u)",
+                                i + 1, eError));
+                       goto failed_BIF_heap_init;
+               }
+       }
+
+       eError = RGXSetupFirmware(psDeviceNode, 
+                                                            bEnableSignatureChecks, 
+                                                            ui32SignatureChecksBufSize,
+                                                            ui32HWPerfFWBufSizeKB,
+                                                            ui64HWPerfFilter,
+                                                            ui32RGXFWAlignChecksSize,
+                                                            pui32RGXFWAlignChecks,
+                                                            ui32ConfigFlags,
+                                                            ui32LogType,
+                                                            ui32NumBIFTilingConfigs,
+                                                            pui32BIFTilingXStrides,
+                                                            ui32FilterFlags,
+                                                            ui32JonesDisableMask,
+                                                            ui32HWRDebugDumpLimit,
+                                                            ui32HWPerfCountersDataSize,
+                                                            psRGXFwInit,
+                                                            eRGXRDPowerIslandingConf);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXInitFirmwareKM: RGXSetupFirmware failed (%u)", eError));
+               goto failed_init_firmware;
+       }
+       *ppsHWPerfDataAllocServerExportCookie = &psDevInfo->sRGXFWHWPerfCountersExportCookie;
+       
+       OSFreeMem(pui32BIFTilingXStrides);
+       return PVRSRV_OK;
+
+failed_init_firmware:
+failed_BIF_heap_init:
+       OSFreeMem(pui32BIFTilingXStrides);
+failed_BIF_tiling_alloc:
+failed_to_pass_compatibility_check:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+
+
+/* See device.h for function declaration */
+static PVRSRV_ERROR RGXAllocUFOBlock(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                        DEVMEM_MEMDESC **psMemDesc,
+                                                                        IMG_UINT32 *puiSyncPrimVAddr,
+                                                                        IMG_UINT32 *puiSyncPrimBlockSize)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+       PVRSRV_ERROR eError;
+       RGXFWIF_DEV_VIRTADDR pFirmwareAddr;
+       IMG_DEVMEM_SIZE_T uiUFOBlockSize = sizeof(IMG_UINT32);
+       IMG_DEVMEM_ALIGN_T ui32UFOBlockAlign = sizeof(IMG_UINT32);
+
+       psDevInfo = psDeviceNode->pvDevice;
+
+       /* Size and align are 'expanded' because we request an Exportalign allocation */
+       DevmemExportalignAdjustSizeAndAlign(psDevInfo->psFirmwareHeap,
+                                                                               &uiUFOBlockSize,
+                                                                               &ui32UFOBlockAlign);
+
+       eError = DevmemFwAllocateExportable(psDeviceNode,
+                                                                               uiUFOBlockSize,
+                                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                                               PVRSRV_MEMALLOCFLAG_CACHE_COHERENT | 
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE,
+                                                                               "UFOBlock",
+                                                                               psMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       DevmemPDumpLoadMem(*psMemDesc,
+                                          0,
+                                          uiUFOBlockSize,
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       RGXSetFirmwareAddress(&pFirmwareAddr, *psMemDesc, 0, RFW_FWADDR_FLAG_NONE);
+       *puiSyncPrimVAddr = pFirmwareAddr.ui32Addr;
+       *puiSyncPrimBlockSize = TRUNCATE_64BITS_TO_32BITS(uiUFOBlockSize);
+
+       return PVRSRV_OK;
+
+       DevmemFwFree(*psMemDesc);
+e0:
+       return eError;
+}
+
+/* See device.h for function declaration */
+static IMG_VOID RGXFreeUFOBlock(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                               DEVMEM_MEMDESC *psMemDesc)
+{
+       /*
+               If the system has snooping of the device cache then the UFO block
+               might be in the cache so we need to flush it out before freeing
+               the memory
+       */
+       if (PVRSRVSystemSnoopingOfDeviceCache())
+       {
+               RGXFWIF_KCCB_CMD sFlushInvalCmd;
+               PVRSRV_ERROR eError;
+
+               /* Schedule the SLC flush command ... */
+#if defined(PDUMP)
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Submit SLC flush and invalidate");
+#endif
+               sFlushInvalCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_TRUE;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_FALSE;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.eDM = 0;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.psContext.ui32Addr = 0;
+
+               eError = RGXSendCommandWithPowLock(psDeviceNode->pvDevice,
+                                                                                       RGXFWIF_DM_GP,
+                                                                                       &sFlushInvalCmd,
+                                                                                       sizeof(sFlushInvalCmd),
+                                                                                       IMG_TRUE);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXFreeUFOBlock: Failed to schedule SLC flush command with error (%u)", eError));
+               }
+               else
+               {
+                       /* Wait for the SLC flush to complete */
+                       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXFreeUFOBlock: SLC flush and invalidate aborted with error (%u)", eError));
+                       }
+               }
+       }
+
+       RGXUnsetFirmwareAddress(psMemDesc);
+       DevmemFwFree(psMemDesc);
+}
+
+/*
+       DevDeInitRGX
+*/
+PVRSRV_ERROR DevDeInitRGX (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_RGXDEV_INFO                      *psDevInfo = (PVRSRV_RGXDEV_INFO*)psDeviceNode->pvDevice;
+       PVRSRV_ERROR                            eError;
+       DEVICE_MEMORY_INFO                  *psDevMemoryInfo;
+
+       if (!psDevInfo)
+       {
+               /* Can happen if DevInitRGX failed */
+               PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: Null DevInfo"));
+               return PVRSRV_OK;
+       }
+
+       /* Unregister debug request notifiers first as they could depend on anything. */
+       PVRSRVUnregisterDbgRequestNotify(psDeviceNode->hDbgReqNotify);
+
+       /* Cancel notifications to this device */
+       PVRSRVUnregisterCmdCompleteNotify(psDeviceNode->hCmdCompNotify);
+       psDeviceNode->hCmdCompNotify = IMG_NULL;
+
+       /*
+        *  De-initialise in reverse order, so stage 2 init is undone first.
+        */
+       if (g_bDevInit2Done)
+       {
+               g_bDevInit2Done = IMG_FALSE;
+
+#if !defined(NO_HARDWARE)
+               (IMG_VOID) OSUninstallDeviceLISR(psDevInfo->pvLISRData);
+               (IMG_VOID) OSUninstallMISR(psDevInfo->pvMISRData);
+               (IMG_VOID) OSUninstallMISR(psDevInfo->hProcessQueuesMISR);
+               if (psDevInfo->pvAPMISRData != IMG_NULL)
+               {
+                       (IMG_VOID) OSUninstallMISR(psDevInfo->pvAPMISRData);
+               }
+#endif /* !NO_HARDWARE */
+
+               /* Remove the device from the power manager */
+               eError = PVRSRVRemovePowerDevice(psDeviceNode->sDevId.ui32DeviceIndex);
+               if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+
+               OSLockDestroy(psDevInfo->hGPUUtilLock);
+
+               /* Free DVFS Table */
+               if (psDevInfo->psGpuDVFSTable != IMG_NULL)
+               {
+                       OSFreeMem(psDevInfo->psGpuDVFSTable);
+                       psDevInfo->psGpuDVFSTable = IMG_NULL;
+               }
+
+               /* De-init Freelists/ZBuffers... */
+               OSLockDestroy(psDevInfo->hLockFreeList);
+               OSLockDestroy(psDevInfo->hLockZSBuffer);
+
+               /* De-init HWPerf Ftrace thread resources for the RGX device */
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+               RGXHWPerfFTraceGPUDeInit(psDevInfo);
+#endif
+
+               /* Unregister MMU related stuff */
+               eError = RGXMMUInit_Unregister(psDeviceNode);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: Failed RGXMMUInit_Unregister (0x%x)", eError));
+                       return eError;
+               }
+
+               /* UnMap Regs */
+               if (psDevInfo->pvRegsBaseKM != IMG_NULL)
+               {
+#if !defined(NO_HARDWARE)
+                       OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
+                                                        psDevInfo->ui32RegSize,
+                                                        0);
+#endif /* !NO_HARDWARE */
+                       psDevInfo->pvRegsBaseKM = IMG_NULL;
+               }
+       }
+
+#if 0 /* not required at this time */
+       if (psDevInfo->hTimer)
+       {
+               eError = OSRemoveTimer(psDevInfo->hTimer);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: Failed to remove timer"));
+                       return  eError;
+               }
+               psDevInfo->hTimer = IMG_NULL;
+       }
+#endif
+
+    psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+
+       RGX_DeInitHeaps(psDevMemoryInfo);
+
+       if (psDevInfo->psRGXFWCodeMemDesc)
+       {
+               /* Free fw code */
+               PDUMPCOMMENT("Freeing FW code memory");
+               if (DevmemIsValidExportCookie(&psDevInfo->sRGXFWCodeExportCookie))
+               {
+                       /* if the export cookie is valid, the init sequence failed */
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: FW Code Export cookie still valid (should have been unexported at init time)"));
+                       DevmemUnexport(psDevInfo->psRGXFWCodeMemDesc, &psDevInfo->sRGXFWCodeExportCookie);
+               }
+               DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWCodeMemDesc);
+               DevmemFwFree(psDevInfo->psRGXFWCodeMemDesc);
+               psDevInfo->psRGXFWCodeMemDesc = IMG_NULL;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR,"No firmware code memory to free!"));
+       }
+
+       if (psDevInfo->psRGXFWDataMemDesc)
+       {
+               /* Free fw data */
+               PDUMPCOMMENT("Freeing FW data memory");
+               if (DevmemIsValidExportCookie(&psDevInfo->sRGXFWDataExportCookie))
+               {
+                       /* if the export cookie is valid, the init sequence failed */
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: FW Data Export cookie still valid (should have been unexported at init time)"));
+                       DevmemUnexport(psDevInfo->psRGXFWDataMemDesc, &psDevInfo->sRGXFWDataExportCookie);
+               }
+               DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWDataMemDesc);
+               DevmemFwFree(psDevInfo->psRGXFWDataMemDesc);
+               psDevInfo->psRGXFWDataMemDesc = IMG_NULL;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR,"No firmware data memory to free!"));
+       }
+
+       if (psDevInfo->psRGXFWCorememMemDesc)
+       {
+               /* Free fw data */
+               PDUMPCOMMENT("Freeing FW coremem memory");
+               if (DevmemIsValidExportCookie(&psDevInfo->sRGXFWCorememExportCookie))
+               {
+                       /* if the export cookie is valid, the init sequence failed */
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitRGX: FW Coremem Export cookie still valid (should have been unexported at init time)"));
+                       DevmemUnexport(psDevInfo->psRGXFWCorememMemDesc, &psDevInfo->sRGXFWCorememExportCookie);
+               }
+               DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWCorememMemDesc);
+               DevmemFwFree(psDevInfo->psRGXFWCorememMemDesc);
+               psDevInfo->psRGXFWCorememMemDesc = IMG_NULL;
+       }
+
+       /*
+          Free the firmware allocations.
+        */
+       RGXFreeFirmware(psDevInfo);
+
+       /*
+        * Clear the mem context create callbacks before destroying the RGX firmware
+        * context to avoid a spurious callback.
+        */
+       psDeviceNode->pfnRegisterMemoryContext = IMG_NULL;
+       psDeviceNode->pfnUnregisterMemoryContext = IMG_NULL;
+
+       if (psDevInfo->psKernelDevmemCtx)
+       {
+               eError = DevmemDestroyContext(psDevInfo->psKernelDevmemCtx);
+               /* FIXME - this should return void */
+               PVR_ASSERT(eError == PVRSRV_OK);
+       }
+
+       /* destroy the context list locks */
+       OSWRLockDestroy(psDevInfo->hRenderCtxListLock);
+       OSWRLockDestroy(psDevInfo->hComputeCtxListLock);
+       OSWRLockDestroy(psDevInfo->hTransferCtxListLock);
+       OSWRLockDestroy(psDevInfo->hRaytraceCtxListLock);
+       OSWRLockDestroy(psDevInfo->hMemoryCtxListLock);
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       if (psDevInfo->hDebugFaultInfoLock != IMG_NULL)
+       {
+               OSLockDestroy(psDevInfo->hDebugFaultInfoLock);
+       }
+       if (psDevInfo->hMMUCtxUnregLock != IMG_NULL)
+       {
+               OSLockDestroy(psDevInfo->hMMUCtxUnregLock);
+       }
+#endif
+
+       /* Free the init scripts. */
+       OSFreeMem(psDevInfo->psScripts);
+
+       /* DeAllocate devinfo */
+       OSFreeMem(psDevInfo);
+
+       psDeviceNode->pvDevice = IMG_NULL;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ @Function     RGXDebugRequestNotify
+
+ @Description Dump the debug data for RGX
+  
+******************************************************************************/
+static IMG_VOID RGXDebugRequestNotify(PVRSRV_DBGREQ_HANDLE hDbgReqestHandle, IMG_UINT32 ui32VerbLevel)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode = hDbgReqestHandle;
+
+       /* Only action the request if we've fully init'ed */
+       if (g_bDevInit2Done)
+       {
+               RGXDebugRequestProcess(g_pfnDumpDebugPrintf, psDeviceNode->pvDevice, ui32VerbLevel);
+       }
+}
+
+#if defined(PDUMP)
+static
+PVRSRV_ERROR RGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)(psDeviceNode->pvDevice);
+       IMG_UINT32                      ui32Idx;
+
+       for (ui32Idx = 0; ui32Idx < RGXFWIF_DM_MAX; ui32Idx++)
+       {
+               psDevInfo->abDumpedKCCBCtlAlready[ui32Idx] = IMG_FALSE;
+       }
+
+
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+
+static INLINE DEVMEM_HEAP_BLUEPRINT _blueprint_init(IMG_CHAR *name,
+       IMG_UINT64 heap_base,
+       IMG_DEVMEM_SIZE_T heap_length,
+       IMG_UINT32 log2_import_alignment)
+{
+       DEVMEM_HEAP_BLUEPRINT b = {
+               .pszName = name,
+               .sHeapBaseAddr.uiAddr = heap_base,
+               .uiHeapLength = heap_length,
+               .uiLog2DataPageSize = GET_LOG2_PAGESIZE(),
+               .uiLog2ImportAlignment = log2_import_alignment
+       };
+
+       return b;
+}
+
+#define INIT_HEAP(NAME) \
+do { \
+       *psDeviceMemoryHeapCursor = _blueprint_init( \
+                       RGX_ ## NAME ## _HEAP_IDENT, \
+                       RGX_ ## NAME ## _HEAP_BASE, \
+                       RGX_ ## NAME ## _HEAP_SIZE, \
+                       0); \
+       psDeviceMemoryHeapCursor++; \
+} while (0)
+
+#define INIT_HEAP_NAME(STR, NAME) \
+do { \
+       *psDeviceMemoryHeapCursor = _blueprint_init( \
+                       STR, \
+                       RGX_ ## NAME ## _HEAP_BASE, \
+                       RGX_ ## NAME ## _HEAP_SIZE, \
+                       0); \
+       psDeviceMemoryHeapCursor++; \
+} while (0)
+
+#define INIT_TILING_HEAP(N) \
+do { \
+       IMG_UINT32 xstride; \
+       GetBIFTilingHeapXStride(N, &xstride); \
+       *psDeviceMemoryHeapCursor = _blueprint_init( \
+                       RGX_BIF_TILING_HEAP_ ## N ## _IDENT, \
+                       RGX_BIF_TILING_HEAP_ ## N ## _BASE, \
+                       RGX_BIF_TILING_HEAP_SIZE, \
+                       RGX_BIF_TILING_HEAP_ALIGN_LOG2_FROM_XSTRIDE(xstride)); \
+       psDeviceMemoryHeapCursor++; \
+} while (0)
+
+static PVRSRV_ERROR RGX_InitHeaps(DEVICE_MEMORY_INFO *psNewMemoryInfo)
+{
+    DEVMEM_HEAP_BLUEPRINT *psDeviceMemoryHeapCursor;
+
+    /* FIXME - consider whether this ought not to be on the device node itself */
+       psNewMemoryInfo->psDeviceMemoryHeap = OSAllocMem(sizeof(DEVMEM_HEAP_BLUEPRINT) * RGX_MAX_HEAP_ID);
+    if(psNewMemoryInfo->psDeviceMemoryHeap == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXRegisterDevice : Failed to alloc memory for DEVMEM_HEAP_BLUEPRINT"));
+               goto e0;
+       }
+
+       /* Initialise the heaps */
+       psDeviceMemoryHeapCursor = psNewMemoryInfo->psDeviceMemoryHeap;
+
+       INIT_HEAP(GENERAL);
+       INIT_HEAP(PDSCODEDATA);
+       INIT_HEAP(USCCODE);
+       INIT_HEAP(TQ3DPARAMETERS);
+       INIT_TILING_HEAP(1);
+       INIT_TILING_HEAP(2);
+       INIT_TILING_HEAP(3);
+       INIT_TILING_HEAP(4);
+       INIT_HEAP(DOPPLER);
+       INIT_HEAP(DOPPLER_OVERFLOW);
+#if defined(FIX_HW_BRN_37200)
+       INIT_HEAP_NAME("HWBRN37200", HWBRN37200);
+#endif
+       INIT_HEAP_NAME("Firmware", FIRMWARE);
+
+       /* set the heap count */
+       psNewMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeapCursor - psNewMemoryInfo->psDeviceMemoryHeap);
+
+       PVR_ASSERT(psNewMemoryInfo->ui32HeapCount <= RGX_MAX_HEAP_ID);
+
+    /* the new way: we'll set up 2 heap configs: one will be for Meta
+       only, and has only the firmware heap in it. 
+       The remaining one shall be for clients only, and shall have all
+       the other heaps in it */
+
+    psNewMemoryInfo->uiNumHeapConfigs = 2;
+       psNewMemoryInfo->psDeviceMemoryHeapConfigArray = OSAllocMem(sizeof(DEVMEM_HEAP_CONFIG) * psNewMemoryInfo->uiNumHeapConfigs);
+    if (psNewMemoryInfo->psDeviceMemoryHeapConfigArray == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXRegisterDevice : Failed to alloc memory for DEVMEM_HEAP_CONFIG"));
+               goto e1;
+       }
+    
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].pszName = "Default Heap Configuration";
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].uiNumHeaps = psNewMemoryInfo->ui32HeapCount-1;
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[0].psHeapBlueprintArray = psNewMemoryInfo->psDeviceMemoryHeap;
+
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].pszName = "Firmware Heap Configuration";
+#if defined(FIX_HW_BRN_37200)
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].uiNumHeaps = 2;
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].psHeapBlueprintArray = psDeviceMemoryHeapCursor-2;
+#else
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].uiNumHeaps = 1;
+    psNewMemoryInfo->psDeviceMemoryHeapConfigArray[1].psHeapBlueprintArray = psDeviceMemoryHeapCursor-1;
+#endif
+
+       return PVRSRV_OK;
+e1:
+       OSFreeMem(psNewMemoryInfo->psDeviceMemoryHeap);
+e0:
+       return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+#undef INIT_HEAP
+#undef INIT_HEAP_NAME
+#undef INIT_TILING_HEAP
+
+static IMG_VOID RGX_DeInitHeaps(DEVICE_MEMORY_INFO *psDevMemoryInfo)
+{
+       OSFreeMem(psDevMemoryInfo->psDeviceMemoryHeapConfigArray);
+       OSFreeMem(psDevMemoryInfo->psDeviceMemoryHeap);
+}
+
+
+/*
+       RGXRegisterDevice
+*/
+PVRSRV_ERROR RGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+    PVRSRV_ERROR eError;
+       DEVICE_MEMORY_INFO *psDevMemoryInfo;
+       PVRSRV_RGXDEV_INFO      *psDevInfo;
+
+       /* pdump info about the core */
+       PDUMPCOMMENT("RGX Version Information (KM): %s", RGX_BVNC_KM);
+       
+       #if defined(RGX_FEATURE_SYSTEM_CACHE)
+       PDUMPCOMMENT("RGX System Level Cache is present");
+       #endif /* RGX_FEATURE_SYSTEM_CACHE */
+
+       PDUMPCOMMENT("RGX Initialisation (Part 1)");
+
+       /*********************
+        * Device node setup *
+        *********************/
+       /* Setup static data and callbacks on the device agnostic device node */
+       psDeviceNode->sDevId.eDeviceType                = DEV_DEVICE_TYPE;
+       psDeviceNode->sDevId.eDeviceClass               = DEV_DEVICE_CLASS;
+#if defined(PDUMP)
+       psDeviceNode->sDevId.pszPDumpRegName    = RGX_PDUMPREG_NAME;
+       /*
+               FIXME: This should not be required as PMR's should give the memspace
+               name. However, due to limitations within PDump we need a memspace name
+               when dpumping with MMU context with virtual address in which case we
+               don't have a PMR to get the name from.
+               
+               There is also the issue obtaining a namespace name for the catbase which
+               is required when we PDump the write of the physical catbase into the FW
+               structure
+       */
+       psDeviceNode->sDevId.pszPDumpDevName    = PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
+       psDeviceNode->pfnPDumpInitDevice = &RGXResetPDump;
+#endif /* PDUMP */
+
+       psDeviceNode->eHealthStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK;
+       psDeviceNode->eHealthReason = PVRSRV_DEVICE_HEALTH_REASON_NONE;
+
+       /* Configure MMU specific stuff */
+       RGXMMUInit_Register(psDeviceNode);
+
+       psDeviceNode->pfnMMUCacheInvalidate = RGXMMUCacheInvalidate;
+
+       psDeviceNode->pfnSLCCacheInvalidateRequest = RGXSLCCacheInvalidateRequest;
+
+       /* Register RGX to receive notifies when other devices complete some work */
+       PVRSRVRegisterCmdCompleteNotify(&psDeviceNode->hCmdCompNotify, &RGXScheduleProcessQueuesKM, psDeviceNode);
+
+       psDeviceNode->pfnInitDeviceCompatCheck  = &RGXDevInitCompatCheck;
+
+       /* Register callbacks for creation of device memory contexts */
+       psDeviceNode->pfnRegisterMemoryContext = RGXRegisterMemoryContext;
+       psDeviceNode->pfnUnregisterMemoryContext = RGXUnregisterMemoryContext;
+
+       /* Register callbacks for Unified Fence Objects */
+       psDeviceNode->pfnAllocUFOBlock = RGXAllocUFOBlock;
+       psDeviceNode->pfnFreeUFOBlock = RGXFreeUFOBlock;
+
+       /* Register callback for dumping debug info */
+       PVRSRVRegisterDbgRequestNotify(&psDeviceNode->hDbgReqNotify, &RGXDebugRequestNotify, DEBUG_REQUEST_RGX, psDeviceNode);
+       
+       /* Register callback for checking the device's health */
+       psDeviceNode->pfnUpdateHealthStatus = RGXUpdateHealthStatus;
+
+       /* Register method to service the FW HWPerf buffer */
+       psDeviceNode->pfnServiceHWPerf = RGXHWPerfDataStoreCB;
+
+       /* Register callback for getting the device version information string */
+       psDeviceNode->pfnDeviceVersionString = RGXDevVersionString;
+
+       /* Register callback for getting the device clock speed */
+       psDeviceNode->pfnDeviceClockSpeed = RGXDevClockSpeed;
+
+       /* Register callback for soft resetting some device modules */
+       psDeviceNode->pfnSoftReset = RGXSoftReset;
+
+       /* Register callback for resetting the HWR logs */
+       psDeviceNode->pfnResetHWRLogs = RGXResetHWRLogs;
+
+
+       /*********************
+        * Device info setup *
+        *********************/
+       /* Allocate device control block */
+       psDevInfo = OSAllocMem(sizeof(*psDevInfo));
+       if (psDevInfo == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DevInitRGXPart1 : Failed to alloc memory for DevInfo"));
+               return (PVRSRV_ERROR_OUT_OF_MEMORY);
+       }
+       OSMemSet (psDevInfo, 0, sizeof(*psDevInfo));
+
+       /* create locks for the context lists stored in the DevInfo structure.
+        * these lists are modified on context create/destroy and read by the
+        * watchdog thread
+        */
+
+       eError = OSWRLockCreate(&(psDevInfo->hRenderCtxListLock));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create render context list lock", __func__));
+               goto e0;
+       }
+
+       eError = OSWRLockCreate(&(psDevInfo->hComputeCtxListLock));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create compute context list lock", __func__));
+               goto e1;
+       }
+
+       eError = OSWRLockCreate(&(psDevInfo->hTransferCtxListLock));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create transfer context list lock", __func__));
+               goto e2;
+       }
+
+       eError = OSWRLockCreate(&(psDevInfo->hRaytraceCtxListLock));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create raytrace context list lock", __func__));
+               goto e3;
+       }
+
+       eError = OSWRLockCreate(&(psDevInfo->hMemoryCtxListLock));
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create memory context list lock", __func__));
+               goto e4;
+       }
+
+       dllist_init(&(psDevInfo->sRenderCtxtListHead));
+       dllist_init(&(psDevInfo->sComputeCtxtListHead));
+       dllist_init(&(psDevInfo->sTransferCtxtListHead));
+       dllist_init(&(psDevInfo->sRaytraceCtxtListHead));
+
+       dllist_init(&(psDevInfo->sCommonCtxtListHead));
+       psDevInfo->ui32CommonCtxtCurrentID = 1;
+
+       dllist_init(&psDevInfo->sMemoryContextList);
+
+       /* Allocate space for scripts. */
+       psDevInfo->psScripts = OSAllocMem(sizeof(*psDevInfo->psScripts));
+       if (!psDevInfo->psScripts)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate memory for scripts", __func__));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e5;
+       }
+
+       /* Setup static data and callbacks on the device specific device info */
+       psDevInfo->eDeviceType          = DEV_DEVICE_TYPE;
+       psDevInfo->eDeviceClass         = DEV_DEVICE_CLASS;
+       psDevInfo->psDeviceNode         = psDeviceNode;
+
+       psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+       psDevMemoryInfo->ui32AddressSpaceSizeLog2 = RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS;
+       psDevInfo->pvDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+       /* flags, backing store details to be specified by system */
+       psDevMemoryInfo->ui32Flags = 0;
+
+       eError = RGX_InitHeaps(psDevMemoryInfo);
+       if (eError != PVRSRV_OK)
+       {
+               goto e6;
+       }
+
+       psDeviceNode->pvDevice = psDevInfo;
+       return PVRSRV_OK;
+
+e6:
+       OSFreeMem(psDevInfo->psScripts);
+e5:
+       OSWRLockDestroy(psDevInfo->hMemoryCtxListLock);
+e4:
+       OSWRLockDestroy(psDevInfo->hRaytraceCtxListLock);
+e3:
+       OSWRLockDestroy(psDevInfo->hTransferCtxListLock);
+e2:
+       OSWRLockDestroy(psDevInfo->hComputeCtxListLock);
+e1:
+       OSWRLockDestroy(psDevInfo->hRenderCtxListLock);
+e0:
+       OSFreeMem(psDevInfo);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver
+
+ @Description
+
+ Validate the FW build options against KM driver build options (KM build options only)
+
+ Following check is reduntant, because next check checks the same bits.
+ Redundancy occurs because if client-server are build-compatible and client-firmware are 
+ build-compatible then server-firmware are build-compatible as well.
+ This check is left for clarity in error messages if any incompatibility occurs.
+
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver(RGXFWIF_INIT *psRGXFWInit)
+{
+#if !defined(NO_HARDWARE)
+       IMG_UINT32                      ui32BuildOptions, ui32BuildOptionsFWKMPart, ui32BuildOptionsMismatch;
+
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       ui32BuildOptions = (RGX_BUILD_OPTIONS_KM);
+
+       ui32BuildOptionsFWKMPart = psRGXFWInit->sRGXCompChecks.ui32BuildOptions & RGX_BUILD_OPTIONS_MASK_KM;
+       
+       if (ui32BuildOptions != ui32BuildOptionsFWKMPart)
+       {
+               ui32BuildOptionsMismatch = ui32BuildOptions ^ ui32BuildOptionsFWKMPart;
+               if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and KM driver build options; "
+                               "extra options present in the KM driver: (0x%x). Please check rgx_options_km.h",
+                               ui32BuildOptions & ui32BuildOptionsMismatch ));
+               }
+
+               if ( (ui32BuildOptionsFWKMPart & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware-side and KM driver build options; "
+                               "extra options present in Firmware: (0x%x). Please check rgx_options_km.h",
+                               ui32BuildOptionsFWKMPart & ui32BuildOptionsMismatch ));
+               }
+               return PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware and KM driver build options match. [ OK ]"));
+       }
+#endif
+
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_BuildOptions_FWAgainstClient
+
+ @Description
+
+ Validate the FW build options against client build options (KM and non-KM)
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+ @Input ui32ClientBuildOptions - client build options flags
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck_BuildOptions_FWAgainstClient(PVRSRV_RGXDEV_INFO      *psDevInfo,
+                                                                                                                                                       RGXFWIF_INIT *psRGXFWInit,
+                                                                                                                                                       IMG_UINT32 ui32ClientBuildOptions)
+{
+#if !defined(NO_HARDWARE)
+       IMG_UINT32                      ui32BuildOptionsMismatch;
+       IMG_UINT32                      ui32BuildOptionsFW;
+#endif
+#if defined(PDUMP)
+       PVRSRV_ERROR            eError;
+#endif
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Compatibility check: client and FW build options");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, ui32BuildOptions),
+                                                                                               ui32ClientBuildOptions,
+                                                                                               0xffffffff,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+#endif
+
+#if !defined(NO_HARDWARE)
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       
+       ui32BuildOptionsFW = psRGXFWInit->sRGXCompChecks.ui32BuildOptions;
+       
+       if (ui32ClientBuildOptions != ui32BuildOptionsFW)
+       {
+               ui32BuildOptionsMismatch = ui32ClientBuildOptions ^ ui32BuildOptionsFW;
+               if ( (ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; "
+                               "extra options present in client: (0x%x). Please check rgx_options.h",
+                               ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
+               }
+
+               if ( (ui32BuildOptionsFW & ui32BuildOptionsMismatch) != 0)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; "
+                               "extra options present in Firmware: (0x%x). Please check rgx_options.h",
+                               ui32BuildOptionsFW & ui32BuildOptionsMismatch ));
+               }
+               return PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware and client build options match. [ OK ]"));
+       }
+#endif
+
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver
+
+ @Description
+
+ Validate FW DDK version against driver DDK version
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                                                                                       RGXFWIF_INIT *psRGXFWInit)
+{
+#if defined(PDUMP)||(!defined(NO_HARDWARE))
+       IMG_UINT32                      ui32DDKVersion;
+       PVRSRV_ERROR            eError;
+       
+       ui32DDKVersion = PVRVERSION_PACK(PVRVERSION_MAJ, PVRVERSION_MIN);
+#endif
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Compatibility check: KM driver and FW DDK version");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, ui32DDKVersion),
+                                                                                               ui32DDKVersion,
+                                                                                               0xffffffff,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+#endif
+
+#if !defined(NO_HARDWARE)
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       if (psRGXFWInit->sRGXCompChecks.ui32DDKVersion != ui32DDKVersion)
+       {
+               PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible driver DDK revision (%u.%u) / Firmware DDK revision (%u.%u).",
+                               PVRVERSION_MAJ, PVRVERSION_MIN, 
+                               PVRVERSION_UNPACK_MAJ(psRGXFWInit->sRGXCompChecks.ui32DDKVersion),
+                               PVRVERSION_UNPACK_MIN(psRGXFWInit->sRGXCompChecks.ui32DDKVersion)));
+               eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
+               PVR_DBG_BREAK;
+               return eError;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: driver DDK revision (%u.%u) and Firmware DDK revision (%u.%u) match. [ OK ]",
+                               PVRVERSION_MAJ, PVRVERSION_MIN, 
+                               PVRVERSION_MAJ, PVRVERSION_MIN));
+       }
+#endif 
+
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver
+
+ @Description
+
+ Validate FW DDK build against driver DDK build
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                                                                                       RGXFWIF_INIT *psRGXFWInit)
+{
+#if defined(PDUMP)||(!defined(NO_HARDWARE))
+       IMG_UINT32                      ui32DDKBuild;
+       PVRSRV_ERROR            eError;
+       
+       ui32DDKBuild = PVRVERSION_BUILD;
+#endif
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Compatibility check: KM driver and FW DDK build");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, ui32DDKBuild),
+                                                                                               ui32DDKBuild,
+                                                                                               0xffffffff,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+#endif
+
+#if !defined(NO_HARDWARE)
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       if (psRGXFWInit->sRGXCompChecks.ui32DDKBuild != ui32DDKBuild)
+       {
+               PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible driver DDK build (%d) / Firmware DDK build (%d).",
+                               ui32DDKBuild, psRGXFWInit->sRGXCompChecks.ui32DDKBuild));
+               eError = PVRSRV_ERROR_DDK_BUILD_MISMATCH;
+               PVR_DBG_BREAK;
+               return eError;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: driver DDK build (%d) and Firmware DDK build (%d) match. [ OK ]",
+                               ui32DDKBuild, psRGXFWInit->sRGXCompChecks.ui32DDKBuild));
+       }
+#endif
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_BVNC_FWAgainstDriver
+
+ @Description
+
+ Validate FW BVNC against driver BVNC
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck_BVNC_FWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                                                                                       RGXFWIF_INIT *psRGXFWInit)
+{
+#if defined(PDUMP)
+       IMG_UINT32                                      i;
+#endif
+#if !defined(NO_HARDWARE)
+       IMG_BOOL bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV;
+#endif
+#if defined(PDUMP)||(!defined(NO_HARDWARE))
+       RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sBVNC);
+       PVRSRV_ERROR                            eError;
+       
+       rgx_bvnc_packed(&sBVNC.ui32BNC, sBVNC.aszV, sBVNC.ui32VLenMax, RGX_BVNC_KM_B, RGX_BVNC_KM_V_ST, RGX_BVNC_KM_N, RGX_BVNC_KM_C);
+#endif
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Compatibility check: KM driver and FW BVNC (struct version)");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                       offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) +
+                                                                                       offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32LayoutVersion),
+                                                                                       sBVNC.ui32LayoutVersion,
+                                                                                       0xffffffff,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+       }
+
+       PDUMPCOMMENT("Compatibility check: KM driver and FW BVNC (maxlen)");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                       offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) +
+                                                                                       offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32VLenMax),
+                                                                                       sBVNC.ui32VLenMax,
+                                                                                       0xffffffff,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+       }
+
+       PDUMPCOMMENT("Compatibility check: KM driver and FW BVNC (BNC part)");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                       offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) +
+                                                                                       offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32BNC),
+                                                                                       sBVNC.ui32BNC,
+                                                                                       0xffffffff,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+       }
+
+       for (i = 0; i < sBVNC.ui32VLenMax; i += sizeof(IMG_UINT32))
+       {
+               PDUMPCOMMENT("Compatibility check: KM driver and FW BVNC (V part)");
+               eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, sFWBVNC) +
+                                                                                               offsetof(RGXFWIF_COMPCHECKS_BVNC, aszV) + 
+                                                                                               i,
+                                                                                               *((IMG_UINT32 *)(sBVNC.aszV + i)),
+                                                                                               0xffffffff,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               }
+       }
+#endif
+
+#if !defined(NO_HARDWARE)
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       RGX_BVNC_EQUAL(sBVNC, psRGXFWInit->sRGXCompChecks.sFWBVNC, bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV);
+       
+       if (!bCompatibleAll)
+       {
+               if (!bCompatibleVersion)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible compatibility struct version of driver (%d) and firmware (%d).",
+                                       __FUNCTION__, 
+                                       sBVNC.ui32LayoutVersion, 
+                                       psRGXFWInit->sRGXCompChecks.sFWBVNC.ui32LayoutVersion));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+
+               if (!bCompatibleLenMax)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible V maxlen of driver (%d) and firmware (%d).",
+                                       __FUNCTION__, 
+                                       sBVNC.ui32VLenMax, 
+                                       psRGXFWInit->sRGXCompChecks.sFWBVNC.ui32VLenMax));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+
+               if (!bCompatibleBNC)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in KM driver BNC (%d._.%d.%d) and Firmware BNC (%d._.%d.%d)",
+                                       RGX_BVNC_PACKED_EXTR_B(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(psRGXFWInit->sRGXCompChecks.sFWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(psRGXFWInit->sRGXCompChecks.sFWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(psRGXFWInit->sRGXCompChecks.sFWBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+               
+               if (!bCompatibleV)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in KM driver BVNC (%d.%s.%d.%d) and Firmware BVNC (%d.%s.%d.%d)",
+                                       RGX_BVNC_PACKED_EXTR_B(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(psRGXFWInit->sRGXCompChecks.sFWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(psRGXFWInit->sRGXCompChecks.sFWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(psRGXFWInit->sRGXCompChecks.sFWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(psRGXFWInit->sRGXCompChecks.sFWBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware BVNC and KM driver BNVC match. [ OK ]"));
+       }
+#endif
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_BVNC_HWAgainstDriver
+
+ @Description
+
+ Validate HW BVNC against driver BVNC
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+#if ((!defined(NO_HARDWARE))&&(!defined(EMULATOR)))
+#define TARGET_SILICON  /* definition for everything that is not emu and not nohw configuration */
+#endif
+
+#if defined(FIX_HW_BRN_38835)
+#define COMPAT_BVNC_MASK_B
+#define COMPAT_BVNC_MASK_V
+#endif
+
+static PVRSRV_ERROR RGXDevInitCompatCheck_BVNC_HWAgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                                                                       RGXFWIF_INIT *psRGXFWInit)
+{
+#if defined(PDUMP) || defined(TARGET_SILICON)
+       IMG_UINT32 ui32MaskBNC = RGX_BVNC_PACK_MASK_B |
+                                                               RGX_BVNC_PACK_MASK_N |
+                                                               RGX_BVNC_PACK_MASK_C;
+
+       IMG_UINT32 bMaskV = IMG_FALSE;
+
+       PVRSRV_ERROR                            eError;
+       RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sSWBVNC);
+#endif
+
+#if defined(TARGET_SILICON)
+       RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(sHWBVNC);
+       IMG_BOOL bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV;
+#endif
+
+#if defined(PDUMP) || defined(TARGET_SILICON)
+
+#if defined(COMPAT_BVNC_MASK_B)
+       ui32MaskBNC &= ~RGX_BVNC_PACK_MASK_B;
+#endif
+#if defined(COMPAT_BVNC_MASK_V)
+       bMaskV = IMG_TRUE;
+#endif
+#if defined(COMPAT_BVNC_MASK_N)
+       ui32MaskBNC &= ~RGX_BVNC_PACK_MASK_N;
+#endif
+#if defined(COMPAT_BVNC_MASK_C)
+       ui32MaskBNC &= ~RGX_BVNC_PACK_MASK_C;
+#endif
+       
+       rgx_bvnc_packed(&sSWBVNC.ui32BNC, sSWBVNC.aszV, sSWBVNC.ui32VLenMax, RGX_BVNC_KM_B, RGX_BVNC_KM_V_ST, RGX_BVNC_KM_N, RGX_BVNC_KM_C);
+
+#if defined(FIX_HW_BRN_38344)
+       if (RGX_BVNC_KM_C >= 10)
+       {
+               ui32MaskBNC &= ~RGX_BVNC_PACK_MASK_C;
+       }
+#endif
+
+       if ((ui32MaskBNC != (RGX_BVNC_PACK_MASK_B | RGX_BVNC_PACK_MASK_N | RGX_BVNC_PACK_MASK_C)) || bMaskV)
+       {
+               PVR_LOG(("Compatibility checks: Ignoring fields: '%s%s%s%s' of HW BVNC.",
+                               ((!(ui32MaskBNC & RGX_BVNC_PACK_MASK_B))?("B"):("")), 
+                               ((bMaskV)?("V"):("")), 
+                               ((!(ui32MaskBNC & RGX_BVNC_PACK_MASK_N))?("N"):("")), 
+                               ((!(ui32MaskBNC & RGX_BVNC_PACK_MASK_C))?("C"):(""))));
+       }
+#endif
+
+#if defined(EMULATOR)
+       PVR_LOG(("Compatibility checks for emu target: Ignoring HW BVNC checks."));
+#endif
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("Compatibility check: Layout version of compchecks struct");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                       offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) +
+                                                                                       offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32LayoutVersion),
+                                                                                       sSWBVNC.ui32LayoutVersion,
+                                                                                       0xffffffff,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+
+       PDUMPCOMMENT("Compatibility check: HW V max len and FW V max len");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                       offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) +
+                                                                                       offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32VLenMax),
+                                                                                       sSWBVNC.ui32VLenMax,
+                                                                                       0xffffffff,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+
+       if (ui32MaskBNC != 0)
+       {
+               PDUMPIF("DISABLE_HWBNC_CHECK");
+               PDUMPELSE("DISABLE_HWBNC_CHECK");
+               PDUMPCOMMENT("Compatibility check: HW BNC and FW BNC");
+               eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) +
+                                                                                               offsetof(RGXFWIF_COMPCHECKS_BVNC, ui32BNC),
+                                                                                               sSWBVNC.ui32BNC,
+                                                                                               ui32MaskBNC,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+                       return eError;
+               }
+               PDUMPFI("DISABLE_HWBNC_CHECK");
+       }
+       if (!bMaskV)
+       {
+               IMG_UINT32 i;
+               PDUMPIF("DISABLE_HWV_CHECK");
+               PDUMPELSE("DISABLE_HWV_CHECK");
+               for (i = 0; i < sSWBVNC.ui32VLenMax; i += sizeof(IMG_UINT32))
+               {
+                       PDUMPCOMMENT("Compatibility check: HW V and FW V");
+                       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               offsetof(RGXFWIF_INIT, sRGXCompChecks) + 
+                                                                                               offsetof(RGXFWIF_COMPCHECKS, sHWBVNC) +
+                                                                                               offsetof(RGXFWIF_COMPCHECKS_BVNC, aszV) + 
+                                                                                               i,
+                                                                                               *((IMG_UINT32 *)(sSWBVNC.aszV + i)),
+                                                                                               0xffffffff,
+                                                                                               PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                               PDUMP_FLAGS_CONTINUOUS);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+                               return eError;
+                       }
+               }
+               PDUMPFI("DISABLE_HWV_CHECK");
+       }
+#endif
+
+#if defined(TARGET_SILICON)
+       if (psRGXFWInit == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+       
+       sHWBVNC = psRGXFWInit->sRGXCompChecks.sHWBVNC;
+
+       sHWBVNC.ui32BNC &= ui32MaskBNC;
+       sSWBVNC.ui32BNC &= ui32MaskBNC;
+
+       if (bMaskV)
+       {
+               sHWBVNC.aszV[0] = '\0';
+               sSWBVNC.aszV[0] = '\0';
+       }
+
+       RGX_BVNC_EQUAL(sSWBVNC, sHWBVNC, bCompatibleAll, bCompatibleVersion, bCompatibleLenMax, bCompatibleBNC, bCompatibleV);
+
+#if defined(FIX_HW_BRN_42480)
+       if (!bCompatibleAll && bCompatibleVersion)
+       {
+               if ((RGX_BVNC_PACKED_EXTR_B(sSWBVNC) == 1) &&
+                       !(OSStringCompare(RGX_BVNC_PACKED_EXTR_V(sSWBVNC),"76")) &&
+                       (RGX_BVNC_PACKED_EXTR_N(sSWBVNC) == 4) &&
+                       (RGX_BVNC_PACKED_EXTR_C(sSWBVNC) == 6))
+               {
+                       if ((RGX_BVNC_PACKED_EXTR_B(sHWBVNC) == 1) &&
+                               !(OSStringCompare(RGX_BVNC_PACKED_EXTR_V(sHWBVNC),"69")) &&
+                               (RGX_BVNC_PACKED_EXTR_N(sHWBVNC) == 4) &&
+                               (RGX_BVNC_PACKED_EXTR_C(sHWBVNC) == 4))
+                       {
+                               bCompatibleBNC = IMG_TRUE;
+                               bCompatibleLenMax = IMG_TRUE;
+                               bCompatibleV = IMG_TRUE;
+                               bCompatibleAll = IMG_TRUE;
+                       }
+               }
+       }
+#endif
+
+       if (!bCompatibleAll)
+       {
+               if (!bCompatibleVersion)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible compatibility struct version of HW (%d) and FW (%d).",
+                                       __FUNCTION__, 
+                                       sHWBVNC.ui32LayoutVersion, 
+                                       sSWBVNC.ui32LayoutVersion));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+
+               if (!bCompatibleLenMax)
+               {
+                       PVR_LOG(("(FAIL) %s: Incompatible V maxlen of HW (%d) and FW (%d).",
+                                       __FUNCTION__, 
+                                       sHWBVNC.ui32VLenMax, 
+                                       sSWBVNC.ui32VLenMax));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+
+               if (!bCompatibleBNC)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible HW BNC (%d._.%d.%d) and FW BNC (%d._.%d.%d).",
+                                       RGX_BVNC_PACKED_EXTR_B(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(sSWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sSWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sSWBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+               
+               if (!bCompatibleV)
+               {
+                       PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible HW BVNC (%d.%s.%d.%d) and FW BVNC (%d.%s.%d.%d).",
+                                       RGX_BVNC_PACKED_EXTR_B(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sHWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_B(sSWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_V(sSWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_N(sSWBVNC), 
+                                       RGX_BVNC_PACKED_EXTR_C(sSWBVNC)));
+                       eError = PVRSRV_ERROR_BVNC_MISMATCH;
+                       return eError;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: HW BVNC (%d.%s.%d.%d) and FW BVNC (%d.%s.%d.%d) match. [ OK ]", 
+                               RGX_BVNC_PACKED_EXTR_B(sHWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_V(sHWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_N(sHWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_C(sHWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_B(sSWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_V(sSWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_N(sSWBVNC), 
+                               RGX_BVNC_PACKED_EXTR_C(sSWBVNC)));
+       }
+#endif
+
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck_METACoreVersion_AgainstDriver
+
+ @Description
+
+ Validate HW META version against driver META version
+
+ @Input psDevInfo - device info
+ @Input psRGXFWInit - FW init data
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+
+static PVRSRV_ERROR RGXDevInitCompatCheck_METACoreVersion_AgainstDriver(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                       RGXFWIF_INIT *psRGXFWInit)
+{
+#if defined(PDUMP)||(!defined(NO_HARDWARE))
+       PVRSRV_ERROR            eError;
+#endif
+
+#if defined(PDUMP)
+       PDUMPIF("DISABLE_HWMETA_CHECK");
+       PDUMPELSE("DISABLE_HWMETA_CHECK");
+       PDUMPCOMMENT("Compatibility check: KM driver and HW META version");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                       offsetof(RGXFWIF_INIT, sRGXCompChecks) +
+                                       offsetof(RGXFWIF_COMPCHECKS, ui32METAVersion),
+                                       RGX_CR_META_CORE_ID_VALUE,
+                                       0xffffffff,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       PDUMP_FLAGS_CONTINUOUS);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               return eError;
+       }
+       PDUMPFI("DISABLE_HWMETA_CHECK");
+#endif
+
+#if !defined(NO_HARDWARE)
+       if (psRGXFWInit == IMG_NULL)
+               return PVRSRV_ERROR_INVALID_PARAMS;
+
+       if (psRGXFWInit->sRGXCompChecks.ui32METAVersion != RGX_CR_META_CORE_ID_VALUE)
+       {
+               PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Incompatible driver META version (%d) / HW META version (%d).",
+                               RGX_CR_META_CORE_ID_VALUE, psRGXFWInit->sRGXCompChecks.ui32METAVersion));
+               eError = PVRSRV_ERROR_META_MISMATCH;
+               PVR_DBG_BREAK;
+               return eError;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: driver META version (%d) and HW META version (%d) match. [ OK ]",
+                               RGX_CR_META_CORE_ID_VALUE, psRGXFWInit->sRGXCompChecks.ui32METAVersion));
+       }
+#endif
+       return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function     RGXDevInitCompatCheck
+
+ @Description
+
+ Check compatibility of host driver and firmware (DDK and build options)
+ for RGX devices at services/device initialisation
+
+ @Input psDeviceNode - device node
+
+ @Return   PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+static PVRSRV_ERROR RGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32ClientBuildOptions)
+{
+       PVRSRV_ERROR            eError;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_INIT            *psRGXFWInit = IMG_NULL;
+#if !defined(NO_HARDWARE)
+       IMG_UINT32                      ui32RegValue;
+#endif
+
+       /* Ensure it's a RGX device */
+       if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_RGX)
+       {
+               PVR_LOG(("(FAIL) %s: Device not of type RGX", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto chk_exit;
+       }
+
+       /* 
+        * Retrieve the FW information
+        */
+       
+#if !defined(NO_HARDWARE)
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                               (IMG_VOID **)&psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"%s: Failed to acquire kernel fw compatibility check info (%u)",
+                               __FUNCTION__, eError));
+               return eError;
+       }
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               if(*((volatile IMG_BOOL *)&psRGXFWInit->sRGXCompChecks.bUpdated))
+               {
+                       /* No need to wait if the FW has already updated the values */
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       ui32RegValue = 0;
+       eError = RGXReadMETAAddr(psDevInfo, META_CR_T0ENABLE_OFFSET, &ui32RegValue);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Reading RGX META register failed. Is the GPU correctly powered up? (%u)",
+                               __FUNCTION__, eError));
+               goto chk_exit;
+       }
+
+       if (!(ui32RegValue & META_CR_TXENABLE_ENABLE_BIT))
+       {
+               eError = PVRSRV_ERROR_META_THREAD0_NOT_ENABLED;
+               PVR_DPF((PVR_DBG_ERROR,"%s: RGX META is not running. Is the GPU correctly powered up? %d (%u)",
+                               __FUNCTION__, psRGXFWInit->sRGXCompChecks.bUpdated, eError));
+               goto chk_exit;
+       }
+       
+       if (!*((volatile IMG_BOOL *)&psRGXFWInit->sRGXCompChecks.bUpdated))
+       {
+               eError = PVRSRV_ERROR_TIMEOUT;
+               PVR_DPF((PVR_DBG_ERROR,"%s: Missing compatibility info from FW (%u)",
+                               __FUNCTION__, eError));
+               goto chk_exit;
+       }
+#endif
+
+       eError = RGXDevInitCompatCheck_KMBuildOptions_FWAgainstDriver(psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = RGXDevInitCompatCheck_BuildOptions_FWAgainstClient(psDevInfo, psRGXFWInit, ui32ClientBuildOptions);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+       
+       eError = RGXDevInitCompatCheck_DDKVersion_FWAgainstDriver(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = RGXDevInitCompatCheck_DDKBuild_FWAgainstDriver(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = RGXDevInitCompatCheck_BVNC_FWAgainstDriver(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = RGXDevInitCompatCheck_BVNC_HWAgainstDriver(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = RGXDevInitCompatCheck_METACoreVersion_AgainstDriver(psDevInfo, psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               goto chk_exit;
+       }
+
+       eError = PVRSRV_OK;
+chk_exit:
+#if !defined(NO_HARDWARE)
+       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+#endif
+       return eError;
+}
+
+#define        MAKESTRING(x) #x
+#define TOSTRING(x) MAKESTRING(x)
+
+
+#if defined(SUPPORT_EXTRA_METASP_DEBUG)
+static PVRSRV_ERROR ValidateFWImageWithSP(IMG_CHAR *pcFWImgAddr, IMG_SIZE_T uiFWImgLen)
+{
+       PVRSRV_ERROR         eError             = PVRSRV_OK;
+#if !defined(NO_HARDWARE) && defined(DEBUG)
+       PVRSRV_DATA          *psPVRSRVData      = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_NODE   *psDeviceNode      = psPVRSRVData->apsRegisteredDevNodes[0];
+       PVRSRV_DEVICE_CONFIG *psDevConfig       = psDeviceNode->psDevConfig;
+       PVRSRV_RGXDEV_INFO   *psDevInfo         = psDeviceNode->pvDevice;
+       IMG_UINT32           *pui32HostCodeAddr = (IMG_UINT32*)pcFWImgAddr;
+       IMG_UINT32           ui32FWCodeAddr     = RGXFW_BOOTLDR_META_ADDR;
+       IMG_UINT32           ui32FWImageLen     = uiFWImgLen/sizeof(IMG_UINT32);
+       IMG_UINT32           i;
+
+       /* ValidateFWImageWithSP is called by PVRSRVRGXInitLoadFWImageKM, but the RGX
+        * registers are mapped later in PVRSRVRGXInitDevPart2KM, we do it now as we need them */
+       psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psDevConfig->sRegsCpuPBase, psDevConfig->ui32RegsSize, 0);
+       if (psDevInfo->pvRegsBaseKM == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"ValidateFWImageWithSP: Failed to create RGX register mapping"));
+               return PVRSRV_ERROR_BAD_MAPPING;
+       }
+
+       for(i = 0 ; i < ui32FWImageLen ; i++)
+       {
+               if(RGXReadWithSP(ui32FWCodeAddr) != *pui32HostCodeAddr)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"ValidateFWImageWithSP: Mismatch between Host and Meta views of the firmware code"));
+                       eError =  PVRSRV_ERROR_META_MISMATCH;
+                       goto validatefwimage_cleanup;
+               }
+               ui32FWCodeAddr += 4;
+               pui32HostCodeAddr++;
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE,"ValidateFWImageWithSP: Match between Host and Meta views of the firmware code"));
+
+validatefwimage_cleanup:
+       OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, psDevInfo->ui32RegSize, 0);
+#else
+       PVR_UNREFERENCED_PARAMETER(pcFWImgAddr);
+       PVR_UNREFERENCED_PARAMETER(uiFWImgLen);
+#endif /* !defined(NO_HARDWARE) && defined(DEBUG) */
+
+       return eError;
+}
+#endif /* defined(SUPPORT_EXTRA_METASP_DEBUG) */
+
+static PVRSRV_ERROR
+ValidateFWImage(
+       IMG_CHAR *pcFWImgDestAddr,
+       IMG_CHAR *pcFWImgSrcAddr,
+       IMG_SIZE_T uiFWImgLen,
+       IMG_CHAR *pcFWImgSigAddr,
+       IMG_UINT64 ui64FWSigLen)
+{
+#if defined(DEBUG)
+       if(OSMemCmp(pcFWImgDestAddr, pcFWImgSrcAddr, uiFWImgLen) != 0)
+       {
+               return PVRSRV_ERROR_INIT_TDMETACODE_PAGES_FAIL;
+       }
+
+       PVR_UNREFERENCED_PARAMETER(pcFWImgSigAddr);
+       PVR_UNREFERENCED_PARAMETER(ui64FWSigLen);
+#else
+       PVR_UNREFERENCED_PARAMETER(pcFWImgDestAddr);
+       PVR_UNREFERENCED_PARAMETER(uiFWImgLen);
+       PVR_UNREFERENCED_PARAMETER(pcFWImgSigAddr);
+       PVR_UNREFERENCED_PARAMETER(ui64FWSigLen);
+#endif
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRCopy(PMR *psDstPMR, PMR *psSrcPMR, IMG_SIZE_T uiMaxCopyLen)
+{
+       IMG_CHAR acBuf[512];
+       IMG_UINT64 uiBytesCopied;
+       PVRSRV_ERROR eStatus;
+       
+       uiBytesCopied = 0;
+       while(uiBytesCopied < uiMaxCopyLen)
+       {
+               IMG_SIZE_T uiRead, uiWritten;
+               IMG_SIZE_T uiCopyAmt;
+               uiCopyAmt = sizeof(acBuf) > uiMaxCopyLen ? uiMaxCopyLen : sizeof(acBuf);
+               eStatus = PMR_ReadBytes(psSrcPMR,
+                                       uiBytesCopied,
+                                       acBuf,
+                                       uiCopyAmt,
+                                       &uiRead);
+               if(eStatus != PVRSRV_OK)
+               {
+                       return eStatus;
+               }
+               eStatus = PMR_WriteBytes(psDstPMR,
+                                        uiBytesCopied,
+                                        acBuf,
+                                        uiCopyAmt,
+                                        &uiWritten);
+               if(eStatus != PVRSRV_OK)
+               {
+                       return eStatus;
+               }
+               PVR_ASSERT(uiRead == uiWritten);
+               PVR_ASSERT(uiRead == uiCopyAmt);
+               uiBytesCopied += uiCopyAmt;
+       }
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXInitLoadFWImageKM(
+       PMR *psFWImgDestPMR,
+       PMR *psFWImgSrcPMR,
+       IMG_UINT64 ui64FWImgLen,
+       PMR *psFWImgSigPMR,
+       IMG_UINT64 ui64FWSigLen)
+{
+       IMG_CHAR *pcFWImgSigAddr, *pcFWImgDestAddr, *pcFWImgSrcAddr;
+       IMG_HANDLE hFWImgSigHdl, hFWImgDestHdl, hFWImgSrcHdl;
+       IMG_SIZE_T uiLen;
+       PVRSRV_ERROR eStatus;
+
+       /* The purpose of this function is to do the following:
+          - copy the data contained in psFWImgSrcPMR into psFWImgDestPMR
+          - use the data contained in psFWImgSigPMR to validate the contents of psFWImgDestPMR
+
+          This is a functional placeholder that is meant to be overridden when actually using
+          the protected META code feature. As a result, normally, the memory backed by 
+          psFWImgDestPMR will not be read/writeable from this layer. Thus the operation of
+          actually doing the copy and verify must be handled in a mode with more privilege,
+          typically a hypervisor.
+
+          Because psFWImgSrcPMR and psFWImgSigPMR are normal OS-memory controlled PMR's, it
+          should be sufficient to acquire their kernel mappings and pass the pointers to
+          their mapped addressed into the hypervisor. However, since psFWImgDestPMR references
+          a region of memory that would typically be allocated (and writeable) by a hypervisor,
+          it will be necessary to pass the psFWImgDestPMR->pvFlavourData (or a field contained
+          within it) to the hypervisor to identify the region of memory to copy to and validate.
+
+          In the example function provided below, the following things happen:
+          - kernel mappings are acquired for the destination and signature PMRs
+          - a copy is done using the PMR_ReadBytes / PMR_WriteBytes callback functionality in
+            the PMR layer
+          - a validation is done by reading back the destination buffer and comparing it against
+            the source buffer.
+
+          c.f. a real implementation, where the following things would likely happen:
+          - kernel mappings are acquired for the source and signature PMRs
+          - the source/signature mapped addresses and lengths, and psFWImgDestPMR->pvFlavourData
+            are passed into the hypervisor to do the copy/validate.
+       */
+
+       eStatus = PMRAcquireKernelMappingData(psFWImgDestPMR,
+                                             0,
+                                             0,
+                                             (IMG_VOID **) &pcFWImgDestAddr,
+                                             &uiLen,
+                                          &hFWImgDestHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Acquire mapping for dest failed (%u)", eStatus));
+               goto error;
+       }
+       if(ui64FWImgLen > uiLen)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: PMR dst len (%llu) > mapped len (%llu)",
+                        ui64FWImgLen, (unsigned long long)uiLen));
+               goto error;
+       }
+
+       eStatus = PMRAcquireKernelMappingData(psFWImgSrcPMR,
+                                             0,
+                                             0,
+                                             (IMG_VOID **) &pcFWImgSrcAddr,
+                                             &uiLen,
+                                          &hFWImgSrcHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Acquire mapping for src failed (%u)", eStatus));
+               goto error;
+       }
+       if(ui64FWImgLen > uiLen)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: PMR dst len (%llu) > mapped len (%llu)",
+                        ui64FWImgLen, (unsigned long long)uiLen));
+               goto error;
+       }
+
+       eStatus = PMRAcquireKernelMappingData(psFWImgSigPMR,
+                                             0,
+                                             0,
+                                             (IMG_VOID **) &pcFWImgSigAddr,
+                                             &uiLen,
+                                          &hFWImgSigHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Acquire mapping for sig failed (%u)", eStatus));
+               goto error;
+       }
+       if(ui64FWSigLen > uiLen)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: sig len (%llu) > mapped len (%llu)",
+                        ui64FWSigLen, (unsigned long long)uiLen));
+               goto error;
+       }
+
+       /* Copy the firmware image from the intermediate buffer to the real firmware memory allocation. */
+       PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVDebugMiscInitFWImageKM: copying %llu bytes from PMR %p to PMR %p",
+                               ui64FWImgLen, psFWImgSrcPMR, psFWImgDestPMR));
+       PMRCopy(psFWImgDestPMR, psFWImgSrcPMR, TRUNCATE_64BITS_TO_SIZE_T(ui64FWImgLen));
+
+       /* Validate the firmware image after it has been copied into place */
+       eStatus = ValidateFWImage(pcFWImgDestAddr, pcFWImgSrcAddr, TRUNCATE_64BITS_TO_SIZE_T(ui64FWImgLen), pcFWImgSigAddr, ui64FWSigLen);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Signature check failed"));
+               goto error;
+       }
+
+#if defined(SUPPORT_EXTRA_METASP_DEBUG)
+       /* Compare the firmware image as seen from the CPU point of view
+        * against the same memory area as seen from the META point of view */
+       eStatus = ValidateFWImageWithSP(pcFWImgDestAddr, TRUNCATE_64BITS_TO_SIZE_T(ui64FWImgLen));
+       if(eStatus != PVRSRV_OK)
+       {
+               goto error;
+       }
+#endif
+
+       eStatus = PMRReleaseKernelMappingData(psFWImgDestPMR,
+                                             hFWImgDestHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Release mapping for dest failed (%u)", eStatus));
+               goto error;
+       }
+
+       eStatus = PMRReleaseKernelMappingData(psFWImgSrcPMR,
+                                             hFWImgSrcHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Release mapping for src failed (%u)", eStatus));
+               goto error;
+       }
+
+       eStatus = PMRReleaseKernelMappingData(psFWImgSigPMR,
+                                             hFWImgSigHdl);
+       if(eStatus != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscInitFWImageKM: Release mapping for sig failed (%u)", eStatus));
+               goto error;
+       }
+
+       return PVRSRV_OK;
+
+error:
+       return PVRSRV_ERROR_INIT_TDMETACODE_PAGES_FAIL;
+}
+
+
+
+/*************************************************************************/ /*!
+@Function       RGXDevVersionString
+@Description    Gets the version string for the given device node and returns 
+                a pointer to it in ppszVersionString. It is then the 
+                responsibility of the caller to free this memory.
+@Input          psDeviceNode            Device node from which to obtain the 
+                                        version string
+@Output                ppszVersionString       Contains the version string upon return
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static PVRSRV_ERROR RGXDevVersionString(PVRSRV_DEVICE_NODE *psDeviceNode, 
+                                       IMG_CHAR **ppszVersionString)
+{
+#if defined(COMPAT_BVNC_MASK_B) || defined(COMPAT_BVNC_MASK_V) || defined(COMPAT_BVNC_MASK_N) || defined(COMPAT_BVNC_MASK_C) || defined(NO_HARDWARE) || defined(EMULATOR)
+       IMG_CHAR pszFormatString[] = "Rogue Version: %d.%s.%d.%d (SW)";
+#else
+       IMG_CHAR pszFormatString[] = "Rogue Version: %d.%s.%d.%d (HW)";
+#endif
+       IMG_SIZE_T uiStringLength;
+
+       if (psDeviceNode == NULL || ppszVersionString == NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       uiStringLength = OSStringLength(pszFormatString);
+       uiStringLength += OSStringLength(TOSTRING(RGX_BVNC_KM_B));
+       uiStringLength += OSStringLength(TOSTRING(RGX_BVNC_KM_V));
+       uiStringLength += OSStringLength(TOSTRING(RGX_BVNC_KM_N));
+       uiStringLength += OSStringLength(TOSTRING(RGX_BVNC_KM_C));
+
+       *ppszVersionString = OSAllocZMem(uiStringLength * sizeof(IMG_CHAR));
+       if (*ppszVersionString == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSSNPrintf(*ppszVersionString, uiStringLength, pszFormatString, 
+                  RGX_BVNC_KM_B, TOSTRING(RGX_BVNC_KM_V), RGX_BVNC_KM_N, RGX_BVNC_KM_C);
+
+       return PVRSRV_OK;
+}
+
+/**************************************************************************/ /*!
+@Function       RGXDevClockSpeed
+@Description    Gets the clock speed for the given device node and returns
+                it in pui32RGXClockSpeed.
+@Input          psDeviceNode           Device node
+@Output         pui32RGXClockSpeed  Variable for storing the clock speed
+@Return         PVRSRV_ERROR
+*/ /***************************************************************************/
+static PVRSRV_ERROR RGXDevClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                       IMG_PUINT32  pui32RGXClockSpeed)
+{
+       RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
+
+       /* get clock speed */
+       *pui32RGXClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
+
+       return PVRSRV_OK;
+}
+
+
+/**************************************************************************/ /*!
+@Function       RGXSoftReset
+@Description    Resets some modules of the RGX device
+@Input          psDeviceNode           Device node
+@Input          ui64ResetValue1 A mask for which each bit set corresponds
+                                to a module to reset (via the SOFT_RESET
+                                register).
+@Input          ui64ResetValue2 A mask for which each bit set corresponds
+                                to a module to reset (via the SOFT_RESET2
+                                register).
+@Return         PVRSRV_ERROR
+*/ /***************************************************************************/
+static PVRSRV_ERROR RGXSoftReset(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                 IMG_UINT64  ui64ResetValue1,
+                                 IMG_UINT64  ui64ResetValue2)
+{
+       PVRSRV_RGXDEV_INFO        *psDevInfo;
+
+       PVR_ASSERT(psDeviceNode != NULL);
+       PVR_ASSERT(psDeviceNode->pvDevice != NULL);
+
+       if ((ui64ResetValue1 & RGX_CR_SOFT_RESET_MASKFULL) != ui64ResetValue1  ||
+           (ui64ResetValue2 & RGX_CR_SOFT_RESET2_MASKFULL) != ui64ResetValue2)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* the device info */
+       psDevInfo = psDeviceNode->pvDevice;
+
+       /* Set in soft-reset */
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, ui64ResetValue1);
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, ui64ResetValue2);
+
+       /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2);
+
+       return PVRSRV_OK;
+}
+
+
+/******************************************************************************
+ End of file (rgxinit.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxinit.h
new file mode 100644 (file)
index 0000000..6521d71
--- /dev/null
@@ -0,0 +1,276 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX initialisation header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX initialisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXINIT_H__)
+#define __RGXINIT_H__
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "rgxscript.h"
+#include "device.h"
+#include "rgxdevice.h"
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXInitDevPart2KM
+
+ @Description
+
+ Second part of server-side RGX initialisation
+
+ @Input pvDeviceNode - device node
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRGXInitDevPart2KM (PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                         RGX_INIT_COMMAND              *psInitScript,
+                                                                         RGX_INIT_COMMAND              *psDbgScript,
+                                                                         RGX_INIT_COMMAND              *psDbgBusScript,
+                                                                         RGX_INIT_COMMAND              *psDeinitScript,
+                                                                         IMG_UINT32                    ui32KernelCatBaseIdReg,
+                                                                         IMG_UINT32                    ui32KernelCatBaseId,
+                                                                         IMG_UINT32                    ui32KernelCatBaseReg,
+                                                                         IMG_UINT32                    ui32KernelCatBaseWordSize,
+                                                                         IMG_UINT32                    ui32KernelCatBaseAlignShift,
+                                                                         IMG_UINT32                    ui32KernelCatBaseShift,
+                                                                         IMG_UINT64                    ui64KernelCatBaseMask,
+                                                                         IMG_UINT32                    ui32DeviceFlags,
+                                                                         RGX_ACTIVEPM_CONF             eActivePMConf,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWCodeAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWDataAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psFWCorememAllocServerExportCookie,
+                                                                         DEVMEM_EXPORTCOOKIE   *psHWPerfDataAllocServerExportCookie);
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitAllocFWImgMemKM(PVRSRV_DEVICE_NODE    *psDeviceNode,
+                                                                                 IMG_DEVMEM_SIZE_T     ui32FWCodeLen,
+                                                                                 IMG_DEVMEM_SIZE_T     ui32FWDataLen,
+                                                                                 IMG_DEVMEM_SIZE_T     uiFWCorememLen,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWCodeAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR      *psFWCodeDevVAddrBase,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWDataAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR      *psFWDataDevVAddrBase,
+                                                                                 DEVMEM_EXPORTCOOKIE   **ppsFWCorememAllocServerExportCookie,
+                                                                                 IMG_DEV_VIRTADDR      *psFWCorememDevVAddrBase,
+                                                                                 RGXFWIF_DEV_VIRTADDR  *psFWCorememMetaVAddrBase);
+
+
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXInitFirmwareKM
+
+ @Description
+
+ Server-side RGX firmware initialisation
+
+ @Input pvDeviceNode - device node
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRGXInitFirmwareKM(PVRSRV_DEVICE_NODE                        *psDeviceNode, 
+                                                                           RGXFWIF_DEV_VIRTADDR                *psRGXFwInit,
+                                                                           IMG_BOOL                                    bEnableSignatureChecks,
+                                                                           IMG_UINT32                                  ui32SignatureChecksBufSize,
+                                                                           IMG_UINT32                                  ui32HWPerfFWBufSizeKB,
+                                                                           IMG_UINT64                                  ui64HWPerfFilter,
+                                                                           IMG_UINT32                                  ui32RGXFWAlignChecksSize,
+                                                                           IMG_UINT32                                  *pui32RGXFWAlignChecks,
+                                                                           IMG_UINT32                                  ui32ConfigFlags,
+                                                                           IMG_UINT32                                  ui32LogType,
+                                                                               IMG_UINT32                                      ui32FilterMode,
+                                                                           IMG_UINT32                                  ui32JonesDisableMask,
+                                                                           IMG_UINT32                                  ui32HWRDebugDumpLimit,
+                                                                           RGXFWIF_COMPCHECKS_BVNC     *psClientBVNC,
+                                                                               IMG_UINT32                                      ui32HWPerfCountersDataSize,
+                                                                               DEVMEM_EXPORTCOOKIE   **ppsHWPerfDataAllocServerExportCookie,
+                                                                           RGX_RD_POWER_ISLAND_CONF                    eRGXRDPowerIslandingConf);
+
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXInitLoadFWImageKM
+
+ @Description
+
+ Load the firmware image into place.
+
+ @Input psFWImgDestPMR - PMR holding destination memory buffer for firmware
+
+ @input psFWImgSrcPMR - PMR holding firmware image data to load
+
+ @input ui64FWImgLen - number of bytes in Src/Dst memory buffers
+
+ @input psFWImgSigPMR - a buffer holding a signature for Src, which is used for validation
+
+ @input ui64FWSigLen - number of bytes contained in the signature buffer.
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXInitLoadFWImageKM(PMR *psFWImgDestPMR,
+                                        PMR *psFWImgSrcPMR,
+                                        IMG_UINT64 ui64FWImgLen,
+                                                                               PMR *psFWImgSigPMR,
+                                        IMG_UINT64 ui64FWSigLen);
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXInitHWPerfCountersKM
+
+ @Description
+
+ Initialisation of the performance counters
+
+ @Input pvDeviceNode - device node
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRGXInitHWPerfCountersKM (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/*!
+*******************************************************************************
+
+ @Function     RGXRegisterDevice
+
+ @Description
+
+ Registers the device with the system
+
+ @Input:       psDeviceNode - device node
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+
+/*!
+*******************************************************************************
+
+ @Function     DevDeInitRGX
+
+ @Description
+
+ Reset and deinitialise Chip
+
+ @Input pvDeviceNode - device info. structure
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR DevDeInitRGX(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#if !defined(NO_HARDWARE)
+void RGX_WaitForInterruptsTimeout(PVRSRV_RGXDEV_INFO *psDevInfo);
+#endif
+/*!
+*******************************************************************************
+
+ @Function     RGXRegisterGpuUtilStats
+
+ @Description  Initialise data used to compute GPU utilisation statistics
+               for a particular user (identified by the handle passed as
+               argument). This function must be called only once for each
+               different user/handle.
+
+ @Input        phGpuUtilUser - Pointer to handle used to identify a user of
+                               RGXGetGpuUtilStats
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RGXRegisterGpuUtilStats(IMG_HANDLE *phGpuUtilUser);
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXUnregisterGpuUtilStats
+
+ @Description  Free data previously used to compute GPU utilisation statistics
+               for a particular user (identified by the handle passed as
+               argument).
+
+ @Input        hGpuUtilUser - Handle used to identify a user of
+                              RGXGetGpuUtilStats
+
+ @Return       PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RGXUnregisterGpuUtilStats(IMG_HANDLE hGpuUtilUser);
+
+
+/*!
+*******************************************************************************
+
+ @Function             PVRSRVGPUVIRTPopulateLMASubArenasKM
+
+ @Description  Populates the LMA arenas based on the min max values passed by
+                               the client during initialization. GPU Virtualization Validation
+                               only.
+
+ @Input                        pvDeviceNode    : Pointer to a device info structure.
+                               ui32NumElements : Total number of min / max values passed by
+                                                                 the client
+                               pui32Elements   : The array containing all the min / max values
+                                                                 passed by the client, all bundled together
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVGPUVIRTPopulateLMASubArenasKM(PVRSRV_DEVICE_NODE    *psDeviceNode, IMG_UINT32 ui32NumElements, IMG_UINT32 aui32Elements[]);
+
+#endif /* __RGXINIT_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.c
new file mode 100644 (file)
index 0000000..1834e16
--- /dev/null
@@ -0,0 +1,681 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX memory context management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX memory context management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvr_debug.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_server_utils.h"
+#include "devicemem_pdump.h"
+#include "rgxdevice.h"
+#include "rgx_fwif_km.h"
+#include "rgxfwutils.h"
+#include "pdump_km.h"
+#include "pvrsrv.h"
+#include "sync_internal.h"
+#include "rgx_memallocflags.h"
+
+/*
+       FIXME:
+       For now just get global state, but what we really want is to do
+       this per memory context
+*/
+static IMG_UINT32 ui32CacheOpps = 0;
+static IMG_UINT32 ui32CacheOpSequence = 0;
+/* FIXME: End */
+
+typedef struct _SERVER_MMU_CONTEXT_ {
+       DEVMEM_MEMDESC *psFWMemContextMemDesc;
+       MMU_CONTEXT *psMMUContext;
+       IMG_PID uiPID;
+       IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME];
+       DLLIST_NODE sNode;
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+} SERVER_MMU_CONTEXT;
+
+IMG_VOID RGXMMUCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                          IMG_HANDLE hDeviceData,
+                                                          MMU_LEVEL eMMULevel,
+                                                          IMG_BOOL bUnmap)
+{
+       PVR_UNREFERENCED_PARAMETER(bUnmap);
+
+       switch (eMMULevel)
+       {
+               case MMU_LEVEL_3:       ui32CacheOpps |= RGXFWIF_MMUCACHEDATA_FLAGS_PC;
+                                                       break;
+               case MMU_LEVEL_2:       ui32CacheOpps |= RGXFWIF_MMUCACHEDATA_FLAGS_PD;
+                                                       break;
+               case MMU_LEVEL_1:       ui32CacheOpps |= RGXFWIF_MMUCACHEDATA_FLAGS_PT;
+                                                       ui32CacheOpps |= RGXFWIF_MMUCACHEDATA_FLAGS_TLB;
+                                                       break;
+               default:
+                                                       PVR_ASSERT(0);
+                                                       break;
+       }
+}
+
+PVRSRV_ERROR RGXSLCCacheInvalidateRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                       PMR *psPmr)
+{
+       RGXFWIF_KCCB_CMD sFlushInvalCmd;
+       IMG_UINT32 ulPMRFlags;
+       IMG_UINT32 ui32DeviceCacheFlags;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       PVR_ASSERT(psDeviceNode);
+
+       /* In DEINIT state, we stop scheduling SLC flush commands, because we don't know in what state the firmware is.
+        * Anyway, if we are in DEINIT state, we don't care anymore about FW memory consistency
+        */
+       if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_DEINIT)
+       {
+
+               /* get the PMR's caching flags */
+               eError = PMR_Flags(psPmr, &ulPMRFlags);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "RGXSLCCacheInvalidateRequest: Unable to get the caching attributes of PMR %p",psPmr));
+               }
+
+               ui32DeviceCacheFlags = DevmemDeviceCacheMode(ulPMRFlags);
+
+               /* Schedule a SLC flush and invalidate if
+                * - the memory is cached.
+                * - we can't get the caching attributes (by precaution).
+                */
+               if ((ui32DeviceCacheFlags == PVRSRV_MEMALLOCFLAG_GPU_CACHED) || (eError != PVRSRV_OK))
+               {
+                       /* Schedule the SLC flush command ... */
+#if defined(PDUMP)
+                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Submit SLC flush and invalidate");
+#endif
+                       sFlushInvalCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL;
+                       sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_TRUE;
+                       sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_FALSE;
+                       sFlushInvalCmd.uCmdData.sSLCFlushInvalData.eDM = 0;
+                       sFlushInvalCmd.uCmdData.sSLCFlushInvalData.psContext.ui32Addr = 0;
+
+                       eError = RGXSendCommandWithPowLock(psDeviceNode->pvDevice,
+                                                                                               RGXFWIF_DM_GP,
+                                                                                               &sFlushInvalCmd,
+                                                                                               sizeof(sFlushInvalCmd),
+                                                                                               IMG_TRUE);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXSLCCacheInvalidateRequest: Failed to schedule SLC flush command with error (%u)", eError));
+                       }
+                       else
+                       {
+                               /* Wait for the SLC flush to complete */
+                               eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXSLCCacheInvalidateRequest: SLC flush and invalidate aborted with error (%u)", eError));
+                               }
+                       }
+               }
+       }
+
+       return eError;
+}
+
+
+PVRSRV_ERROR RGXPreKickCacheCommand(PVRSRV_RGXDEV_INFO         *psDevInfo)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
+       RGXFWIF_KCCB_CMD sFlushCmd;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       RGXFWIF_DM eDMcount = RGXFWIF_DM_MAX;
+
+       if (!ui32CacheOpps)
+       {
+               goto _PVRSRVPowerLock_Exit;
+       }
+
+       sFlushCmd.eCmdType = RGXFWIF_KCCB_CMD_MMUCACHE;
+       /* Set which memory context this command is for (all ctxs for now) */
+       ui32CacheOpps |= RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL;
+#if 0
+       sFlushCmd.uCmdData.sMMUCacheData.psMemoryContext = ???
+#endif
+
+       /* PVRSRVPowerLock guarantees atomicity between commands and global variables consistency.
+        * This is helpful in a scenario with several applications allocating resources. */
+       eError = PVRSRVPowerLock();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXPreKickCacheCommand: failed to acquire powerlock (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+               goto _PVRSRVPowerLock_Exit;
+       }
+
+       PDUMPPOWCMDSTART();
+       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE_ON,
+                                                                                IMG_FALSE);
+       PDUMPPOWCMDEND();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "RGXPreKickCacheCommand: failed to transition RGX to ON (%s)",
+                                       PVRSRVGetErrorStringKM(eError)));
+
+               goto _PVRSRVSetDevicePowerStateKM_Exit;
+       }
+
+       sFlushCmd.uCmdData.sMMUCacheData.ui32Flags = ui32CacheOpps;
+       sFlushCmd.uCmdData.sMMUCacheData.ui32CacheSequenceNum = ++ui32CacheOpSequence;
+
+#if defined(PDUMP)
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+                                                       "Submit MMU flush and invalidate (flags = 0x%08x, cache operation sequence = %u)",
+                                                       ui32CacheOpps, ui32CacheOpSequence);
+#endif
+
+       ui32CacheOpps = 0;
+
+       /* Schedule MMU cache command */
+       do
+       {
+               eDMcount--;
+               eError = RGXSendCommandRaw(psDevInfo, eDMcount, &sFlushCmd, sizeof(RGXFWIF_KCCB_CMD), PDUMP_FLAGS_CONTINUOUS);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXPreKickCacheCommand: Failed to schedule MMU cache command \
+                                                                       to DM=%d with error (%u)", eDMcount, eError));
+                       break;
+               }
+       }
+       while(eDMcount > 0);
+
+_PVRSRVSetDevicePowerStateKM_Exit:
+       PVRSRVPowerUnlock();
+
+_PVRSRVPowerLock_Exit:
+       return eError;
+}
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+/* page fault debug is the only current use case for needing to find process info
+ * after that process device memory context has been destroyed
+ */
+
+typedef struct _UNREGISTERED_MEMORY_CONTEXT_
+{
+       IMG_PID uiPID;
+       IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME];
+       IMG_DEV_PHYADDR sPCDevPAddr;
+} UNREGISTERED_MEMORY_CONTEXT;
+
+/* must be a power of two */
+#define UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE (1 << 3)
+
+static UNREGISTERED_MEMORY_CONTEXT gasUnregisteredMemCtxs[UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE];
+static IMG_UINT32 gui32UnregisteredMemCtxsHead = 0;
+
+/* record a device memory context being unregistered.
+ * the list of unregistered contexts can be used to find the PID and process name
+ * belonging to a memory context which has been destroyed
+ */
+static IMG_VOID _RecordUnregisteredMemoryContext(PVRSRV_RGXDEV_INFO *psDevInfo, SERVER_MMU_CONTEXT *psServerMMUContext)
+{
+       UNREGISTERED_MEMORY_CONTEXT *psRecord;
+
+       OSLockAcquire(psDevInfo->hMMUCtxUnregLock);
+
+       psRecord = &gasUnregisteredMemCtxs[gui32UnregisteredMemCtxsHead];
+
+       gui32UnregisteredMemCtxsHead = (gui32UnregisteredMemCtxsHead + 1)
+                                       & (UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1);
+
+       OSLockRelease(psDevInfo->hMMUCtxUnregLock);
+
+       psRecord->uiPID = psServerMMUContext->uiPID;
+       MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &psRecord->sPCDevPAddr);
+       OSStringNCopy(psRecord->szProcessName, psServerMMUContext->szProcessName, sizeof(psRecord->szProcessName));
+       psRecord->szProcessName[sizeof(psRecord->szProcessName) - 1] = '\0';
+}
+
+#endif
+
+IMG_VOID RGXUnregisterMemoryContext(IMG_HANDLE hPrivData)
+{
+       SERVER_MMU_CONTEXT *psServerMMUContext = hPrivData;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psServerMMUContext->psDevInfo;
+
+       OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock);
+       dllist_remove_node(&psServerMMUContext->sNode);
+       OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock);
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       _RecordUnregisteredMemoryContext(psDevInfo, psServerMMUContext);
+#endif
+
+       /*
+        * Release the page catalogue address acquired in RGXRegisterMemoryContext().
+        */
+       MMU_ReleaseBaseAddr(IMG_NULL /* FIXME */);
+       
+       /*
+        * Free the firmware memory context.
+        */
+       DevmemFwFree(psServerMMUContext->psFWMemContextMemDesc);
+
+       OSFreeMem(psServerMMUContext);
+}
+
+
+/*
+ * RGXRegisterMemoryContext
+ */ 
+PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                         MMU_CONTEXT                   *psMMUContext,
+                                                                         IMG_HANDLE                    *hPrivData)
+{
+       PVRSRV_ERROR                    eError;
+       PVRSRV_RGXDEV_INFO              *psDevInfo = psDeviceNode->pvDevice;
+       DEVMEM_FLAGS_T                  uiFWMemContextMemAllocFlags;
+       RGXFWIF_FWMEMCONTEXT    *psFWMemContext;
+       DEVMEM_MEMDESC                  *psFWMemContextMemDesc;
+       SERVER_MMU_CONTEXT *psServerMMUContext;
+
+       if (psDevInfo->psKernelMMUCtx == IMG_NULL)
+       {
+               /*
+                * This must be the creation of the Kernel memory context. Take a copy
+                * of the MMU context for use when programming the BIF.
+                */ 
+               psDevInfo->psKernelMMUCtx = psMMUContext;
+       }
+       else
+       {
+               psServerMMUContext = OSAllocMem(sizeof(*psServerMMUContext));
+               if (psServerMMUContext == IMG_NULL)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto fail_alloc_server_ctx;
+               }
+
+               psServerMMUContext->psDevInfo = psDevInfo;
+
+               /*
+                * This FW MemContext is only mapped into kernel for initialisation purposes.
+                * Otherwise this allocation is only used by the FW.
+                * Therefore the GPU cache doesn't need coherency,
+                * and write-combine is suffice on the CPU side (WC buffer will be flushed at any kick)
+                */
+               uiFWMemContextMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                                                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                                                                               PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE;
+
+               /*
+                       Allocate device memory for the firmware memory context for the new
+                       application.
+               */
+               PDUMPCOMMENT("Allocate RGX firmware memory context");
+               /* FIXME: why cache-consistent? */
+               eError = DevmemFwAllocate(psDevInfo,
+                                                               sizeof(*psFWMemContext),
+                                                               uiFWMemContextMemAllocFlags,
+                                                               "FirmwareMemoryContext",
+                                                               &psFWMemContextMemDesc);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to allocate firmware memory context (%u)",
+                                       eError));
+                       goto fail_alloc_fw_ctx;
+               }
+               
+               /*
+                       Temporarily map the firmware memory context to the kernel.
+               */
+               eError = DevmemAcquireCpuVirtAddr(psFWMemContextMemDesc,
+                                                                                 (IMG_VOID **)&psFWMemContext);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to map firmware memory context (%u)",
+                                       eError));
+                       goto fail_acquire_cpu_addr;
+               }
+               
+               /*
+                * Write the new memory context's page catalogue into the firmware memory
+                * context for the client.
+                */
+               eError = MMU_AcquireBaseAddr(psMMUContext, &psFWMemContext->sPCDevPAddr);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to acquire Page Catalogue address (%u)",
+                                       eError));
+                       DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc);
+                       goto fail_acquire_base_addr;
+               }
+
+               /*
+                * Set default values for the rest of the structure.
+                */
+               psFWMemContext->uiPageCatBaseRegID = -1;
+               psFWMemContext->uiBreakpointAddr = 0;
+               psFWMemContext->uiBPHandlerAddr = 0;
+               psFWMemContext->uiBreakpointCtl = 0;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+{
+               IMG_UINT32 ui32OSid = 0, ui32OSidReg = 0;
+
+               MMU_GetOSids(psMMUContext, &ui32OSid, &ui32OSidReg);
+
+               psFWMemContext->ui32OSid = ui32OSidReg;
+}
+#endif
+
+#if defined(PDUMP)
+               {
+                       IMG_CHAR                        aszName[PMR_MAX_MEMSPNAME_SYMB_ADDR_LENGTH_DEFAULT];
+                       IMG_DEVMEM_OFFSET_T uiOffset = 0;
+
+                       /*
+                        * Dump the Mem context allocation
+                        */
+                       DevmemPDumpLoadMem(psFWMemContextMemDesc, 0, sizeof(*psFWMemContext), PDUMP_FLAGS_CONTINUOUS);
+                       
+
+                       /*
+                        * Obtain a symbolic addr of the mem context structure
+                        */
+                       eError = DevmemPDumpPageCatBaseToSAddr(psFWMemContextMemDesc, 
+                                                                                                  &uiOffset, 
+                                                                                                  aszName, 
+                                                                                                  PMR_MAX_MEMSPNAME_SYMB_ADDR_LENGTH_DEFAULT);
+
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to generate a Dump Page Catalogue address (%u)",
+                                               eError));
+                               DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc);
+                               goto fail_pdump_cat_base_addr;
+                       }
+
+                       /*
+                        * Dump the Page Cat tag in the mem context (symbolic address)
+                        */
+                       eError = MMU_PDumpWritePageCatBase(psMMUContext,
+                                                                                               aszName,
+                                                                                               uiOffset,
+                                                                                               8, /* 64-bit register write */
+                                                                                               0,
+                                                                                               0,
+                                                                                               0);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to acquire Page Catalogue address (%u)",
+                                               eError));
+                               DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc);
+                               goto fail_pdump_cat_base;
+                       }
+               }
+#endif
+
+               /*
+                * Release kernel address acquired above.
+                */
+               DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc);
+
+               /*
+                * Store the process information for this device memory context
+                * for use with the host page-fault analysis.
+                */
+               psServerMMUContext->uiPID = OSGetCurrentProcessID();
+               psServerMMUContext->psMMUContext = psMMUContext;
+               psServerMMUContext->psFWMemContextMemDesc = psFWMemContextMemDesc;
+               if (OSSNPrintf(psServerMMUContext->szProcessName,
+                                               RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME,
+                                               "%s",
+                                               OSGetCurrentProcessName()) == RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME)
+               {
+                       psServerMMUContext->szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME-1] = '\0';
+               }
+
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "New memory context: Process Name: %s PID: %u (0x%08X)",
+                                                                               psServerMMUContext->szProcessName,
+                                                                               psServerMMUContext->uiPID,
+                                                                               psServerMMUContext->uiPID);
+
+               OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock);
+               dllist_add_to_tail(&psDevInfo->sMemoryContextList, &psServerMMUContext->sNode);
+               OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock);
+
+               MMU_SetDeviceData(psMMUContext, psFWMemContextMemDesc);
+               *hPrivData = psServerMMUContext;
+       }
+                       
+       return PVRSRV_OK;
+
+#if defined(PDUMP)
+fail_pdump_cat_base:
+fail_pdump_cat_base_addr:
+       MMU_ReleaseBaseAddr(IMG_NULL);
+#endif
+fail_acquire_base_addr:
+       /* Done before jumping to the fail point as the release is done before exit */
+fail_acquire_cpu_addr:
+       DevmemFwFree(psServerMMUContext->psFWMemContextMemDesc);
+fail_alloc_fw_ctx:
+       OSFreeMem(psServerMMUContext);
+fail_alloc_server_ctx:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+DEVMEM_MEMDESC *RGXGetFWMemDescFromMemoryContextHandle(IMG_HANDLE hPriv)
+{
+       SERVER_MMU_CONTEXT *psMMUContext = (SERVER_MMU_CONTEXT *) hPriv;
+
+       return psMMUContext->psFWMemContextMemDesc;
+}
+
+typedef struct _RGX_FAULT_DATA_ {
+       IMG_DEV_VIRTADDR *psDevVAddr;
+       IMG_DEV_PHYADDR *psDevPAddr;
+} RGX_FAULT_DATA;
+
+static IMG_BOOL _RGXCheckFaultAddress(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       SERVER_MMU_CONTEXT *psServerMMUContext = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode);
+       RGX_FAULT_DATA *psFaultData = (RGX_FAULT_DATA *) pvCallbackData;
+       IMG_DEV_PHYADDR sPCDevPAddr;
+       
+       if (MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &sPCDevPAddr) != PVRSRV_OK)
+       {
+               PVR_LOG(("Failed to get PC address for memory context"));
+               return IMG_TRUE;
+       }
+
+       if (psFaultData->psDevPAddr->uiAddr == sPCDevPAddr.uiAddr)
+       {
+               PVR_LOG(("Found memory context (PID = %d, %s)",
+                                psServerMMUContext->uiPID,
+                                psServerMMUContext->szProcessName));
+
+               MMU_CheckFaultAddress(psServerMMUContext->psMMUContext, psFaultData->psDevVAddr);
+               return IMG_FALSE;
+       }
+       return IMG_TRUE;
+}
+
+IMG_VOID RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *psDevVAddr, IMG_DEV_PHYADDR *psDevPAddr)
+{
+       RGX_FAULT_DATA sFaultData;
+       IMG_DEV_PHYADDR sPCDevPAddr;
+
+       sFaultData.psDevVAddr = psDevVAddr;
+       sFaultData.psDevPAddr = psDevPAddr;
+
+       OSWRLockAcquireRead(psDevInfo->hMemoryCtxListLock);
+
+       dllist_foreach_node(&psDevInfo->sMemoryContextList,
+                                               _RGXCheckFaultAddress,
+                                               &sFaultData);
+
+       /* Lastly check for fault in the kernel allocated memory */
+       if (MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sPCDevPAddr) != PVRSRV_OK)
+       {
+               PVR_LOG(("Failed to get PC address for kernel memory context"));
+       }
+
+       if (sFaultData.psDevPAddr->uiAddr == sPCDevPAddr.uiAddr)
+       {
+               MMU_CheckFaultAddress(psDevInfo->psKernelMMUCtx, psDevVAddr);
+       }
+
+       OSWRLockReleaseRead(psDevInfo->hMemoryCtxListLock);
+}
+
+/* input for query to find the MMU context corresponding to a
+ * page catalogue address
+ */
+typedef struct _RGX_FIND_MMU_CONTEXT_
+{
+       IMG_DEV_PHYADDR sPCAddress;
+       SERVER_MMU_CONTEXT *psServerMMUContext;
+       MMU_CONTEXT *psMMUContext;
+} RGX_FIND_MMU_CONTEXT;
+
+static IMG_BOOL _RGXFindMMUContext(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       SERVER_MMU_CONTEXT *psServerMMUContext = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode);
+       RGX_FIND_MMU_CONTEXT *psData = pvCallbackData;
+       IMG_DEV_PHYADDR sPCDevPAddr;
+
+       if (MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &sPCDevPAddr) != PVRSRV_OK)
+       {
+               PVR_LOG(("Failed to get PC address for memory context"));
+               return IMG_TRUE;
+       }
+
+       if (psData->sPCAddress.uiAddr == sPCDevPAddr.uiAddr)
+       {
+               psData->psServerMMUContext = psServerMMUContext;
+
+               return IMG_FALSE;
+       }
+       return IMG_TRUE;
+}
+
+/* given the physical address of a page catalogue, searches for a corresponding
+ * MMU context and if found, provides the caller details of the process.
+ * Returns IMG_TRUE if a process is found.
+ */
+IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress,
+                                                               RGXMEM_PROCESS_INFO *psInfo)
+{
+       RGX_FIND_MMU_CONTEXT sData;
+       IMG_BOOL bRet = IMG_FALSE;
+
+       sData.sPCAddress = sPCAddress;
+       sData.psServerMMUContext = IMG_NULL;
+
+       dllist_foreach_node(&psDevInfo->sMemoryContextList, _RGXFindMMUContext, &sData);
+
+       if(sData.psServerMMUContext != IMG_NULL)
+       {
+               psInfo->uiPID = sData.psServerMMUContext->uiPID;
+               OSStringNCopy(psInfo->szProcessName, sData.psServerMMUContext->szProcessName, sizeof(psInfo->szProcessName));
+               psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0';
+               psInfo->bUnregistered = IMG_FALSE;
+               bRet = IMG_TRUE;
+       }
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       else
+       {
+               /* no active memory context found with the given PC address.
+                * Check the list of most recently freed memory contexts.
+                */
+                IMG_UINT32 i;
+
+                OSLockAcquire(psDevInfo->hMMUCtxUnregLock);
+
+               /* iterate through the list of unregistered memory contexts
+                * from newest (one before the head) to the oldest (the current head)
+                */
+               i = gui32UnregisteredMemCtxsHead;
+
+               do
+               {
+                       UNREGISTERED_MEMORY_CONTEXT *psRecord;
+
+                       i ? i-- : (i = (UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1));
+
+                       psRecord = &gasUnregisteredMemCtxs[i];
+
+                       if(psRecord->sPCDevPAddr.uiAddr == sPCAddress.uiAddr)
+                       {
+                               psInfo->uiPID = psRecord->uiPID;
+                               OSStringNCopy(psInfo->szProcessName, psRecord->szProcessName, sizeof(psInfo->szProcessName)-1);
+                               psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0';
+                               psInfo->bUnregistered = IMG_TRUE;
+                               bRet = IMG_TRUE;
+                               break;
+                       }
+               } while(i != gui32UnregisteredMemCtxsHead);
+
+               OSLockRelease(psDevInfo->hMMUCtxUnregLock);
+
+       }
+#endif
+       return bRet;
+}
+
+/******************************************************************************
+ End of file (rgxmem.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmem.h
new file mode 100644 (file)
index 0000000..4565abb
--- /dev/null
@@ -0,0 +1,89 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX memory context management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for RGX memory context management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXMEM_H__)
+#define __RGXMEM_H__
+
+#include "pvrsrv_error.h"
+#include "device.h"
+#include "mmu_common.h"
+#include "rgxdevice.h"
+
+#define RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME 40
+
+typedef struct _RGXMEM_PROCESS_INFO_
+{
+       IMG_PID uiPID;
+       IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME];
+       IMG_BOOL bUnregistered;
+} RGXMEM_PROCESS_INFO;
+
+/* FIXME: SyncPrim should be stored on the memory context */
+IMG_VOID RGXMMUSyncPrimAlloc(PVRSRV_DEVICE_NODE *psDeviceNode);
+IMG_VOID RGXMMUSyncPrimFree(IMG_VOID);
+
+IMG_VOID RGXMMUCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                          IMG_HANDLE hDeviceData,
+                                                          MMU_LEVEL eMMULevel,
+                                                          IMG_BOOL bUnmap);
+
+PVRSRV_ERROR RGXSLCCacheInvalidateRequest(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                                       PMR *psPmr);
+
+PVRSRV_ERROR RGXPreKickCacheCommand(PVRSRV_RGXDEV_INFO         *psDevInfo);
+
+IMG_VOID RGXUnregisterMemoryContext(IMG_HANDLE hPrivData);
+PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                         MMU_CONTEXT                   *psMMUContext,
+                                                                         IMG_HANDLE                    *hPrivData);
+
+DEVMEM_MEMDESC *RGXGetFWMemDescFromMemoryContextHandle(IMG_HANDLE hPriv);
+
+IMG_VOID RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                         IMG_DEV_VIRTADDR *psDevVAddr,
+                                                         IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress,
+                                                               RGXMEM_PROCESS_INFO *psInfo);
+
+#endif /* __RGXMEM_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.c
new file mode 100644 (file)
index 0000000..f235e31
--- /dev/null
@@ -0,0 +1,990 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific initialisation routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific MMU initialisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "rgxmmuinit.h"
+#include "rgxmmudefs_km.h"
+
+#include "device.h"
+#include "img_types.h"
+#include "mmu_common.h"
+#include "pdump_mmu.h"
+
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "rgx_memallocflags.h"
+#include "pdump_km.h"
+
+/*
+ * Bits of PT, PD and PC not involving addresses 
+ */
+
+#define RGX_MMUCTRL_PTE_PROTMASK       (RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_PM_SRC_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_CC_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_READ_ONLY_EN | \
+                                                                        RGX_MMUCTRL_PT_DATA_VALID_EN)
+
+#define RGX_MMUCTRL_PDE_PROTMASK       (RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN | \
+                                                                        ~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK | \
+                                                                        RGX_MMUCTRL_PD_DATA_VALID_EN)
+
+#define RGX_MMUCTRL_PCE_PROTMASK       (RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN | \
+                                                                        RGX_MMUCTRL_PC_DATA_VALID_EN)
+
+
+
+
+
+static MMU_PxE_CONFIG sRGXMMUPCEConfig;
+static MMU_DEVVADDR_CONFIG sRGXMMUTopLevelDevVAddrConfig;
+
+
+typedef struct _RGX_PAGESIZECONFIG_
+{
+       const MMU_PxE_CONFIG *psPDEConfig;
+       const MMU_PxE_CONFIG *psPTEConfig;
+       const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
+       IMG_UINT32 uiRefCount;
+       IMG_UINT32 uiMaxRefCount;
+} RGX_PAGESIZECONFIG;
+
+/*
+ *
+ *  Configuration for heaps with 4kB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_4KBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_4KBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_4KBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig4KB;
+
+
+/*
+ *
+ *  Configuration for heaps with 16kB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_16KBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_16KBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_16KBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig16KB;
+
+
+/*
+ *
+ *  Configuration for heaps with 64kB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_64KBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_64KBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_64KBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig64KB;
+
+
+/*
+ *
+ *  Configuration for heaps with 256kB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_256KBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_256KBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig256KB;
+
+
+/*
+ *
+ *  Configuration for heaps with 1MB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_1MBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_1MBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_1MBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig1MB;
+
+
+/*
+ *
+ *  Configuration for heaps with 2MB Data-Page size
+ *
+ */
+
+static MMU_PxE_CONFIG sRGXMMUPDEConfig_2MBDP;
+static MMU_PxE_CONFIG sRGXMMUPTEConfig_2MBDP;
+static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_2MBDP;
+static RGX_PAGESIZECONFIG gsPageSizeConfig2MB;
+
+
+/* Forward declaration of protection bits derivation functions, for
+   the following structure */
+static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize);
+static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags);
+static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize);
+static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags);
+static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize);
+static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags);
+
+static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
+                                           const MMU_PxE_CONFIG **ppsMMUPDEConfig,
+                                           const MMU_PxE_CONFIG **ppsMMUPTEConfig,
+                                           const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
+                                           IMG_HANDLE *phPriv);
+
+static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv);
+
+static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize);
+static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize);
+
+static MMU_DEVICEATTRIBS sRGXMMUDeviceAttributes;
+
+PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       /*
+        * Setup sRGXMMUDeviceAttributes
+        */
+       sRGXMMUDeviceAttributes.eMMUType = PDUMP_MMU_TYPE_VARPAGE_40BIT;
+       sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3;
+       sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
+       sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig;
+       sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig;
+
+       /* Functions for deriving page table/dir/cat protection bits */
+       sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4;
+       sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4;
+       sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4;
+
+       /* Functions for establishing configurations for PDE/PTE/DEVVADDR
+          on per-heap basis */
+       sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB;
+       sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB;
+
+       sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE4 = RGXGetPageSizeFromPDE4;
+       sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE8 = RGXGetPageSizeFromPDE8;
+
+       /*
+        * Setup sRGXMMUPCEConfig
+        */
+       sRGXMMUPCEConfig.uiBytesPerEntry = 4; /* 32 bit entries */
+       sRGXMMUPCEConfig.uiAddrMask = 0xfffffff0; /* Mask to get significant address bits of PC entry */
+
+       sRGXMMUPCEConfig.uiAddrShift = 4; /* Shift this many bits to get PD address in PC entry */
+       sRGXMMUPCEConfig.uiLog2Align = 12; /* Alignment of PD AND PC */
+
+       sRGXMMUPCEConfig.uiProtMask = RGX_MMUCTRL_PCE_PROTMASK; //Mask to get the status bits of the PC */
+       sRGXMMUPCEConfig.uiProtShift = 0; /* Shift this many bits to have status bits starting with bit 0 */
+
+       sRGXMMUPCEConfig.uiValidEnMask = RGX_MMUCTRL_PC_DATA_VALID_EN; /* Mask to get entry valid bit of the PC */
+       sRGXMMUPCEConfig.uiValidEnShift = RGX_MMUCTRL_PC_DATA_VALID_SHIFT; /* Shift this many bits to have entry valid bit starting with bit 0 */
+
+       /*
+        *  Setup sRGXMMUTopLevelDevVAddrConfig
+        */
+       sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; /* Get the PC address bits from a 40 bit virt. address (in a 64bit UINT) */
+       sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; /* Get the PD address bits from a 40 bit virt. address (in a 64bit UINT) */
+       sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+/*
+ *
+ *  Configuration for heaps with 4kB Data-Page size
+ *
+ */
+
+       /*
+        * Setup sRGXMMUPDEConfig_4KBDP
+        */
+       sRGXMMUPDEConfig_4KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_4KBDP.uiAddrShift = 12;
+       sRGXMMUPDEConfig_4KBDP.uiLog2Align = 12;
+
+       sRGXMMUPDEConfig_4KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_4KBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_4KBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUPTEConfig_4KBDP
+        */
+       sRGXMMUPTEConfig_4KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffff000);
+       sRGXMMUPTEConfig_4KBDP.uiAddrShift = 12;
+       sRGXMMUPTEConfig_4KBDP.uiLog2Align = 12;
+
+       sRGXMMUPTEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_4KBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_4KBDP
+        */
+       sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask = ~RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift = RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000000fff);
+       sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig4KB
+        */
+       gsPageSizeConfig4KB.psPDEConfig = &sRGXMMUPDEConfig_4KBDP;
+       gsPageSizeConfig4KB.psPTEConfig = &sRGXMMUPTEConfig_4KBDP;
+       gsPageSizeConfig4KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_4KBDP;
+       gsPageSizeConfig4KB.uiRefCount = 0;
+       gsPageSizeConfig4KB.uiMaxRefCount = 0;
+
+
+/*
+ *
+ *  Configuration for heaps with 16kB Data-Page size
+ *
+ */
+
+       /*
+        * Setup sRGXMMUPDEConfig_16KBDP
+        */
+       sRGXMMUPDEConfig_16KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_16KBDP.uiAddrShift = 10; /* These are for a page directory ENTRY, meaning the address of a PT cropped to suit the PD */
+       sRGXMMUPDEConfig_16KBDP.uiLog2Align = 10; /* Alignment of the page tables NOT directories */
+
+       sRGXMMUPDEConfig_16KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_16KBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_16KBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUPTEConfig_16KBDP
+        */
+       sRGXMMUPTEConfig_16KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xffffffc000);
+       sRGXMMUPTEConfig_16KBDP.uiAddrShift = 14; /* These are for a page table ENTRY, meaning the address of a PAGE cropped to suit the PD */
+       sRGXMMUPTEConfig_16KBDP.uiLog2Align = 14; /* Alignment of the pages NOT tables */
+
+       sRGXMMUPTEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_16KBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_16KBDP
+        */
+       sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001fc000);
+       sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift = 14;
+
+       sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000003fff);
+       sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig16KB
+        */
+       gsPageSizeConfig16KB.psPDEConfig = &sRGXMMUPDEConfig_16KBDP;
+       gsPageSizeConfig16KB.psPTEConfig = &sRGXMMUPTEConfig_16KBDP;
+       gsPageSizeConfig16KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_16KBDP;
+       gsPageSizeConfig16KB.uiRefCount = 0;
+       gsPageSizeConfig16KB.uiMaxRefCount = 0;
+
+
+/*
+ *
+ *  Configuration for heaps with 64kB Data-Page size
+ *
+ */
+
+       /*
+        * Setup sRGXMMUPDEConfig_64KBDP
+        */
+       sRGXMMUPDEConfig_64KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_64KBDP.uiAddrShift = 8;
+       sRGXMMUPDEConfig_64KBDP.uiLog2Align = 8;
+
+       sRGXMMUPDEConfig_64KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_64KBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_64KBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUPTEConfig_64KBDP
+        */
+       sRGXMMUPTEConfig_64KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xffffff0000);
+       sRGXMMUPTEConfig_64KBDP.uiAddrShift =16;
+       sRGXMMUPTEConfig_64KBDP.uiLog2Align = 16;
+
+       sRGXMMUPTEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_64KBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_64KBDP
+        */
+       sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001f0000);
+       sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift = 16;
+
+       sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000000ffff);
+       sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig64KB
+        */
+       gsPageSizeConfig64KB.psPDEConfig = &sRGXMMUPDEConfig_64KBDP;
+       gsPageSizeConfig64KB.psPTEConfig = &sRGXMMUPTEConfig_64KBDP;
+       gsPageSizeConfig64KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_64KBDP;
+       gsPageSizeConfig64KB.uiRefCount = 0;
+       gsPageSizeConfig64KB.uiMaxRefCount = 0;
+
+
+/*
+ *
+ *  Configuration for heaps with 256kB Data-Page size
+ *
+ */
+
+       /*
+        * Setup sRGXMMUPDEConfig_256KBDP
+        */
+       sRGXMMUPDEConfig_256KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_256KBDP.uiAddrShift = 6;
+       sRGXMMUPDEConfig_256KBDP.uiLog2Align = 6;
+
+       sRGXMMUPDEConfig_256KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_256KBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_256KBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP
+        */
+       sRGXMMUPTEConfig_256KBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffc0000);
+       sRGXMMUPTEConfig_256KBDP.uiAddrShift = 18;
+       sRGXMMUPTEConfig_256KBDP.uiLog2Align = 18;
+
+       sRGXMMUPTEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_256KBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_256KBDP
+        */
+       sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001c0000);
+       sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift = 18;
+
+       sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000003ffff);
+       sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig256KB
+        */
+       gsPageSizeConfig256KB.psPDEConfig = &sRGXMMUPDEConfig_256KBDP;
+       gsPageSizeConfig256KB.psPTEConfig = &sRGXMMUPTEConfig_256KBDP;
+       gsPageSizeConfig256KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_256KBDP;
+       gsPageSizeConfig256KB.uiRefCount = 0;
+       gsPageSizeConfig256KB.uiMaxRefCount = 0;
+
+       /*
+        * Setup sRGXMMUPDEConfig_1MBDP
+        */
+       sRGXMMUPDEConfig_1MBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_1MBDP.uiAddrShift = 4;
+       sRGXMMUPDEConfig_1MBDP.uiLog2Align = 4;
+
+       sRGXMMUPDEConfig_1MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_1MBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_1MBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUPTEConfig_1MBDP
+        */
+       sRGXMMUPTEConfig_1MBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffff00000);
+       sRGXMMUPTEConfig_1MBDP.uiAddrShift = 20;
+       sRGXMMUPTEConfig_1MBDP.uiLog2Align = 20;
+
+       sRGXMMUPTEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_1MBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_1MBDP
+        */
+       sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000100000);
+       sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift = 20;
+
+       sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00000fffff);
+       sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig1MB
+        */
+       gsPageSizeConfig1MB.psPDEConfig = &sRGXMMUPDEConfig_1MBDP;
+       gsPageSizeConfig1MB.psPTEConfig = &sRGXMMUPTEConfig_1MBDP;
+       gsPageSizeConfig1MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_1MBDP;
+       gsPageSizeConfig1MB.uiRefCount = 0;
+       gsPageSizeConfig1MB.uiMaxRefCount = 0;
+
+       /*
+        * Setup sRGXMMUPDEConfig_2MBDP
+        */
+       sRGXMMUPDEConfig_2MBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPDEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
+       sRGXMMUPDEConfig_2MBDP.uiAddrShift = 4;
+       sRGXMMUPDEConfig_2MBDP.uiLog2Align = 4;
+
+       sRGXMMUPDEConfig_2MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
+       sRGXMMUPDEConfig_2MBDP.uiVarCtrlShift = 1;
+
+       sRGXMMUPDEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
+       sRGXMMUPDEConfig_2MBDP.uiProtShift = 0;
+
+       sRGXMMUPDEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
+       sRGXMMUPDEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUPTEConfig_2MBDP
+        */
+       sRGXMMUPTEConfig_2MBDP.uiBytesPerEntry = 8;
+
+       sRGXMMUPTEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xffffe00000);
+       sRGXMMUPTEConfig_2MBDP.uiAddrShift = 21;
+       sRGXMMUPTEConfig_2MBDP.uiLog2Align = 21;
+
+       sRGXMMUPTEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
+       sRGXMMUPTEConfig_2MBDP.uiProtShift = 0;
+
+       sRGXMMUPTEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
+       sRGXMMUPTEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
+
+       /*
+        * Setup sRGXMMUDevVAddrConfig_2MBDP
+        */
+       sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
+       sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
+
+       sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000000000);
+       sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift = 21;
+
+       sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00001fffff);
+       sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetShift = 0;
+
+       /*
+        * Setup gsPageSizeConfig2MB
+        */
+       gsPageSizeConfig2MB.psPDEConfig = &sRGXMMUPDEConfig_2MBDP;
+       gsPageSizeConfig2MB.psPTEConfig = &sRGXMMUPTEConfig_2MBDP;
+       gsPageSizeConfig2MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_2MBDP;
+       gsPageSizeConfig2MB.uiRefCount = 0;
+       gsPageSizeConfig2MB.uiMaxRefCount = 0;
+
+       /*
+        * Setup sRGXMMUDeviceAttributes
+        */
+       sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3;
+       sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
+       sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig;
+       sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig;
+
+       /* Functions for deriving page table/dir/cat protection bits */
+       sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4;
+       sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4;
+       sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8;
+       sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4;
+
+       /* Functions for establishing configurations for PDE/PTE/DEVVADDR
+          on per-heap basis */
+       sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB;
+       sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB;
+
+       psDeviceNode->psMMUDevAttrs = &sRGXMMUDeviceAttributes;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+    PVRSRV_ERROR eError;
+
+    eError = PVRSRV_OK;
+
+#if defined(PDUMP)
+    psDeviceNode->pfnMMUGetContextID = IMG_NULL;
+#endif
+
+    psDeviceNode->psMMUDevAttrs = IMG_NULL;
+
+#if defined(DEBUG)
+    PVR_DPF((PVR_DBG_MESSAGE, "Variable Page Size Heap Stats:"));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 4K page heaps: %d",
+             gsPageSizeConfig4KB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 4K page heaps (should be 0): %d",
+             gsPageSizeConfig4KB.uiRefCount));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 16K page heaps: %d",
+             gsPageSizeConfig16KB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 16K page heaps (should be 0): %d",
+             gsPageSizeConfig16KB.uiRefCount));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 64K page heaps: %d",
+             gsPageSizeConfig64KB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 64K page heaps (should be 0): %d",
+             gsPageSizeConfig64KB.uiRefCount));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 256K page heaps: %d",
+             gsPageSizeConfig256KB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 256K page heaps (should be 0): %d",
+             gsPageSizeConfig256KB.uiRefCount));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 1M page heaps: %d",
+             gsPageSizeConfig1MB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 1M page heaps (should be 0): %d",
+             gsPageSizeConfig1MB.uiRefCount));
+    PVR_DPF((PVR_DBG_MESSAGE, "Max 2M page heaps: %d",
+             gsPageSizeConfig2MB.uiMaxRefCount));
+    PVR_DPF((PVR_DBG_VERBOSE, "Current 2M page heaps (should be 0): %d",
+             gsPageSizeConfig2MB.uiRefCount));
+#endif
+    if (gsPageSizeConfig4KB.uiRefCount > 0 ||
+        gsPageSizeConfig16KB.uiRefCount > 0 ||
+        gsPageSizeConfig64KB.uiRefCount > 0 ||
+        gsPageSizeConfig256KB.uiRefCount > 0 ||
+        gsPageSizeConfig1MB.uiRefCount > 0 ||
+        gsPageSizeConfig2MB.uiRefCount > 0
+        )
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RGXMMUInit_Unregister: Unbalanced MMU API Usage (Internal error)"));
+    }
+
+    return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePCEProt4
+@Description    calculate the PCE protection flags based on a 4 byte entry
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags)
+{
+    return (uiProtFlags & MMU_PROTFLAGS_INVALID)?0:RGX_MMUCTRL_PC_DATA_VALID_EN;
+}
+
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePCEProt8
+@Description    calculate the PCE protection flags based on an 8 byte entry
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize)
+{
+       PVR_UNREFERENCED_PARAMETER(uiProtFlags);
+       PVR_UNREFERENCED_PARAMETER(ui8Log2PageSize);
+
+       PVR_DPF((PVR_DBG_ERROR, "8-byte PCE not supported on this device"));
+       return 0;       
+}
+
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePDEProt4
+@Description    derive the PDE protection flags based on a 4 byte entry
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags)
+{
+    PVR_UNREFERENCED_PARAMETER(uiProtFlags);
+       PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
+       return 0;
+}
+
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePDEProt8
+@Description    derive the PDE protection flags based on an 8 byte entry
+
+@Input          ui8Log2PageSize The log2 of the required page size.
+                E.g, for 4KiB pages, this parameter must be 12.
+                For 2MiB pages, it must be set to 21.
+
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize)
+{
+       IMG_UINT64 ret_value = 0; // 0 means invalid
+
+    if (! (uiProtFlags & MMU_PROTFLAGS_INVALID)) // if not invalid
+       {
+               switch (ui8Log2PageSize)
+               {
+                       case 12:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB;
+                               break;
+                       case 14:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB;
+                               break;
+                       case 16:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB;
+                               break;
+                       case 18:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB;
+                               break;
+                       case 20:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB;
+                               break;
+                       case 21:
+                               ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB;
+                               break;
+                       default:
+                               PVR_DPF((PVR_DBG_ERROR,
+                                                "%s:%d: in function<%s>: Invalid parameter log2_page_size. Expected {12, 14, 16, 18, 20, 21}. Got [%u]",
+                                                __FILE__, __LINE__, __FUNCTION__, ui8Log2PageSize));
+               }
+       }
+       return ret_value;
+}
+
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePTEProt4
+@Description    calculate the PTE protection flags based on a 4 byte entry
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags)
+{
+    PVR_UNREFERENCED_PARAMETER(uiProtFlags);
+       PVR_DPF((PVR_DBG_ERROR, "4-byte PTE not supported on this device"));
+
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       RGXDerivePTEProt8
+@Description    calculate the PTE protection flags based on an 8 byte entry
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT8 ui8Log2PageSize)
+{
+       IMG_UINT64 ui64MMUFlags=0;
+
+       PVR_UNREFERENCED_PARAMETER(ui8Log2PageSize);
+
+       if(((MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE) & uiProtFlags) == (MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE))
+       {
+               /* read/write */
+       }
+       else if(MMU_PROTFLAGS_READABLE & uiProtFlags)
+       {
+               /* read only */
+               ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_READ_ONLY_EN;
+       }
+       else if(MMU_PROTFLAGS_WRITEABLE & uiProtFlags)
+       {
+               /* write only */
+        PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: write-only is not possible on this device"));
+       }
+    else if ((MMU_PROTFLAGS_INVALID & uiProtFlags) == 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: neither read nor write specified..."));
+    }
+
+       /* cache coherency */
+       if(MMU_PROTFLAGS_CACHE_COHERENT & uiProtFlags)
+       {
+               ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_CC_EN;
+       }
+
+       /* cache setup */
+       if ((MMU_PROTFLAGS_CACHED & uiProtFlags) == 0)
+       {
+               ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN;
+       }
+
+    if ((uiProtFlags & MMU_PROTFLAGS_INVALID) == 0)
+    {
+        ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_VALID_EN;
+    }
+
+       if (MMU_PROTFLAGS_DEVICE(PMMETA_PROTECT) & uiProtFlags)
+       {
+               ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN;
+       }
+
+       return ui64MMUFlags;
+}
+
+
+/*************************************************************************/ /*!
+@Function       RGXGetPageSizeConfig
+@Description    Set up configuration for variable sized data pages.
+                RGXPutPageSizeConfigCB has to be called to ensure correct
+                refcounting.
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
+                                           const MMU_PxE_CONFIG **ppsMMUPDEConfig,
+                                           const MMU_PxE_CONFIG **ppsMMUPTEConfig,
+                                           const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
+                                           IMG_HANDLE *phPriv)
+{
+    RGX_PAGESIZECONFIG *psPageSizeConfig;
+
+    switch (uiLog2DataPageSize)
+    {
+    case 12:
+        psPageSizeConfig = &gsPageSizeConfig4KB;
+        break;
+    case 14:
+        psPageSizeConfig = &gsPageSizeConfig16KB;
+        break;
+    case 16:
+        psPageSizeConfig = &gsPageSizeConfig64KB;
+        break;
+    case 18:
+        psPageSizeConfig = &gsPageSizeConfig256KB;
+        break;
+    case 20:
+        psPageSizeConfig = &gsPageSizeConfig1MB;
+        break;
+    case 21:
+        psPageSizeConfig = &gsPageSizeConfig2MB;
+        break;
+    default:
+        PVR_DPF((PVR_DBG_ERROR,
+                 "RGXGetPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
+                 uiLog2DataPageSize));
+        return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
+    }
+    
+    /* Refer caller's pointers to the data */
+    *ppsMMUPDEConfig = psPageSizeConfig->psPDEConfig;
+    *ppsMMUPTEConfig = psPageSizeConfig->psPTEConfig;
+    *ppsMMUDevVAddrConfig = psPageSizeConfig->psDevVAddrConfig;
+
+#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
+    /* Increment ref-count - not that we're allocating anything here
+       (I'm using static structs), but one day we might, so we want
+       the Get/Put code to be balanced properly */
+    psPageSizeConfig->uiRefCount ++;
+
+    /* This is purely for debug statistics */
+    psPageSizeConfig->uiMaxRefCount = MAX(psPageSizeConfig->uiMaxRefCount,
+                                          psPageSizeConfig->uiRefCount);
+#endif
+
+    *phPriv = (IMG_HANDLE)(IMG_UINTPTR_T)uiLog2DataPageSize;
+       PVR_ASSERT (uiLog2DataPageSize == (IMG_UINT32)(IMG_UINTPTR_T)*phPriv);
+
+    return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       RGXPutPageSizeConfig
+@Description    Tells this code that the mmu module is done with the
+                configurations set in RGXGetPageSizeConfig.  This can
+                be a no-op.
+                Called after RGXGetPageSizeConfigCB.
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv)
+{
+#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
+    RGX_PAGESIZECONFIG *psPageSizeConfig;
+    IMG_UINT32 uiLog2DataPageSize;
+
+    uiLog2DataPageSize = (IMG_UINT32)(IMG_UINTPTR_T) hPriv;
+
+    switch (uiLog2DataPageSize)
+    {
+    case 12:
+        psPageSizeConfig = &gsPageSizeConfig4KB;
+        break;
+    case 14:
+        psPageSizeConfig = &gsPageSizeConfig16KB;
+        break;
+    case 16:
+        psPageSizeConfig = &gsPageSizeConfig64KB;
+        break;
+    case 18:
+        psPageSizeConfig = &gsPageSizeConfig256KB;
+        break;
+    case 20:
+        psPageSizeConfig = &gsPageSizeConfig1MB;
+        break;
+    case 21:
+        psPageSizeConfig = &gsPageSizeConfig2MB;
+        break;
+    default:
+        PVR_DPF((PVR_DBG_ERROR,
+                 "RGXPutPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
+                 uiLog2DataPageSize));
+        return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
+    }
+
+    /* Ref-count here is not especially useful, but it's an extra
+       check that the API is being used correctly */
+    psPageSizeConfig->uiRefCount --;
+#else
+    PVR_UNREFERENCED_PARAMETER(hPriv);
+#endif
+    return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize)
+{
+    PVR_UNREFERENCED_PARAMETER(ui32PDE);
+    PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize);
+       PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
+       return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
+}
+
+static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize)
+{
+       switch (ui64PDE & (~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK))
+       {
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB:
+                       *pui32Log2PageSize = 12;
+                       break;
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB:
+                       *pui32Log2PageSize = 14;
+                       break;
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB:
+                       *pui32Log2PageSize = 16;
+                       break;
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB:
+                       *pui32Log2PageSize = 18;
+                       break;
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB:
+                       *pui32Log2PageSize = 20;
+                       break;
+               case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB:
+                       *pui32Log2PageSize = 21;
+                       break;
+               default:
+                       return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
+                       break;
+       }
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxmmuinit.h
new file mode 100644 (file)
index 0000000..c79a72e
--- /dev/null
@@ -0,0 +1,60 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific initialisation routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific MMU initialisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* NB: this file is not to be included arbitrarily.  It exists solely
+   for the linkage between rgxinit.c and rgxmmuinit.c, the former
+   being otherwise cluttered by the contents of the latter */
+
+#ifndef _SRVKM_RGXMMUINIT_H_
+#define _SRVKM_RGXMMUINIT_H_
+
+#include "device.h"
+#include "img_types.h"
+#include "mmu_common.h"
+#include "img_defs.h"
+
+IMG_EXPORT PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode);
+IMG_EXPORT PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+
+#endif /* #ifndef _SRVKM_RGXMMUINIT_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.c
new file mode 100644 (file)
index 0000000..0f245c0
--- /dev/null
@@ -0,0 +1,133 @@
+/*************************************************************************/ /*!
+@File                  rgxpdump.c
+@Title          Device specific pdump routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific pdump functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(PDUMP)
+
+#include "devicemem_pdump.h"
+#include "rgxpdump.h"
+
+/*
+ * PVRSRVPDumpSignatureBufferKM
+ */
+PVRSRV_ERROR PVRSRVPDumpSignatureBufferKM(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                                                 IMG_UINT32                    ui32PDumpFlags)
+{      
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+
+       /* TA signatures */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump TA signatures and checksums Buffer");
+        
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSigTAChecksMemDesc,
+                                                                0,
+                                                                psDevInfo->ui32SigTAChecksSize,
+                                                                "out.tasig",
+                                                                0,
+                                                                ui32PDumpFlags);
+
+       /* 3D signatures */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump 3D signatures and checksums Buffer");
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSig3DChecksMemDesc,
+                                                                0,
+                                                                psDevInfo->ui32Sig3DChecksSize,
+                                                                "out.3dsig",
+                                                                0,
+                                                                ui32PDumpFlags);
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       /* RT signatures */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump RTU signatures and checksums Buffer");
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSigRTChecksMemDesc,
+                                                                0,
+                                                                psDevInfo->ui32SigRTChecksSize,
+                                                                "out.rtsig",
+                                                                0,
+                                                                ui32PDumpFlags);
+                                                                
+       /* SH signatures */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump SHG signatures and checksums Buffer");
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWSigSHChecksMemDesc,
+                                                                0,
+                                                                psDevInfo->ui32SigSHChecksSize,
+                                                                "out.shsig",
+                                                                0,
+                                                                ui32PDumpFlags);
+#endif
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPDumpTraceBufferKM(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                         IMG_UINT32                    ui32PDumpFlags)
+{      
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+
+       /* Dump trace buffers */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump trace buffers");
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
+                                                               offsetof(RGXFWIF_TRACEBUF, sTraceBuf),
+                                                               RGXFW_THREAD_NUM * 
+                                                                  ( 1 * sizeof(IMG_UINT32) 
+                                                                   +RGXFW_TRACE_BUFFER_SIZE * sizeof(IMG_UINT32) 
+                                                                   +RGXFW_TRACE_BUFFER_ASSERT_SIZE * sizeof(IMG_CHAR)),
+                                                               "out.trace",
+                                                               0,
+                                                               ui32PDumpFlags);
+
+       /* Dump hwperf buffer */
+       PDumpCommentWithFlags(ui32PDumpFlags, "** Dump HWPerf Buffer");
+       DevmemPDumpSaveToFileVirtual(psDevInfo->psRGXFWIfHWPerfBufMemDesc,
+                                                                0,
+                                                                psDevInfo->ui32RGXFWIfHWPerfBufSize,
+                                                                "out.hwperf",
+                                                                0,
+                                                                ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+
+#endif /* PDUMP */
+
+/******************************************************************************
+ End of file (rgxpdump.c)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpdump.h
new file mode 100644 (file)
index 0000000..4cdf9cb
--- /dev/null
@@ -0,0 +1,112 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX pdump Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX pdump functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "rgxdevice.h"
+#include "device.h"
+#include "devicemem.h"
+#include "pdump_km.h"
+#include "pvr_debug.h"
+
+#if defined(PDUMP)
+/*!
+******************************************************************************
+
+ @Function     PVRSRVPDumpSignatureBufferKM
+
+ @Description
+
+ Dumps TA and 3D signature and checksum buffers
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPDumpSignatureBufferKM(PVRSRV_DEVICE_NODE   *psDeviceNode,
+                                                                               IMG_UINT32                      ui32PDumpFlags);
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVPDumpTraceBufferKM
+
+ @Description
+
+ Dumps TA and 3D signature and checksum buffers
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPDumpTraceBufferKM(PVRSRV_DEVICE_NODE       *psDeviceNode,
+                                                                               IMG_UINT32                      ui32PDumpFlags);
+#else          /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpSignatureBufferKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpSignatureBufferKM(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                                                        IMG_UINT32                     ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPDumpTraceBufferKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVPDumpTraceBufferKM(PVRSRV_DEVICE_NODE    *psDeviceNode,
+                                                IMG_UINT32                     ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+/******************************************************************************
+ End of file (rgxpdump.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.c
new file mode 100644 (file)
index 0000000..f8f6e99
--- /dev/null
@@ -0,0 +1,1353 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific power routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "rgxpower.h"
+#include "rgxinit.h"
+#include "rgx_fwif_km.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "pdump_km.h"
+#include "rgxdefs_km.h"
+#include "pvrsrv.h"
+#include "pvr_debug.h"
+#include "osfunc.h"
+#include "rgxdebug.h"
+#include "rgx_meta.h"
+#include "devicemem_pdump.h"
+#include "rgxapi_km.h"
+#include "rgxtimecorr.h"
+
+#include "process_stats.h"
+
+extern IMG_UINT32 g_ui32HostSampleIRQCount;
+
+#if ! defined(FIX_HW_BRN_37453)
+/*!
+*******************************************************************************
+
+ @Function     RGXEnableClocks
+
+ @Description Enable RGX Clocks
+
+ @Input psDevInfo - device info structure
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID RGXEnableClocks(PVRSRV_RGXDEV_INFO     *psDevInfo)
+{
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGX clock: use default (automatic clock gating)");
+}
+#endif
+#if defined(PVR_DVFS)
+#include "pvr_dvfs_device.h"
+#endif
+
+
+/*!
+*******************************************************************************
+
+ @Function     _RGXInitSLC
+
+ @Description Initialise RGX SLC
+
+ @Input psDevInfo - device info structure
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+#if !defined(RGX_FEATURE_S7_CACHE_HIERARCHY)
+
+#define RGX_INIT_SLC _RGXInitSLC
+
+static IMG_VOID _RGXInitSLC(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       IMG_UINT32      ui32Reg;
+       IMG_UINT32      ui32RegVal;
+
+#if defined(FIX_HW_BRN_36492)
+       /* Because the WA for this BRN forbids using SLC reset, need to inval it instead */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Invalidate the SLC");
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, 
+                       RGX_CR_SLC_CTRL_FLUSH_INVAL, RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN);
+       PDUMPREG32(RGX_PDUMPREG_NAME, 
+                       RGX_CR_SLC_CTRL_FLUSH_INVAL, RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN, 
+                       PDUMP_FLAGS_CONTINUOUS);
+
+       /* poll for completion */
+       PVRSRVPollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + RGX_CR_SLC_STATUS0),
+                                                        0x0,
+                                                        RGX_CR_SLC_STATUS0_INVAL_PENDING_EN);
+
+       PDUMPREGPOL(RGX_PDUMPREG_NAME,
+                               RGX_CR_SLC_STATUS0,
+                               0x0,
+                               RGX_CR_SLC_STATUS0_INVAL_PENDING_EN,
+                               PDUMP_FLAGS_CONTINUOUS,
+                               PDUMP_POLL_OPERATOR_EQUAL);
+#endif
+        
+       if (!PVRSRVSystemSnoopingOfCPUCache() && !PVRSRVSystemSnoopingOfDeviceCache())
+       {
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has NO cache snooping");
+       }
+       else
+       {
+               if (PVRSRVSystemSnoopingOfCPUCache())
+               {
+                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has CPU cache snooping");
+               }
+               if (PVRSRVSystemSnoopingOfDeviceCache())
+               {
+                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has DEVICE cache snooping");
+               }
+       }
+
+#if (RGX_FEATURE_SLC_SIZE_IN_BYTES < (128*1024))
+       /*
+        * SLC Bypass control
+        */
+       ui32Reg = RGX_CR_SLC_CTRL_BYPASS;
+
+       /* Bypass SLC for textures if the SLC size is less than 128kB */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Bypass SLC for TPU");
+       ui32RegVal = RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_EN;
+
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
+       PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+       /*
+        * SLC Bypass control
+        */
+       ui32Reg = RGX_CR_SLC_CTRL_MISC;
+       ui32RegVal = RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1;
+
+       /* Bypass burst combiner if SLC line size is smaller than 1024 bits */
+#if (RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS < 1024)
+       ui32RegVal |= RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN;
+#endif
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
+       PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
+
+}
+#endif /* RGX_FEATURE_S7_CACHE_HIERARCHY */
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXInitSLC3
+
+ @Description Initialise RGX SLC3
+
+ @Input psDevInfo - device info structure
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+#if defined(RGX_FEATURE_S7_CACHE_HIERARCHY)
+
+#define RGX_INIT_SLC _RGXInitSLC3
+
+static IMG_VOID _RGXInitSLC3(PVRSRV_RGXDEV_INFO        *psDevInfo)
+{
+       IMG_UINT32      ui32Reg;
+       IMG_UINT32      ui32RegVal;
+
+
+#if defined(HW_ERN_51468)
+    /*
+     * SLC control
+     */
+       ui32Reg = RGX_CR_SLC3_CTRL_MISC;
+       ui32RegVal = RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_WEAVED_HASH;
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
+       PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
+
+#else
+
+    /*
+     * SLC control
+     */
+       ui32Reg = RGX_CR_SLC3_CTRL_MISC;
+       ui32RegVal = RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SCRAMBLE_PVR_HASH;
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
+       PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
+
+       /*
+        * SLC scramble bits
+        */
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 aui32ScrambleRegs[] = {
+                   RGX_CR_SLC3_SCRAMBLE, 
+                   RGX_CR_SLC3_SCRAMBLE2,
+                   RGX_CR_SLC3_SCRAMBLE3,
+                   RGX_CR_SLC3_SCRAMBLE4};
+
+               IMG_UINT64 aui64ScrambleValues[] = {
+#if (RGX_FEATURE_SLC_BANKS == 2)
+                  IMG_UINT64_C(0x6965a99a55696a6a),
+                  IMG_UINT64_C(0x6aa9aa66959aaa9a),
+                  IMG_UINT64_C(0x9a5665965a99a566),
+                  IMG_UINT64_C(0x5aa69596aa66669a)
+#elif (RGX_FEATURE_SLC_BANKS == 4)
+                  IMG_UINT64_C(0xc6788d722dd29ce4),
+                  IMG_UINT64_C(0x7272e4e11b279372),
+                  IMG_UINT64_C(0x87d872d26c6c4be1),
+                  IMG_UINT64_C(0xe1b4878d4b36e478)
+#elif (RGX_FEATURE_SLC_BANKS == 8)
+                  IMG_UINT64_C(0x859d6569e8fac688),
+                  IMG_UINT64_C(0xf285e1eae4299d33),
+                  IMG_UINT64_C(0x1e1af2be3c0aa447)
+#endif        
+               };
+
+               for (i = 0;
+                    i < sizeof(aui64ScrambleValues)/sizeof(IMG_UINT64);
+                        i++)
+               {
+                       IMG_UINT32 ui32Reg = aui32ScrambleRegs[i];
+                       IMG_UINT64 ui64Value = aui64ScrambleValues[i];
+
+                       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, ui32Reg, ui64Value);
+                       PDUMPREG64(RGX_PDUMPREG_NAME, ui32Reg, ui64Value, PDUMP_FLAGS_CONTINUOUS);
+               }
+       }
+#endif
+
+#if defined(HW_ERN_45914)
+       /* Disable the forced SLC coherency which the hardware enables for compatibility with older pdumps */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: disable forced SLC coherency");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_GARTEN_SLC, 0);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_GARTEN_SLC, 0, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+}
+#endif
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXInitBIF
+
+ @Description Initialise RGX BIF
+
+ @Input psDevInfo - device info structure
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID RGXInitBIF(PVRSRV_RGXDEV_INFO  *psDevInfo)
+{
+       PVRSRV_ERROR    eError;
+       IMG_DEV_PHYADDR sPCAddr;
+
+       /*
+               Acquire the address of the Kernel Page Catalogue.
+       */
+       eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sPCAddr);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* Sanity check Cat-Base address */
+       PVR_ASSERT((((sPCAddr.uiAddr
+                       >> psDevInfo->ui32KernelCatBaseAlignShift)
+                       << psDevInfo->ui32KernelCatBaseShift)
+                       & ~psDevInfo->ui64KernelCatBaseMask) == 0x0UL);
+
+       /*
+               Write the kernel catalogue base.
+       */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGX firmware MMU Page Catalogue");
+
+       if (psDevInfo->ui32KernelCatBaseIdReg != -1)
+       {
+               /* Set the mapping index */
+               OSWriteHWReg32(psDevInfo->pvRegsBaseKM,
+                                               psDevInfo->ui32KernelCatBaseIdReg,
+                                               psDevInfo->ui32KernelCatBaseId);
+
+               /* pdump mapping context */
+               PDUMPREG32(RGX_PDUMPREG_NAME,
+                                                       psDevInfo->ui32KernelCatBaseIdReg,
+                                                       psDevInfo->ui32KernelCatBaseId,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+       }
+
+       if (psDevInfo->ui32KernelCatBaseWordSize == 8)
+       {
+               /* Write the cat-base address */
+               OSWriteHWReg64(psDevInfo->pvRegsBaseKM,
+                                               psDevInfo->ui32KernelCatBaseReg,
+                                               ((sPCAddr.uiAddr
+                                                       >> psDevInfo->ui32KernelCatBaseAlignShift)
+                                                       << psDevInfo->ui32KernelCatBaseShift)
+                                                       & psDevInfo->ui64KernelCatBaseMask);
+       }
+       else
+       {
+               /* Write the cat-base address */
+               OSWriteHWReg32(psDevInfo->pvRegsBaseKM,
+                                               psDevInfo->ui32KernelCatBaseReg,
+                                               (IMG_UINT32)(((sPCAddr.uiAddr
+                                                       >> psDevInfo->ui32KernelCatBaseAlignShift)
+                                                       << psDevInfo->ui32KernelCatBaseShift)
+                                                       & psDevInfo->ui64KernelCatBaseMask));
+       }
+
+       /* pdump catbase address */
+       MMU_PDumpWritePageCatBase(psDevInfo->psKernelMMUCtx,
+                                                         RGX_PDUMPREG_NAME,
+                                                         psDevInfo->ui32KernelCatBaseReg,
+                                                         psDevInfo->ui32KernelCatBaseWordSize,
+                                                         psDevInfo->ui32KernelCatBaseAlignShift,
+                                                         psDevInfo->ui32KernelCatBaseShift,
+                                                         PDUMP_FLAGS_CONTINUOUS);
+
+       /*
+        * Trusted META boot
+        */
+#if defined(SUPPORT_TRUSTED_DEVICE)
+       #if defined(TRUSTED_DEVICE_DEFAULT_ENABLED)
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitBIF: Trusted Device enabled");
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN);
+       PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN, PDUMP_FLAGS_CONTINUOUS);
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SYS_BUS_SECURE, RGX_CR_SYS_BUS_SECURE_ENABLE_EN);
+       PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_SYS_BUS_SECURE, RGX_CR_SYS_BUS_SECURE_ENABLE_EN, PDUMP_FLAGS_CONTINUOUS);
+       #else /* ! defined(TRUSTED_DEVICE_DEFAULT_ENABLED) */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitBIF: Trusted Device disabled");
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_TRUST, 0);
+       PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_BIF_TRUST, 0, PDUMP_FLAGS_CONTINUOUS);
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SYS_BUS_SECURE, 0);
+       PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_SYS_BUS_SECURE, 0, PDUMP_FLAGS_CONTINUOUS);
+       #endif /* TRUSTED_DEVICE_DEFAULT_ENABLED */
+#endif
+
+}
+
+#if defined(RGX_FEATURE_AXI_ACELITE)
+/*!
+*******************************************************************************
+
+ @Function     RGXAXIACELiteInit
+
+ @Description Initialise AXI-ACE Lite interface
+
+ @Input psDevInfo - device info structure
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+static IMG_VOID RGXAXIACELiteInit(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       IMG_UINT32 ui32RegAddr;
+       IMG_UINT64 ui64RegVal;
+
+       ui32RegAddr = RGX_CR_AXI_ACE_LITE_CONFIGURATION;
+
+       /* Setup AXI-ACE config. Set everything to outer cache */
+       ui64RegVal =   (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT) |
+                                  (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT) |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT)  |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT) |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT) |
+                                  (((IMG_UINT64) 1) << RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_SHIFT) |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT) |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT) |
+                                  (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT);
+
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM,
+                                  ui32RegAddr,
+                                  ui64RegVal);
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Init AXI-ACE interface");
+       PDUMPREG64(RGX_PDUMPREG_NAME, ui32RegAddr, ui64RegVal, PDUMP_FLAGS_CONTINUOUS);
+}
+#endif
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXStart
+
+ @Description
+
+ (client invoked) chip-reset and initialisation
+
+ @Input psDevInfo - device info structure
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR RGXStart(PVRSRV_RGXDEV_INFO        *psDevInfo, PVRSRV_DEVICE_CONFIG *psDevConfig)
+{
+       PVRSRV_ERROR    eError = PVRSRV_OK;
+       RGXFWIF_INIT    *psRGXFWInit;
+
+#if defined(FIX_HW_BRN_37453)
+       /* Force all clocks on*/
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: force all clocks on");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_ON);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_ON, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+#if defined(SUPPORT_SHARED_SLC)        && !defined(FIX_HW_BRN_36492)
+       /* When the SLC is shared, the SLC reset is performed by the System layer when calling
+        * RGXInitSLC (before any device uses it), therefore mask out the SLC bit to avoid
+        * soft_resetting it here. If HW_BRN_36492, the bit is already masked out. 
+        */
+#define        RGX_CR_SOFT_RESET_ALL   (RGX_CR_SOFT_RESET_MASKFULL ^ RGX_CR_SOFT_RESET_SLC_EN)
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Shared SLC (don't reset SLC as part of RGX reset)");
+#else
+#define        RGX_CR_SOFT_RESET_ALL   (RGX_CR_SOFT_RESET_MASKFULL)
+#endif
+
+#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+       /* Set RGX in soft-reset */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset assert step 1");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS, PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset assert step 2");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_JONES_ALL | RGX_S7_SOFT_RESET_DUSTS);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_JONES_ALL | RGX_S7_SOFT_RESET_DUSTS, PDUMP_FLAGS_CONTINUOUS);
+
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, RGX_S7_SOFT_RESET2);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET2, RGX_S7_SOFT_RESET2, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Take everything out of reset but META */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset de-assert step 1 excluding META");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS | RGX_CR_SOFT_RESET_GARTEN_EN);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS | RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
+
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, 0x0);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET2, 0x0, PDUMP_FLAGS_CONTINUOUS);
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset de-assert step 2 excluding META");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+#else
+       /* Set RGX in soft-reset */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset everything");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Take Rascal and Dust out of reset */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Rascal and Dust out of reset");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL ^ RGX_CR_SOFT_RESET_RASCALDUSTS_EN);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL ^ RGX_CR_SOFT_RESET_RASCALDUSTS_EN, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Take everything out of reset but META */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Take everything out of reset but META");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+#if ! defined(FIX_HW_BRN_37453)
+       /*
+        * Enable clocks.
+        */
+       RGXEnableClocks(psDevInfo);
+#endif
+
+       /*
+        * Initialise SLC.
+        */
+#if !defined(SUPPORT_SHARED_SLC)       
+       RGX_INIT_SLC(psDevInfo);
+#endif
+
+#if !defined(SUPPORT_META_SLAVE_BOOT)
+       /* Configure META to Master boot */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: META Master boot");
+       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_BOOT, RGX_CR_META_BOOT_MODE_EN);
+       PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_META_BOOT, RGX_CR_META_BOOT_MODE_EN, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+       /* Set Garten IDLE to META idle and Set the Garten Wrapper BIF Fence address */
+       {
+               IMG_UINT64 ui64GartenConfig;
+
+               /* Garten IDLE bit controlled by META */
+               ui64GartenConfig = RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META;
+
+               /* Set fence addr to the bootloader */
+               ui64GartenConfig |= (RGXFW_BOOTLDR_DEVV_ADDR & ~RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK);
+
+               /* Set PC = 0 for fences */
+               ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK;
+
+#if defined(RGX_FEATURE_SLC_VIVT)
+#if !defined(FIX_HW_BRN_51281)
+               /* Ensure the META fences go all the way to external memory */
+               ui64GartenConfig |= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_EN;    /* SLC Coherent 1 */
+               ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_CLRMSK; /* SLC Persistence 0 */
+#endif
+
+#else 
+               /* Set SLC DM=META */
+               ui64GartenConfig |= ((IMG_UINT64) RGXFW_SEGMMU_META_DM_ID) << RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT;
+
+#endif
+
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Configure META wrapper");
+               OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, ui64GartenConfig);
+               PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, ui64GartenConfig, PDUMP_FLAGS_CONTINUOUS);
+       }
+
+#if defined(RGX_FEATURE_AXI_ACELITE)
+       /*
+               We must init the AXI-ACE interface before 1st BIF transaction
+       */
+       RGXAXIACELiteInit(psDevInfo);
+#endif
+
+       /*
+        * Initialise BIF.
+        */
+       RGXInitBIF(psDevInfo);
+
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Take META out of reset");
+       /* need to wait for at least 16 cycles before taking meta out of reset ... */
+       PVRSRVSystemWaitCycles(psDevConfig, 32);
+       PDUMPIDLWITHFLAGS(32, PDUMP_FLAGS_CONTINUOUS);
+       
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, 0x0);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, 0x0, PDUMP_FLAGS_CONTINUOUS);
+
+       (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+       
+       /* ... and afterwards */
+       PVRSRVSystemWaitCycles(psDevConfig, 32);
+       PDUMPIDLWITHFLAGS(32, PDUMP_FLAGS_CONTINUOUS);
+#if defined(FIX_HW_BRN_37453)
+       /* we rely on the 32 clk sleep from above */
+
+       /* switch clocks back to auto */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: set clocks back to auto");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_AUTO);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_AUTO, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+       /*
+        * Start the firmware.
+        */
+#if defined(SUPPORT_META_SLAVE_BOOT)
+       RGXStartFirmware(psDevInfo);
+#else
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: RGX Firmware Master boot Start");
+#endif
+       
+       OSMemoryBarrier();
+
+       /* Check whether the FW has started by polling on bFirmwareStarted flag */
+       eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                         (IMG_VOID **)&psRGXFWInit);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXStart: Failed to acquire kernel fw if ctl (%u)", eError));
+               return eError;
+       }
+
+       if (PVRSRVPollForValueKM((IMG_UINT32 *)&psRGXFWInit->bFirmwareStarted,
+                                                        IMG_TRUE,
+                                                        0xFFFFFFFF) != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXStart: Polling for 'FW started' flag failed."));
+               eError = PVRSRV_ERROR_TIMEOUT;
+               DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+               return eError;
+       }
+
+#if defined(PDUMP)
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Wait for the Firmware to start.");
+       eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
+                                                                                       offsetof(RGXFWIF_INIT, bFirmwareStarted),
+                                                                                       IMG_TRUE,
+                                                                                       0xFFFFFFFFU,
+                                                                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                                                                       PDUMP_FLAGS_CONTINUOUS);
+       
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXStart: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
+               DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+               return eError;
+       }
+#endif
+
+       SetFirmwareStartTime(psRGXFWInit->ui32FirmwareStartedTimeStamp);
+
+       DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
+
+       return eError;
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function     RGXStop
+
+ @Description Stop RGX in preparation for power down
+
+ @Input psDevInfo - RGX device info
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR RGXStop(PVRSRV_RGXDEV_INFO *psDevInfo)
+
+{
+       PVRSRV_ERROR            eError; 
+
+
+       eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDeinitCommands, RGX_MAX_DEINIT_COMMANDS, PDUMP_FLAGS_CONTINUOUS, IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXStop: RGXRunScript failed (%d)", eError));
+               return eError;
+       }
+
+
+       return PVRSRV_OK;
+}
+
+/*
+       RGXInitSLC
+*/
+#if defined(SUPPORT_SHARED_SLC)
+PVRSRV_ERROR RGXInitSLC(IMG_HANDLE hDevHandle)
+{
+
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo;
+
+       if (psDeviceNode == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psDevInfo = psDeviceNode->pvDevice;
+
+#if !defined(FIX_HW_BRN_36492)
+
+       /* reset the SLC */
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitSLC: soft reset SLC");
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_SLC_EN);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_SLC_EN, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
+       OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
+       PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
+
+       /* Take everything out of reset */
+       OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, 0);
+       PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, 0, PDUMP_FLAGS_CONTINUOUS);
+#endif
+
+       RGX_INIT_SLC(psDevInfo);
+
+       return PVRSRV_OK;
+}
+#endif
+
+
+static IMG_VOID _RGXUpdateGPUUtilStats(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb;
+       IMG_UINT64 *paui64StatsCounters;
+       IMG_UINT64 ui64LastPeriod;
+       IMG_UINT64 ui64LastState;
+       IMG_UINT64 ui64LastTime;
+       IMG_UINT64 ui64TimeNow;
+
+       psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb;
+       paui64StatsCounters = &psUtilFWCb->aui64StatsCounters[0];
+
+       OSLockAcquire(psDevInfo->hGPUUtilLock);
+
+       ui64TimeNow = RGXFWIF_GPU_UTIL_GET_TIME(OSClockns64());
+
+       /* Update counters to account for the time since the last update */
+       ui64LastState  = RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord);
+       ui64LastTime   = RGXFWIF_GPU_UTIL_GET_TIME(psUtilFWCb->ui64LastWord);
+       ui64LastPeriod = RGXFWIF_GPU_UTIL_GET_PERIOD(ui64TimeNow, ui64LastTime);
+       paui64StatsCounters[ui64LastState] += ui64LastPeriod;
+
+       /* Update state and time of the latest update */
+       psUtilFWCb->ui64LastWord = RGXFWIF_GPU_UTIL_MAKE_WORD(ui64TimeNow, ui64LastState);
+
+       OSLockRelease(psDevInfo->hGPUUtilLock);
+}
+
+
+/*
+       RGXPrePowerState
+*/
+PVRSRV_ERROR RGXPrePowerState (IMG_HANDLE                              hDevHandle,
+                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState,
+                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState,
+                                                          IMG_BOOL                                     bForced)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if ((eNewPowerState != eCurrentPowerState) &&
+               (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
+       {
+               PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+               PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+               RGXFWIF_KCCB_CMD        sPowCmd;
+               RGXFWIF_TRACEBUF        *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+               IMG_UINT32                      ui32DM;
+
+               /* Send the Power off request to the FW */
+               sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
+               sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_OFF_REQ;
+               sPowCmd.uCmdData.sPowData.uPoweReqData.bForced = bForced;
+
+               SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
+
+               /* Send one pow command to each DM to make sure we flush all the DMs pipelines */
+               for (ui32DM = 0; ui32DM < RGXFWIF_DM_MAX; ui32DM++)
+               {
+                       eError = RGXSendCommandRaw(psDevInfo,
+                                       ui32DM,
+                                       &sPowCmd,
+                                       sizeof(sPowCmd),
+                                       0);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Failed to send Power off request for DM%d", ui32DM));
+                               return eError;
+                       }
+               }
+
+               /* Wait for the firmware to complete processing. It cannot use PVRSRVWaitForValueKM as it relies 
+                  on the EventObject which is signalled in this MISR */
+               eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
+
+               /* Check the Power state after the answer */
+               if (eError == PVRSRV_OK)        
+               {
+                       /* Finally, de-initialise some registers. */
+                       if (psFWTraceBuf->ePowState == RGXFWIF_POW_OFF)
+                       {
+#if !defined(NO_HARDWARE)
+                               /* Wait for the pending META to host interrupts to come back. */
+                               eError = PVRSRVPollForValueKM(&g_ui32HostSampleIRQCount,
+                                                                                 psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount,
+                                                                                 0xffffffff);
+
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Wait for pending interrupts failed. Host:%d, FW: %d",
+                                       g_ui32HostSampleIRQCount,
+                                       psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount));
+
+                                       RGX_WaitForInterruptsTimeout(psDevInfo);
+                               }
+#endif /* NO_HARDWARE */
+
+                               /* Update GPU frequency and timer correlation related data */
+                               RGXGPUFreqCalibratePrePowerState(psDeviceNode);
+
+                               /* Update GPU state counters */
+                               _RGXUpdateGPUUtilStats(psDevInfo);
+
+#if defined(PVR_DVFS)
+                               eError = SuspendDVFS();
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: Failed to suspend DVFS"));
+                                       return eError;
+                               }
+#endif
+                               eError = RGXStop(psDevInfo);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: RGXStop failed (%s)", PVRSRVGetErrorStringKM(eError)));
+                                       eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE;
+                               }
+                               psDevInfo->bIgnoreFurtherIRQs = IMG_TRUE;
+                       }
+                       else
+                       {
+                               /* the sync was updated bu the pow state isn't off -> the FW denied the transition */
+                               eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED;
+
+                               if (bForced)
+                               {       /* It is an error for a forced request to be denied */
+                                       PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Failure to power off during a forced power off. FW: %d", psFWTraceBuf->ePowState));
+                               }
+                       }
+               }
+               else if (eError == PVRSRV_ERROR_TIMEOUT)
+               {
+                       /* timeout waiting for the FW to ack the request: return timeout */
+                       PVR_DPF((PVR_DBG_WARNING,"RGXPrePowerState: Timeout waiting for powoff ack from the FW"));
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Error waiting for powoff ack from the FW (%s)", PVRSRVGetErrorStringKM(eError)));
+                       eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE;
+               }
+
+       }
+
+       return eError;
+}
+
+
+/*
+       RGXPostPowerState
+*/
+PVRSRV_ERROR RGXPostPowerState (IMG_HANDLE                             hDevHandle,
+                                                               PVRSRV_DEV_POWER_STATE  eNewPowerState,
+                                                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState,
+                                                               IMG_BOOL                                bForced)
+{
+       if ((eNewPowerState != eCurrentPowerState) &&
+               (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
+       {
+               PVRSRV_ERROR             eError;
+               PVRSRV_DEVICE_NODE       *psDeviceNode = hDevHandle;
+               PVRSRV_RGXDEV_INFO       *psDevInfo = psDeviceNode->pvDevice;
+               PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig;
+
+               if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+               {
+                       /* Update GPU frequency and timer correlation related data */
+                       RGXGPUFreqCalibratePostPowerState(psDeviceNode);
+
+                       /* Update GPU state counters */
+                       _RGXUpdateGPUUtilStats(psDevInfo);
+
+                       /*
+                               Run the RGX init script.
+                       */
+                       eError = RGXStart(psDevInfo, psDevConfig);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: RGXStart failed"));
+                               return eError;
+                       }
+
+                       /* Coming up from off, re-allow RGX interrupts.  */
+                       psDevInfo->bIgnoreFurtherIRQs = IMG_FALSE;
+
+#if defined(PVR_DVFS)
+                       eError = ResumeDVFS();
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: Failed to resume DVFS"));
+                               return eError;
+                       }
+#endif
+               }
+       }
+
+       PDUMPCOMMENT("RGXPostPowerState: Current state: %d, New state: %d", eCurrentPowerState, eNewPowerState);
+
+       return PVRSRV_OK;
+}
+
+
+/*
+       RGXPreClockSpeedChange
+*/
+PVRSRV_ERROR RGXPreClockSpeedChange (IMG_HANDLE                                hDevHandle,
+                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_DATA                        *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
+       RGXFWIF_TRACEBUF        *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+
+       PVR_UNREFERENCED_PARAMETER(psRGXData);
+
+       PVR_DPF((PVR_DBG_MESSAGE,"RGXPreClockSpeedChange: RGX clock speed was %uHz",
+                       psRGXData->psRGXTimingInfo->ui32CoreClockSpeed));
+
+    if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF)
+               && (psFWTraceBuf->ePowState != RGXFWIF_POW_OFF))
+       {
+               /* Update GPU frequency and timer correlation related data */
+               RGXGPUFreqCalibratePreClockSpeedChange(psDeviceNode);
+       }
+
+       return eError;
+}
+
+
+/*
+       RGXPostClockSpeedChange
+*/
+PVRSRV_ERROR RGXPostClockSpeedChange (IMG_HANDLE                               hDevHandle,
+                                                                         PVRSRV_DEV_POWER_STATE        eCurrentPowerState)
+{
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_DATA                        *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_TRACEBUF        *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+       IMG_UINT32              ui32NewClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
+
+       /* Update runtime configuration with the new value */
+       psDevInfo->psRGXFWIfRuntimeCfg->ui32CoreClockSpeed = ui32NewClockSpeed;
+
+    if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF) 
+               && (psFWTraceBuf->ePowState != RGXFWIF_POW_OFF))
+       {
+               RGXFWIF_KCCB_CMD        sCOREClkSpeedChangeCmd;
+
+               RGXGPUFreqCalibratePostClockSpeedChange(psDeviceNode, ui32NewClockSpeed);
+
+               sCOREClkSpeedChangeCmd.eCmdType = RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE;
+               sCOREClkSpeedChangeCmd.uCmdData.sCORECLKSPEEDCHANGEData.ui32NewClockSpeed = ui32NewClockSpeed;
+
+               /* Ensure the new clock speed is written to memory before requesting the FW to read it */
+               OSMemoryBarrier();
+
+               PDUMPCOMMENT("Scheduling CORE clock speed change command");
+
+               PDUMPPOWCMDSTART();
+               eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
+                                          RGXFWIF_DM_GP,
+                                          &sCOREClkSpeedChangeCmd,
+                                          sizeof(sCOREClkSpeedChangeCmd),
+                                          0);
+               PDUMPPOWCMDEND();
+
+               if (eError != PVRSRV_OK)
+               {
+                       PDUMPCOMMENT("Scheduling CORE clock speed change command failed");
+                       PVR_DPF((PVR_DBG_ERROR, "RGXPostClockSpeedChange: Scheduling KCCB command failed. Error:%u", eError));
+                       return eError;
+               }
+               PVR_DPF((PVR_DBG_MESSAGE,"RGXPostClockSpeedChange: RGX clock speed changed to %uHz",
+                               psRGXData->psRGXTimingInfo->ui32CoreClockSpeed));
+       }
+
+       return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     RGXDustCountChange
+
+ @Description
+
+       Does change of number of DUSTs
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           ui32NumberOfDusts : Number of DUSTs to make transition to
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXDustCountChange(IMG_HANDLE                             hDevHandle,
+                                                               IMG_UINT32                              ui32NumberOfDusts)
+{
+
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_ERROR            eError;
+       RGXFWIF_KCCB_CMD        sDustCountChange;
+       IMG_UINT32                      ui32MaxAvailableDusts = RGX_FEATURE_NUM_CLUSTERS / 2;
+
+#if !defined(NO_HARDWARE)
+       RGXFWIF_TRACEBUF        *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+
+       if (psFWTraceBuf->ePowState != RGXFWIF_POW_FORCED_IDLE)
+       {
+               eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED;
+               PVR_DPF((PVR_DBG_ERROR,"RGXDustCountChange: Attempt to change dust count when not IDLE"));
+               return eError;
+       }
+#endif
+
+       PVR_ASSERT(ui32MaxAvailableDusts > 1);
+
+       if (ui32NumberOfDusts > ui32MaxAvailableDusts)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               PVR_DPF((PVR_DBG_ERROR, 
+                               "RGXDustCountChange: Invalid number of DUSTs (%u) while expecting value within <0,%u>. Error:%u",
+                               ui32NumberOfDusts,
+                               ui32MaxAvailableDusts,
+                               eError));
+               return eError;
+       }
+
+       SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
+
+       sDustCountChange.eCmdType = RGXFWIF_KCCB_CMD_POW;
+       sDustCountChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_NUMDUST_CHANGE;
+       sDustCountChange.uCmdData.sPowData.uPoweReqData.ui32NumOfDusts = ui32NumberOfDusts;
+
+       PDUMPCOMMENT("Scheduling command to change Dust Count to %u", ui32NumberOfDusts);
+       eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sDustCountChange,
+                               sizeof(sDustCountChange),
+                               0);
+
+       if (eError != PVRSRV_OK)
+       {
+               PDUMPCOMMENT("Scheduling command to change Dust Count failed. Error:%u", eError);
+               PVR_DPF((PVR_DBG_ERROR, "RGXDustCountChange: Scheduling KCCB to change Dust Count failed. Error:%u", eError));
+               return eError;
+       }
+
+       /* Wait for the firmware to answer. */
+       eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXDustCountChange: Timeout waiting for idle request"));
+               return eError;
+       }
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("RGXDustCountChange: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
+
+       SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
+                                       1,
+                                       0xffffffff,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       0);
+#endif
+
+       return PVRSRV_OK;
+}
+/*
+ @Function     RGXAPMLatencyChange
+*/
+PVRSRV_ERROR RGXAPMLatencyChange(IMG_HANDLE                            hDevHandle,
+                               IMG_UINT32                              ui32ActivePMLatencyms,
+                               IMG_BOOL                                bActivePMLatencyPersistant)
+{
+
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_ERROR            eError;
+       RGXFWIF_RUNTIME_CFG     *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg;
+       PVRSRV_DEV_POWER_STATE  ePowerState;
+
+       eError = PVRSRVPowerLock();
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXAPMLatencyChange: Failed to acquire power lock"));
+               return eError;
+       }
+
+       /* Update runtime configuration with the new values */
+       psRuntimeCfg->ui32ActivePMLatencyms = ui32ActivePMLatencyms;
+       psRuntimeCfg->bActivePMLatencyPersistant = bActivePMLatencyPersistant;
+
+       eError = PVRSRVGetDevicePowerState(psDeviceNode->sDevId.ui32DeviceIndex, &ePowerState);
+
+       if ((eError == PVRSRV_OK) && (ePowerState != PVRSRV_DEV_POWER_STATE_OFF))
+       {
+               RGXFWIF_KCCB_CMD        sActivePMLatencyChange;
+               sActivePMLatencyChange.eCmdType = RGXFWIF_KCCB_CMD_POW;
+               sActivePMLatencyChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_APM_LATENCY_CHANGE;
+               sActivePMLatencyChange.uCmdData.sPowData.uPoweReqData.ui32ActivePMLatencyms = ui32ActivePMLatencyms;
+
+               /* Ensure the new APM latency is written to memory before requesting the FW to read it */
+               OSMemoryBarrier();
+
+               PDUMPCOMMENT("Scheduling command to change APM latency to %u", ui32ActivePMLatencyms);
+               eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
+                                       RGXFWIF_DM_GP,
+                                       &sActivePMLatencyChange,
+                                       sizeof(sActivePMLatencyChange),
+                                       0);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PDUMPCOMMENT("Scheduling command to change APM latency failed. Error:%u", eError);
+                       PVR_DPF((PVR_DBG_ERROR, "RGXAPMLatencyChange: Scheduling KCCB to change APM latency failed. Error:%u", eError));
+                       return eError;
+               }
+       }
+
+       PVRSRVPowerUnlock();
+
+       return PVRSRV_OK;
+}
+
+/*
+       RGXActivePowerRequest
+*/
+PVRSRV_ERROR RGXActivePowerRequest(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+
+       OSAcquireBridgeLock();
+       /* NOTE: If this function were to wait for event object attempt should be
+          made to prevent releasing bridge lock during sleep. Bridge lock should
+          be held during sleep. */
+
+       /* Powerlock to avoid further requests from racing with the FW hand-shake from now on
+          (previous kicks to this point are detected by the FW) */
+       eError = PVRSRVPowerLock();
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXActivePowerRequest: Failed to acquire PowerLock (device index: %d, error: %s)", 
+                                       psDeviceNode->sDevId.ui32DeviceIndex,
+                                       PVRSRVGetErrorStringKM(eError)));
+               goto _RGXActivePowerRequest_PowerLock_failed;
+       }
+
+       /* Check again for IDLE once we have the power lock */
+       if (psFWTraceBuf->ePowState == RGXFWIF_POW_IDLE)
+       {
+
+               psDevInfo->ui32ActivePMReqTotal++;
+
+        SetFirmwareHandshakeIdleTime(RGXReadHWTimerReg(psDevInfo)-psFWTraceBuf->ui64StartIdleTime);
+
+               PDUMPPOWCMDSTART();
+               eError = 
+                       PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                       PVRSRV_DEV_POWER_STATE_OFF,
+                                       IMG_FALSE); /* forced */
+               PDUMPPOWCMDEND();
+
+               if (eError == PVRSRV_OK)
+               {
+                       psDevInfo->ui32ActivePMReqOk++;
+               }
+               else if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
+               {
+                       psDevInfo->ui32ActivePMReqDenied++;
+               }
+
+       }
+
+       PVRSRVPowerUnlock();
+
+_RGXActivePowerRequest_PowerLock_failed:
+       OSReleaseBridgeLock();
+
+       return eError;
+
+}
+/*
+       RGXForcedIdleRequest
+*/
+
+#define RGX_FORCED_IDLE_RETRY_COUNT 10
+
+PVRSRV_ERROR RGXForcedIdleRequest(IMG_HANDLE hDevHandle, IMG_BOOL bDeviceOffPermitted)
+{
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_KCCB_CMD        sPowCmd;
+       PVRSRV_ERROR            eError;
+       IMG_UINT32              ui32RetryCount = 0;
+
+#if !defined(NO_HARDWARE)
+       RGXFWIF_TRACEBUF        *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
+
+       /* Firmware already forced idle */
+       if (psFWTraceBuf->ePowState == RGXFWIF_POW_FORCED_IDLE)
+       {
+               return PVRSRV_OK;
+       }
+
+       /* Firmware is not powered. Sometimes this is permitted, for instance we were forcing idle to power down. */
+       if (psFWTraceBuf->ePowState == RGXFWIF_POW_OFF)
+       {
+               return (bDeviceOffPermitted) ? PVRSRV_OK : PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED;
+       }
+#endif
+
+       SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
+       sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
+       sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ;
+       sPowCmd.uCmdData.sPowData.uPoweReqData.bCancelForcedIdle = IMG_FALSE;
+
+       PDUMPCOMMENT("RGXForcedIdleRequest: Sending forced idle command");
+
+       /* Send one forced IDLE command to GP */
+       eError = RGXSendCommandRaw(psDevInfo,
+                       RGXFWIF_DM_GP,
+                       &sPowCmd,
+                       sizeof(sPowCmd),
+                       0);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Failed to send idle request"));
+               return eError;
+       }
+
+       /* Wait for GPU to finish current workload */
+       do {
+               eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
+               if ((eError == PVRSRV_OK) || (ui32RetryCount == RGX_FORCED_IDLE_RETRY_COUNT))
+               {
+                       break;
+               }
+               ui32RetryCount++;
+               PVR_DPF((PVR_DBG_WARNING,"RGXForcedIdleRequest: Request timeout. Retry %d of %d", ui32RetryCount, RGX_FORCED_IDLE_RETRY_COUNT));
+       } while (IMG_TRUE);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Idle request failed. Firmware potentially left in forced idle state"));
+               return eError;
+       }
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("RGXForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
+
+       SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
+                                       1,
+                                       0xffffffff,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       0);
+#endif
+
+#if !defined(NO_HARDWARE)
+       /* Check the firmware state for idleness */
+       if (psFWTraceBuf->ePowState != RGXFWIF_POW_FORCED_IDLE)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Failed to force IDLE"));
+
+               return PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED;
+       }
+#endif
+
+       return PVRSRV_OK;
+}
+
+/*
+       RGXCancelForcedIdleRequest
+*/
+PVRSRV_ERROR RGXCancelForcedIdleRequest(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_KCCB_CMD        sPowCmd;
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+
+       SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
+
+       /* Send the IDLE request to the FW */
+       sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
+       sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ;
+       sPowCmd.uCmdData.sPowData.uPoweReqData.bCancelForcedIdle = IMG_TRUE;
+
+       PDUMPCOMMENT("RGXForcedIdleRequest: Sending cancel forced idle command");
+
+       /* Send cancel forced IDLE command to GP */
+       eError = RGXSendCommandRaw(psDevInfo,
+                       RGXFWIF_DM_GP,
+                       &sPowCmd,
+                       sizeof(sPowCmd),
+                       0);
+
+       if (eError != PVRSRV_OK)
+       {
+               PDUMPCOMMENT("RGXCancelForcedIdleRequest: Failed to send cancel IDLE request for DM%d", RGXFWIF_DM_GP);
+               goto ErrorExit;
+       }
+
+       /* Wait for the firmware to answer. */
+       eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 1, 0xFFFFFFFF);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCancelForcedIdleRequest: Timeout waiting for cancel idle request"));
+               goto ErrorExit;
+       }
+
+#if defined(PDUMP)
+       PDUMPCOMMENT("RGXCancelForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
+
+       SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
+                                       1,
+                                       0xffffffff,
+                                       PDUMP_POLL_OPERATOR_EQUAL,
+                                       0);
+#endif
+
+       return eError;
+
+ErrorExit:
+       PVR_DPF((PVR_DBG_ERROR,"RGXCancelForcedIdleRequest: Firmware potentially left in forced idle state"));
+       return eError;
+}
+
+/******************************************************************************
+ End of file (rgxpower.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxpower.h
new file mode 100644 (file)
index 0000000..82f45e6
--- /dev/null
@@ -0,0 +1,216 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX power header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX power
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXPOWER_H__)
+#define __RGXPOWER_H__
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "servicesext.h"
+
+
+/*!
+******************************************************************************
+
+ @Function     RGXPrePowerState
+
+ @Description
+
+ does necessary preparation before power state transition
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           eNewPowerState : New power state
+ @Input           eCurrentPowerState : Current power state
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXPrePowerState(IMG_HANDLE                               hDevHandle, 
+                                                         PVRSRV_DEV_POWER_STATE        eNewPowerState, 
+                                                         PVRSRV_DEV_POWER_STATE        eCurrentPowerState,
+                                                         IMG_BOOL                                      bForced);
+
+/*!
+******************************************************************************
+
+ @Function     RGXPostPowerState
+
+ @Description
+
+ does necessary preparation after power state transition
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           eNewPowerState : New power state
+ @Input           eCurrentPowerState : Current power state
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXPostPowerState(IMG_HANDLE                              hDevHandle, 
+                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState, 
+                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState,
+                                                         IMG_BOOL                                      bForced);
+
+
+/*!
+******************************************************************************
+
+ @Function     RGXPreClockSpeedChange
+
+ @Description
+
+       Does processing required before an RGX clock speed change.
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           bIdleDevice : Whether the firmware needs to be idled
+ @Input           eCurrentPowerState : Power state of the device
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXPreClockSpeedChange(IMG_HANDLE                         hDevHandle,
+                                                                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
+
+/*!
+******************************************************************************
+
+ @Function     RGXPostClockSpeedChange
+
+ @Description
+
+       Does processing required after an RGX clock speed change.
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           bIdleDevice : Whether the firmware had been idled previously
+ @Input           eCurrentPowerState : Power state of the device
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXPostClockSpeedChange(IMG_HANDLE                                hDevHandle,
+                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+
+/*!
+******************************************************************************
+
+ @Function     RGXDustCountChange
+
+ @Description Change of number of DUSTs
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           ui32NumberOfDusts : Number of DUSTs to make transition to
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXDustCountChange(IMG_HANDLE                             hDevHandle,
+                                                               IMG_UINT32                              ui32NumberOfDusts);
+
+/*!
+******************************************************************************
+
+ @Function     RGXAPMLatencyChange
+
+ @Description
+
+       Changes the wait duration used before firmware indicates IDLE.
+       Reducing this value will cause the firmware to shut off faster and
+       more often but may increase bubbles in GPU scheduling due to the added
+       power management activity. If bPersistent is NOT set, APM latency will
+       return back to system default on power up.
+
+ @Input           hDevHandle : RGX Device Node
+ @Input           ui32ActivePMLatencyms : Number of milliseconds to wait
+ @Input           bPersistent : Set to ensure new value is not reset
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXAPMLatencyChange(IMG_HANDLE                            hDevHandle,
+                               IMG_UINT32                              ui32ActivePMLatencyms,
+                               IMG_BOOL                                bActivePMLatencyPersistant);
+
+/*!
+******************************************************************************
+
+ @Function     RGXActivePowerRequest
+
+ @Description Initiate a handshake with the FW to power off the GPU
+
+ @Input           hDevHandle : RGX Device Node
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXActivePowerRequest(IMG_HANDLE hDevHandle);
+
+/*!
+******************************************************************************
+
+ @Function     RGXForcedIdleRequest
+
+ @Description Initiate a handshake with the FW to idle the GPU
+
+ @Input           hDevHandle : RGX Device Node
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXForcedIdleRequest(IMG_HANDLE hDevHandle, IMG_BOOL bDeviceOffPermitted);
+
+/*!
+******************************************************************************
+
+ @Function     RGXCancelForcedIdleRequest
+
+ @Description Send a request to cancel idle to the firmware.
+
+ @Input           hDevHandle : RGX Device Node
+
+ @Return   PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR RGXCancelForcedIdleRequest(IMG_HANDLE hDevHandle);
+
+#endif /* __RGXPOWER_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.c
new file mode 100644 (file)
index 0000000..0c74a55
--- /dev/null
@@ -0,0 +1,227 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Register configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX Regconfig routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "rgxregconfig.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "device.h"
+#include "sync_internal.h"
+#include "pdump_km.h"
+#include "pvrsrv.h"
+PVRSRV_ERROR PVRSRVRGXSetRegConfigPIKM(PVRSRV_DEVICE_NODE      *psDeviceNode,
+                                       IMG_UINT8              ui8RegPowerIsland)
+{
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_REG_CONFIG          *psRegCfg = &psDevInfo->sRegCongfig;
+       RGXFWIF_PWR_EVT         ePowerIsland = (RGXFWIF_PWR_EVT) ui8RegPowerIsland;
+
+
+       if (ePowerIsland < psRegCfg->ePowerIslandToPush)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Register configuration must be in power island order."));
+               return PVRSRV_ERROR_REG_CONFIG_INVALID_PI;
+       }
+
+       psRegCfg->ePowerIslandToPush = ePowerIsland;
+
+       return eError;
+#else
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION"));
+       return PVRSRV_ERROR_FEATURE_DISABLED;
+#endif
+}
+
+PVRSRV_ERROR PVRSRVRGXAddRegConfigKM(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                                       IMG_UINT32              ui32RegAddr,
+                                       IMG_UINT64              ui64RegValue)
+{
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sRegCfgCmd;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_REG_CONFIG          *psRegCfg = &psDevInfo->sRegCongfig;
+
+       if (psRegCfg->bEnabled)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Cannot add record whilst register configuration active."));
+               return PVRSRV_ERROR_REG_CONFIG_ENABLED;
+       }
+       if (psRegCfg->ui32NumRegRecords == RGXFWIF_REG_CFG_MAX_SIZE)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Register configuration full."));
+               return PVRSRV_ERROR_REG_CONFIG_FULL;
+       }
+
+       sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG;
+       sRegCfgCmd.uCmdData.sRegConfigData.sRegConfig.ui64Addr = (IMG_UINT64) ui32RegAddr;
+       sRegCfgCmd.uCmdData.sRegConfigData.sRegConfig.ui64Value = ui64RegValue;
+       sRegCfgCmd.uCmdData.sRegConfigData.eRegConfigPI = psRegCfg->ePowerIslandToPush;
+       sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_ADD;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sRegCfgCmd,
+                               sizeof(sRegCfgCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXAddRegConfigKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       psRegCfg->ui32NumRegRecords++;
+
+       return eError;
+#else
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION"));
+       return PVRSRV_ERROR_FEATURE_DISABLED;
+#endif
+}
+
+PVRSRV_ERROR PVRSRVRGXClearRegConfigKM(PVRSRV_DEVICE_NODE      *psDeviceNode)
+{
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sRegCfgCmd;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_REG_CONFIG          *psRegCfg = &psDevInfo->sRegCongfig;
+
+       if (psRegCfg->bEnabled)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXSetRegConfigPIKM: Attempt to clear register configuration whilst active."));
+               return PVRSRV_ERROR_REG_CONFIG_ENABLED;
+       }
+
+       sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG;
+       sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_CLEAR;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sRegCfgCmd,
+                               sizeof(sRegCfgCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXClearRegConfigKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       psRegCfg->ui32NumRegRecords = 0;
+       psRegCfg->ePowerIslandToPush = RGXFWIF_PWR_EVT_PWR_ON; /* Default first PI */
+
+       return eError;
+#else
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXClearRegConfigKM: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION"));
+       return PVRSRV_ERROR_FEATURE_DISABLED;
+#endif
+}
+
+PVRSRV_ERROR PVRSRVRGXEnableRegConfigKM(PVRSRV_DEVICE_NODE     *psDeviceNode)
+{
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sRegCfgCmd;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_REG_CONFIG          *psRegCfg = &psDevInfo->sRegCongfig;
+
+       sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG;
+       sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_ENABLE;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sRegCfgCmd,
+                               sizeof(sRegCfgCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXEnableRegConfigKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       psRegCfg->bEnabled = IMG_TRUE;
+
+       return eError;
+#else
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXEnableRegConfigKM: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION"));
+       return PVRSRV_ERROR_FEATURE_DISABLED;
+#endif
+}
+
+PVRSRV_ERROR PVRSRVRGXDisableRegConfigKM(PVRSRV_DEVICE_NODE    *psDeviceNode)
+{
+#if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
+       PVRSRV_ERROR            eError = PVRSRV_OK;
+       RGXFWIF_KCCB_CMD        sRegCfgCmd;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_REG_CONFIG          *psRegCfg = &psDevInfo->sRegCongfig;
+
+       sRegCfgCmd.eCmdType = RGXFWIF_KCCB_CMD_REGCONFIG;
+       sRegCfgCmd.uCmdData.sRegConfigData.eCmdType = RGXFWIF_REGCFG_CMD_DISABLE;
+
+       eError = RGXScheduleCommand(psDeviceNode->pvDevice,
+                               RGXFWIF_DM_GP,
+                               &sRegCfgCmd,
+                               sizeof(sRegCfgCmd),
+                               IMG_TRUE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXDisableRegConfigKM: RGXScheduleCommand failed. Error:%u", eError));
+               return eError;
+       }
+
+       psRegCfg->bEnabled = IMG_FALSE;
+
+       return eError;
+#else
+       PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXDisableRegConfigKM: Feature disabled. Compile with SUPPORT_USER_REGISTER_CONFIGURATION"));
+       return PVRSRV_ERROR_FEATURE_DISABLED;
+#endif
+}
+
+
+/******************************************************************************
+ End of file (rgxregconfig.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxregconfig.h
new file mode 100644 (file)
index 0000000..bbe1586
--- /dev/null
@@ -0,0 +1,123 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX register configuration functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX register configuration functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXREGCONFIG_H__)
+#define __RGXREGCONFIG_H__
+
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_km.h"
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXSetRegConfigPIKM
+
+ @Description
+       Server-side implementation of RGXSetRegConfig
+
+ @Input psDeviceNode - RGX Device node
+ @Input ui8RegPowerIsland - Reg configuration
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXSetRegConfigPIKM(PVRSRV_DEVICE_NODE      *psDeviceNode,
+                                       IMG_UINT8       ui8RegPowerIsland);
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXSetRegConfigKM
+
+ @Description
+       Server-side implementation of RGXSetRegConfig
+
+ @Input psDeviceNode - RGX Device node
+ @Input ui64RegAddr - Register address
+ @Input ui64RegValue - Reg value
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+
+PVRSRV_ERROR PVRSRVRGXAddRegConfigKM(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                                       IMG_UINT32      ui64RegAddr,
+                                       IMG_UINT64      ui64RegValue);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXClearRegConfigKM
+
+ @Description
+       Server-side implementation of RGXClearRegConfig
+
+ @Input psDeviceNode - RGX Device node
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXClearRegConfigKM(PVRSRV_DEVICE_NODE      *psDeviceNode);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXEnableRegConfigKM
+
+ @Description
+       Server-side implementation of RGXEnableRegConfig
+
+ @Input psDeviceNode - RGX Device node
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXEnableRegConfigKM(PVRSRV_DEVICE_NODE     *psDeviceNode);
+
+/*!
+*******************************************************************************
+ @Function     PVRSRVRGXDisableRegConfigKM
+
+ @Description
+       Server-side implementation of RGXDisableRegConfig
+
+ @Input psDeviceNode - RGX Device node
+
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRGXDisableRegConfigKM(PVRSRV_DEVICE_NODE    *psDeviceNode);
+
+#endif /* __RGXREGCONFIG_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.c
new file mode 100644 (file)
index 0000000..d1e8130
--- /dev/null
@@ -0,0 +1,198 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX sync kick routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX sync kick routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "srvkm.h"
+#include "pdump_km.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "osfunc.h"
+#include "rgxccb.h"
+
+#include "sync_server.h"
+#include "sync_internal.h"
+
+#include "rgxsync.h"
+
+PVRSRV_ERROR RGXKickSyncKM(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                           RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
+                                                  RGXFWIF_DM                eDM,
+                                                  IMG_CHAR                  *pszCommandName,
+                           IMG_UINT32                ui32ClientFenceCount,
+                           PRGXFWIF_UFO_ADDR         *pauiClientFenceUFOAddress,
+                           IMG_UINT32                *paui32ClientFenceValue,
+                           IMG_UINT32                ui32ClientUpdateCount,
+                           PRGXFWIF_UFO_ADDR         *pauiClientUpdateUFOAddress,
+                           IMG_UINT32                *paui32ClientUpdateValue,
+                           IMG_UINT32                ui32ServerSyncPrims,
+                           IMG_UINT32                *paui32ServerSyncFlags,
+                           SERVER_SYNC_PRIMITIVE     **pasServerSyncs,
+                           IMG_BOOL                  bPDumpContinuous)
+{
+       RGXFWIF_KCCB_CMD                sCmpKCCBCmd;
+       RGX_CCB_CMD_HELPER_DATA asCmdHelperData[1];
+       IMG_BOOL                                bKickRequired;
+       PVRSRV_ERROR                    eError;
+       PVRSRV_ERROR                    eError2;
+       IMG_UINT32                              i;
+
+       /* Sanity check the server fences */
+       for (i=0;i<ui32ServerSyncPrims;i++)
+       {
+               if (!(paui32ServerSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Server fence (on %s) must fence", __FUNCTION__, pszCommandName));
+                       return PVRSRV_ERROR_INVALID_SYNC_PRIM_OP;
+               }
+       }
+
+       eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(psServerCommonContext),
+                                                                         ui32ClientFenceCount,
+                                                                         pauiClientFenceUFOAddress,
+                                                                         paui32ClientFenceValue,
+                                                                         ui32ClientUpdateCount,
+                                                                         pauiClientUpdateUFOAddress,
+                                                                         paui32ClientUpdateValue,
+                                                                         ui32ServerSyncPrims,
+                                                                         paui32ServerSyncFlags,
+                                                                         pasServerSyncs,
+                                                                         0,         /* ui32CmdSize */
+                                                                         IMG_NULL,  /* pui8DMCmd */
+                                                                         IMG_NULL,  /* ppPreAddr */
+                                                                         IMG_NULL,  /* ppPostAddr */
+                                                                         IMG_NULL,  /* ppRMWUFOAddr */
+                                                                         RGXFWIF_CCB_CMD_TYPE_NULL,
+                                                                         bPDumpContinuous,
+                                                                         pszCommandName,
+                                                                         asCmdHelperData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_cmdinit;
+       }
+
+       eError = RGXCmdHelperAcquireCmdCCB(IMG_ARR_NUM_ELEMS(asCmdHelperData),
+                                          asCmdHelperData, &bKickRequired);
+       if ((eError != PVRSRV_OK) && (!bKickRequired))
+       {
+               /*
+                       Only bail if no new data was submitted into the client CCB, we might
+                       have already submitted a padding packet which we should flush through
+                       the FW.
+               */
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create client CCB command", __FUNCTION__));
+               goto fail_cmdaquire;
+       }
+
+
+       /*
+               We should reserved space in the kernel CCB here and fill in the command
+               directly.
+               This is so if there isn't space in the kernel CCB we can return with
+               retry back to services client before we take any operations
+       */
+
+       /*
+               We might only be kicking for flush out a padding packet so only submit
+               the command if the create was successful
+       */
+       if (eError == PVRSRV_OK)
+       {
+               /*
+                       All the required resources are ready at this point, we can't fail so
+                       take the required server sync operations and commit all the resources
+               */
+               RGXCmdHelperReleaseCmdCCB(1, asCmdHelperData, pszCommandName, FWCommonContextGetFWAddress(psServerCommonContext).ui32Addr);
+       }
+
+       /* Construct the kernel compute CCB command. */
+       sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+       sCmpKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psServerCommonContext);
+       sCmpKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psServerCommonContext));
+       sCmpKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+
+       /*
+        * Submit the compute command to the firmware.
+        */
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError2 = RGXScheduleCommand(psDeviceNode->pvDevice,
+                                                                       eDM,
+                                                                       &sCmpKCCBCmd,
+                                                                       sizeof(sCmpKCCBCmd),
+                                                                       bPDumpContinuous);
+               if (eError2 != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+       
+       if (eError2 != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s failed to schedule kernel CCB command. (0x%x)", __FUNCTION__, eError));
+       }
+       /*
+        * Now check eError (which may have returned an error from our earlier call
+        * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first
+        * so we check it now...
+        */
+       if (eError != PVRSRV_OK )
+       {
+               goto fail_cmdaquire;
+       }
+
+       return PVRSRV_OK;
+
+fail_cmdaquire:
+fail_cmdinit:
+
+       return eError;
+}
+
+/******************************************************************************
+ End of file (rgxsync.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxsync.h
new file mode 100644 (file)
index 0000000..fa77134
--- /dev/null
@@ -0,0 +1,80 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX sync kick functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX sync kick functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXSYNC__)
+#define __RGXSYNC_H__
+
+#include "devicemem.h"
+#include "device.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_resetframework.h"
+#include "rgxdebug.h"
+
+#include "sync_server.h"
+#include "sync_internal.h"
+#include "connection_server.h"
+
+/*!
+*******************************************************************************
+ @Function     RGXKickSyncKM
+
+ @Description Send a sync kick command to the FW
+       
+ @Return   PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR RGXKickSyncKM(PVRSRV_DEVICE_NODE        *psDeviceNode,
+                                                  RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
+                                                  RGXFWIF_DM                eDM,
+                                                  IMG_CHAR                  *pszCommandName,
+                                                  IMG_UINT32                ui32ClientFenceCount,
+                                                  PRGXFWIF_UFO_ADDR         *pauiClientFenceUFOAddress,
+                                                  IMG_UINT32                *paui32ClientFenceValue,
+                                                  IMG_UINT32                ui32ClientUpdateCount,
+                                                  PRGXFWIF_UFO_ADDR         *pauiClientUpdateUFOAddress,
+                                                  IMG_UINT32                *paui32ClientUpdateValue,
+                                                  IMG_UINT32                ui32ServerSyncPrims,
+                                                  IMG_UINT32                *paui32ServerSyncFlags,
+                                                  SERVER_SYNC_PRIMITIVE     **pasServerSyncs,
+                                                  IMG_BOOL                  bPDumpContinuous);
+
+#endif /* __RGXSYNC_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.c
new file mode 100644 (file)
index 0000000..4b78005
--- /dev/null
@@ -0,0 +1,3574 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX TA/3D routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX TA/3D routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* for the offsetof macro */
+#include <stddef.h> 
+
+#include "pdump_km.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgxta3d.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "osfunc.h"
+#include "pvrsrv.h"
+#include "rgx_memallocflags.h"
+#include "rgxccb.h"
+#include "rgxhwperf.h"
+#include "rgxtimerquery.h"
+#include "rgxsync.h"
+
+#include "rgxdefs_km.h"
+#include "rgx_fwif_km.h"
+#include "physmem.h"
+#include "sync_server.h"
+#include "sync_internal.h"
+#include "process_stats.h"
+#include "osfunc.h"
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#include "pvr_sync.h"
+#endif
+
+typedef struct _DEVMEM_REF_LOOKUP_
+{
+       IMG_UINT32 ui32ZSBufferID;
+       RGX_ZSBUFFER_DATA *psZSBuffer;
+} DEVMEM_REF_LOOKUP;
+
+typedef struct _DEVMEM_FREELIST_LOOKUP_
+{
+       IMG_UINT32 ui32FreeListID;
+       RGX_FREELIST *psFreeList;
+} DEVMEM_FREELIST_LOOKUP;
+
+typedef struct {
+       DEVMEM_MEMDESC                          *psContextStateMemDesc;
+       RGX_SERVER_COMMON_CONTEXT       *psServerCommonContext;
+       IMG_UINT32                                      ui32Priority;
+} RGX_SERVER_RC_TA_DATA;
+
+typedef struct {
+       DEVMEM_MEMDESC                          *psContextStateMemDesc;
+       RGX_SERVER_COMMON_CONTEXT       *psServerCommonContext;
+       IMG_UINT32                                      ui32Priority;
+} RGX_SERVER_RC_3D_DATA;
+
+struct _RGX_SERVER_RENDER_CONTEXT_ {
+       PVRSRV_DEVICE_NODE                      *psDeviceNode;
+       DEVMEM_MEMDESC                          *psFWRenderContextMemDesc;
+       DEVMEM_MEMDESC                          *psFWFrameworkMemDesc;
+       RGX_SERVER_RC_TA_DATA           sTAData;
+       RGX_SERVER_RC_3D_DATA           s3DData;
+       IMG_UINT32                                      ui32CleanupStatus;
+#define RC_CLEANUP_TA_COMPLETE         (1 << 0)
+#define RC_CLEANUP_3D_COMPLETE         (1 << 1)
+       PVRSRV_CLIENT_SYNC_PRIM         *psCleanupSync;
+       DLLIST_NODE                                     sListNode;
+       SYNC_ADDR_LIST                  sSyncAddrListTAFence;
+       SYNC_ADDR_LIST                  sSyncAddrListTAUpdate;
+       SYNC_ADDR_LIST                  sSyncAddrList3DFence;
+       SYNC_ADDR_LIST                  sSyncAddrList3DUpdate;
+};
+
+
+static
+#ifdef __GNUC__
+       __attribute__((noreturn))
+#endif
+void sleep_for_ever(void)
+{
+#if defined(__KLOCWORK__) // klocworks would report an infinite loop because of while(1).
+       PVR_ASSERT(0); 
+#else
+       while(1)
+       {
+               OSSleepms(~0); // sleep the maximum amount of time possible
+       }
+#endif
+}
+
+
+/*
+       Static functions used by render context code
+*/
+
+static
+PVRSRV_ERROR _DestroyTAContext(RGX_SERVER_RC_TA_DATA *psTAData,
+                                                          PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                          PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync)
+{
+       PVRSRV_ERROR eError;
+
+       /* Check if the FW has finished with this resource ... */
+       eError = RGXFWRequestCommonContextCleanUp(psDeviceNode,
+                                                                                         FWCommonContextGetFWAddress(psTAData->psServerCommonContext),
+                                                                                         psCleanupSync,
+                                                                                         RGXFWIF_DM_TA);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+       else if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
+                               __FUNCTION__,
+                               PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+
+       /* ... it has so we can free it's resources */
+#if defined(DEBUG)
+       /* Log the number of TA context stores which occurred */
+       {
+               RGXFWIF_TACTX_STATE     *psFWTAState;
+
+               eError = DevmemAcquireCpuVirtAddr(psTAData->psContextStateMemDesc,
+                                                                                 (IMG_VOID**)&psFWTAState);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"%s: Failed to map firmware render context state (%u)",
+                                       __FUNCTION__, eError));
+               }
+               else
+               {
+                       /* Release the CPU virt addr */
+                       DevmemReleaseCpuVirtAddr(psTAData->psContextStateMemDesc);
+               }
+       }
+#endif
+       FWCommonContextFree(psTAData->psServerCommonContext);
+       DevmemFwFree(psTAData->psContextStateMemDesc);
+       return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR _Destroy3DContext(RGX_SERVER_RC_3D_DATA *ps3DData,
+                                                          PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                          PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync)
+{
+       PVRSRV_ERROR eError;
+
+       /* Check if the FW has finished with this resource ... */
+       eError = RGXFWRequestCommonContextCleanUp(psDeviceNode,
+                                                                                         FWCommonContextGetFWAddress(ps3DData->psServerCommonContext),
+                                                                                         psCleanupSync,
+                                                                                         RGXFWIF_DM_3D);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+       else if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
+                                __FUNCTION__,
+                                PVRSRVGetErrorStringKM(eError)));
+               return eError;
+       }
+
+       /* ... it has so we can free it's resources */
+#if defined(DEBUG)
+       /* Log the number of 3D context stores which occurred */
+       {
+               RGXFWIF_3DCTX_STATE     *psFW3DState;
+
+               eError = DevmemAcquireCpuVirtAddr(ps3DData->psContextStateMemDesc,
+                                                                                 (IMG_VOID**)&psFW3DState);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"%s: Failed to map firmware render context state (%u)",
+                                       __FUNCTION__, eError));
+               }
+               else
+               {
+                       /* Release the CPU virt addr */
+                       DevmemReleaseCpuVirtAddr(ps3DData->psContextStateMemDesc);
+               }
+       }
+#endif
+
+       FWCommonContextFree(ps3DData->psServerCommonContext);
+       DevmemFwFree(ps3DData->psContextStateMemDesc);
+       return PVRSRV_OK;
+}
+
+static IMG_BOOL _RGXDumpPMRPageList(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       RGX_PMR_NODE *psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock);
+       PVRSRV_ERROR                    eError;
+
+       eError = PMRDumpPageList(psPMRNode->psPMR,
+                                                       RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Error (%u) printing pmr %p", eError, psPMRNode->psPMR));
+       }
+
+       return IMG_TRUE;
+}
+
+IMG_BOOL RGXDumpFreeListPageList(RGX_FREELIST *psFreeList)
+{
+       PVR_LOG(("Freelist FWAddr 0x%08x, ID = %d, CheckSum 0x%016llx",
+                               psFreeList->sFreeListFWDevVAddr.ui32Addr,
+                               psFreeList->ui32FreelistID,
+                               psFreeList->ui64FreelistChecksum));
+
+       /* Dump Init FreeList page list */
+       PVR_LOG(("  Initial Memory block"));
+       dllist_foreach_node(&psFreeList->sMemoryBlockInitHead,
+                                       _RGXDumpPMRPageList,
+                                       IMG_NULL);
+
+       /* Dump Grow FreeList page list */
+       PVR_LOG(("  Grow Memory blocks"));
+       dllist_foreach_node(&psFreeList->sMemoryBlockHead,
+                                       _RGXDumpPMRPageList,
+                                       IMG_NULL);
+
+       return IMG_TRUE;
+}
+
+static PVRSRV_ERROR _UpdateFwFreelistSize(RGX_FREELIST *psFreeList,
+                                                                               IMG_BOOL bGrow,
+                                                                               IMG_UINT32 ui32DeltaSize)
+{
+       PVRSRV_ERROR                    eError;
+       RGXFWIF_KCCB_CMD                sGPCCBCmd;
+
+       sGPCCBCmd.eCmdType = (bGrow) ? RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE : RGXFWIF_KCCB_CMD_FREELIST_SHRINK_UPDATE;
+       sGPCCBCmd.uCmdData.sFreeListGSData.psFreeListFWDevVAddr = psFreeList->sFreeListFWDevVAddr.ui32Addr;
+       sGPCCBCmd.uCmdData.sFreeListGSData.ui32DeltaSize = ui32DeltaSize;
+       sGPCCBCmd.uCmdData.sFreeListGSData.ui32NewSize = psFreeList->ui32CurrentFLPages;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "Send FW update: freelist [FWAddr=0x%08x] has 0x%08x pages",
+                                                               psFreeList->sFreeListFWDevVAddr.ui32Addr,
+                                                               psFreeList->ui32CurrentFLPages));
+
+       /* Submit command to the firmware.  */
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError = RGXScheduleCommand(psFreeList->psDevInfo,
+                                                                       RGXFWIF_DM_GP,
+                                                                       &sGPCCBCmd,
+                                                                       sizeof(sGPCCBCmd),
+                                                                       IMG_TRUE);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_UpdateFwFreelistSize: failed to update FW freelist size. (error = %u)", eError));
+               return eError;
+       }
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _FreeListCheckSum(RGX_FREELIST *psFreeList,
+                                                          IMG_UINT64 *pui64CheckSum)
+{
+#if defined(NO_HARDWARE)
+       /* No checksum needed as we have all information in the pdumps */
+       PVR_UNREFERENCED_PARAMETER(psFreeList);
+       *pui64CheckSum = 0;
+       return PVRSRV_OK;
+#else
+       PVRSRV_ERROR eError;
+       IMG_SIZE_T uiNumBytes;
+    IMG_UINT8* pui8Buffer;
+    IMG_UINT32* pui32Buffer;
+    IMG_UINT32 ui32CheckSumAdd = 0;
+    IMG_UINT32 ui32CheckSumXor = 0;
+    IMG_UINT32 ui32Entry;
+    IMG_UINT32 ui32Entry2;
+
+       /* Allocate Buffer of the size of the freelist */
+       pui8Buffer = OSAllocMem(psFreeList->ui32CurrentFLPages * sizeof(IMG_UINT32));
+    if (pui8Buffer == IMG_NULL)
+    {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto _OSAllocMem_Exit;
+    }
+
+    /* Copy freelist content into Buffer */
+    eError = PMR_ReadBytes(psFreeList->psFreeListPMR,
+                               psFreeList->uiFreeListPMROffset + (psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages) * sizeof(IMG_UINT32),
+                               pui8Buffer,
+                               psFreeList->ui32CurrentFLPages * sizeof(IMG_UINT32),
+                       &uiNumBytes);
+    if (eError != PVRSRV_OK)
+    {
+       goto _PMR_ReadBytes_Exit;
+    }
+
+    PVR_ASSERT(uiNumBytes == psFreeList->ui32CurrentFLPages * sizeof(IMG_UINT32));
+
+    /* Generate checksum */
+    pui32Buffer = (IMG_UINT32 *)pui8Buffer;
+    for(ui32Entry = 0; ui32Entry < psFreeList->ui32CurrentFLPages; ui32Entry++)
+    {
+       ui32CheckSumAdd += pui32Buffer[ui32Entry];
+       ui32CheckSumXor ^= pui32Buffer[ui32Entry];
+
+       /* Check for double entries */
+       for (ui32Entry2 = 0; ui32Entry2 < psFreeList->ui32CurrentFLPages; ui32Entry2++)
+       {
+                       if ((ui32Entry != ui32Entry2) &&
+                               (pui32Buffer[ui32Entry] == pui32Buffer[ui32Entry2]))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "Freelist consistency failure: FW addr: 0x%08X, Double entry found 0x%08x on idx: %d and %d",
+                                                                                       psFreeList->sFreeListFWDevVAddr.ui32Addr,
+                                                                                       pui32Buffer[ui32Entry2],
+                                                                                       ui32Entry,
+                                                                                       ui32Entry2));
+                               sleep_for_ever();
+//                             PVR_ASSERT(0);
+                       }
+       }
+    }
+
+    OSFreeMem(pui8Buffer);
+
+    /* Set return value */
+    *pui64CheckSum = ((IMG_UINT64)ui32CheckSumXor << 32) | ui32CheckSumAdd;
+    PVR_ASSERT(eError == PVRSRV_OK);
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+_PMR_ReadBytes_Exit:
+       OSFreeMem(pui8Buffer);
+
+_OSAllocMem_Exit:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+#endif
+}
+
+PVRSRV_ERROR RGXGrowFreeList(RGX_FREELIST *psFreeList,
+                                                       IMG_UINT32 ui32NumPages,
+                                                       PDLLIST_NODE pListHeader)
+{
+       RGX_PMR_NODE    *psPMRNode;
+       IMG_DEVMEM_SIZE_T uiSize;
+       IMG_BOOL bMappingTable = IMG_TRUE;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       IMG_DEVMEM_SIZE_T uiLength;
+       IMG_DEVMEM_SIZE_T uistartPage;
+       PVRSRV_ERROR eError;
+       IMG_UINT64 ui64CheckSum;
+       IMG_UINT32 ui32CheckSumXor;
+       IMG_UINT32 ui32CheckSumAdd;
+
+       /* Are we allowed to grow ? */
+       if ((psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages) < ui32NumPages)
+       {
+               PVR_DPF((PVR_DBG_WARNING,"Freelist [0x%p]: grow by %u pages denied. Max PB size reached (current pages %u/%u)",
+                               psFreeList,
+                               ui32NumPages,
+                               psFreeList->ui32CurrentFLPages,
+                               psFreeList->ui32MaxFLPages));
+               return PVRSRV_ERROR_PBSIZE_ALREADY_MAX;
+       }
+
+       /* Allocate kernel memory block structure */
+       psPMRNode = OSAllocMem(sizeof(*psPMRNode));
+       if (psPMRNode == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXGrowFreeList: failed to allocate host data structure"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto ErrorAllocHost;
+       }
+
+       /*
+        * Lock protects simultaneous manipulation of:
+        * - the memory block list
+        * - the freelist's ui32CurrentFLPages
+        */
+       OSLockAcquire(psFreeList->psDevInfo->hLockFreeList);
+
+
+       psPMRNode->ui32NumPages = ui32NumPages;
+       psPMRNode->psFreeList = psFreeList;
+
+       /* Allocate Memory Block */
+       PDUMPCOMMENT("Allocate PB Block (Pages %08X)", ui32NumPages);
+       uiSize = (IMG_DEVMEM_SIZE_T)ui32NumPages * RGX_BIF_PM_PHYSICAL_PAGE_SIZE;
+       eError = PhysmemNewRamBackedPMR(psFreeList->psDevInfo->psDeviceNode,
+                                                                       uiSize,
+                                                                       uiSize,
+                                                                       1,
+                                                                       1,
+                                                                       &bMappingTable,
+                                                                       RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT,
+                                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE,
+                                                                       &psPMRNode->psPMR);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                                "RGXGrowFreeList: Failed to allocate PB block of size: 0x%016llX",
+                                (IMG_UINT64)uiSize));
+               goto ErrorBlockAlloc;
+       }
+
+       /* Zeroing physical pages pointed by the PMR */
+       if (psFreeList->psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_ZERO_FREELIST)
+       {
+               eError = PMRZeroingPMR(psPMRNode->psPMR, RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXGrowFreeList: Failed to zero PMR %p of freelist %p with Error %d",
+                                                                       psPMRNode->psPMR,
+                                                                       psFreeList,
+                                                                       eError));
+                       PVR_ASSERT(0);
+               }
+       }
+
+       uiLength = psPMRNode->ui32NumPages * sizeof(IMG_UINT32);
+       uistartPage = (psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages - psPMRNode->ui32NumPages);
+       uiOffset = psFreeList->uiFreeListPMROffset + (uistartPage * sizeof(IMG_UINT32));
+
+       /* write Freelist with Memory Block physical addresses */
+       eError = PMRWritePMPageList(
+                                               /* Target PMR, offset, and length */
+                                               psFreeList->psFreeListPMR,
+                                               uiOffset,
+                                               uiLength,
+                                               /* Referenced PMR, and "page" granularity */
+                                               psPMRNode->psPMR,
+                                               RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT,
+                                               &psPMRNode->psPageList,
+                                               &ui64CheckSum);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                                "RGXGrowFreeList: Failed to write pages of Node %p",
+                                psPMRNode));
+               goto ErrorPopulateFreelist;
+       }
+
+       /* We add It must be added to the tail, otherwise the freelist population won't work */
+       dllist_add_to_head(pListHeader, &psPMRNode->sMemoryBlock);
+
+       /* Update number of available pages */
+       psFreeList->ui32CurrentFLPages += ui32NumPages;
+
+       /* Update statistics */
+       if (psFreeList->ui32NumHighPages < psFreeList->ui32CurrentFLPages)
+       {
+               psFreeList->ui32NumHighPages = psFreeList->ui32CurrentFLPages;
+       }
+
+       if (psFreeList->bCheckFreelist)
+       {
+               /* Update checksum */
+               ui32CheckSumAdd = (IMG_UINT32)(psFreeList->ui64FreelistChecksum + ui64CheckSum);
+               ui32CheckSumXor = (IMG_UINT32)((psFreeList->ui64FreelistChecksum  ^ ui64CheckSum) >> 32);
+               psFreeList->ui64FreelistChecksum = ((IMG_UINT64)ui32CheckSumXor << 32) | ui32CheckSumAdd;
+               /* Note: We can't do a freelist check here, because the freelist is probably empty (OOM) */
+       }
+
+       OSLockRelease(psFreeList->psDevInfo->hLockFreeList);
+
+       PVR_DPF((PVR_DBG_MESSAGE,"Freelist [%p]: grow by %u pages (current pages %u/%u)",
+                       psFreeList,
+                       ui32NumPages,
+                       psFreeList->ui32CurrentFLPages,
+                       psFreeList->ui32MaxFLPages));
+
+       return PVRSRV_OK;
+
+       /* Error handling */
+ErrorPopulateFreelist:
+       PMRUnrefPMR(psPMRNode->psPMR);
+
+ErrorBlockAlloc:
+       OSFreeMem(psPMRNode);
+       OSLockRelease(psFreeList->psDevInfo->hLockFreeList);
+
+ErrorAllocHost:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+
+}
+
+static PVRSRV_ERROR RGXShrinkFreeList(PDLLIST_NODE pListHeader,
+                                                                               RGX_FREELIST *psFreeList)
+{
+       DLLIST_NODE *psNode;
+       RGX_PMR_NODE *psPMRNode;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       IMG_UINT32 ui32OldValue;
+
+       /*
+        * Lock protects simultaneous manipulation of:
+        * - the memory block list
+        * - the freelist's ui32CurrentFLPages value
+        */
+       PVR_ASSERT(pListHeader);
+       PVR_ASSERT(psFreeList);
+       PVR_ASSERT(psFreeList->psDevInfo);
+       PVR_ASSERT(psFreeList->psDevInfo->hLockFreeList);
+
+       OSLockAcquire(psFreeList->psDevInfo->hLockFreeList);
+
+       /* Get node from head of list and remove it */
+       psNode = dllist_get_next_node(pListHeader);
+       if (psNode)
+       {
+               dllist_remove_node(psNode);
+
+               psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock);
+               PVR_ASSERT(psPMRNode);
+               PVR_ASSERT(psPMRNode->psPMR);
+               PVR_ASSERT(psPMRNode->psFreeList);
+
+               /* remove block from freelist list */
+
+               /* Unwrite Freelist with Memory Block physical addresses */
+               eError = PMRUnwritePMPageList(psPMRNode->psPageList);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "RGXRemoveBlockFromFreeListKM: Failed to unwrite pages of Node %p",
+                                        psPMRNode));
+                       PVR_ASSERT(IMG_FALSE);
+               }
+
+               /* Free PMR (We should be the only one that holds a ref on the PMR) */
+               eError = PMRUnrefPMR(psPMRNode->psPMR);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "RGXRemoveBlockFromFreeListKM: Failed to free PB block %p (error %u)",
+                                        psPMRNode->psPMR,
+                                        eError));
+                       PVR_ASSERT(IMG_FALSE);
+               }
+
+               /* update available pages in freelist */
+               ui32OldValue = psFreeList->ui32CurrentFLPages;
+               psFreeList->ui32CurrentFLPages -= psPMRNode->ui32NumPages;
+
+               /* check underflow */
+               PVR_ASSERT(ui32OldValue > psFreeList->ui32CurrentFLPages);
+
+               PVR_DPF((PVR_DBG_MESSAGE, "Freelist [%p]: shrink by %u pages (current pages %u/%u)",
+                                                               psFreeList,
+                                                               psPMRNode->ui32NumPages,
+                                                               psFreeList->ui32CurrentFLPages,
+                                                               psFreeList->ui32MaxFLPages));
+
+               OSFreeMem(psPMRNode);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_WARNING,"Freelist [0x%p]: shrink denied. PB already at initial PB size (%u pages)",
+                                                               psFreeList,
+                                                               psFreeList->ui32InitFLPages));
+               eError = PVRSRV_ERROR_PBSIZE_ALREADY_MIN;
+       }
+
+       OSLockRelease(psFreeList->psDevInfo->hLockFreeList);
+
+       return eError;
+}
+
+static IMG_BOOL _FindFreeList(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       DEVMEM_FREELIST_LOOKUP *psRefLookUp = (DEVMEM_FREELIST_LOOKUP *)pvCallbackData;
+       RGX_FREELIST *psFreeList;
+
+       psFreeList = IMG_CONTAINER_OF(psNode, RGX_FREELIST, sNode);
+
+       if (psFreeList->ui32FreelistID == psRefLookUp->ui32FreeListID)
+       {
+               psRefLookUp->psFreeList = psFreeList;
+               return IMG_FALSE;
+       }
+       else
+       {
+               return IMG_TRUE;
+       }
+}
+
+IMG_VOID RGXProcessRequestGrow(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               IMG_UINT32 ui32FreelistID)
+{
+       DEVMEM_FREELIST_LOOKUP sLookUp;
+       RGXFWIF_KCCB_CMD s3DCCBCmd;
+       IMG_UINT32 ui32GrowValue;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psDevInfo);
+
+       /* find the freelist with the corresponding ID */
+       sLookUp.ui32FreeListID = ui32FreelistID;
+       sLookUp.psFreeList = IMG_NULL;
+
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       dllist_foreach_node(&psDevInfo->sFreeListHead, _FindFreeList, (IMG_PVOID)&sLookUp);
+       OSLockRelease(psDevInfo->hLockFreeList);
+
+       if (sLookUp.psFreeList)
+       {
+               RGX_FREELIST *psFreeList = sLookUp.psFreeList;
+
+               /* Try to grow the freelist */
+               eError = RGXGrowFreeList(psFreeList,
+                                                               psFreeList->ui32GrowFLPages,
+                                                               &psFreeList->sMemoryBlockHead);
+               if (eError == PVRSRV_OK)
+               {
+                       /* Grow successful, return size of grow size */
+                       ui32GrowValue = psFreeList->ui32GrowFLPages;
+
+                       psFreeList->ui32NumGrowReqByFW++;
+
+ #if defined(PVRSRV_ENABLE_PROCESS_STATS)
+                       /* Update Stats */
+                       PVRSRVStatsUpdateFreelistStats(0,
+                                      1, /* Add 1 to the appropriate counter (Requests by FW) */
+                                      psFreeList->ui32InitFLPages,
+                                      psFreeList->ui32NumHighPages,
+                                      psFreeList->ownerPid);
+
+ #endif
+
+               }
+               else
+               {
+                       /* Grow failed */
+                       ui32GrowValue = 0;
+                       PVR_DPF((PVR_DBG_ERROR,"Grow for FreeList %p failed (error %u)",
+                                                                       psFreeList,
+                                                                       eError));
+               }
+
+               /* send feedback */
+               s3DCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE;
+               s3DCCBCmd.uCmdData.sFreeListGSData.psFreeListFWDevVAddr = sLookUp.psFreeList->sFreeListFWDevVAddr.ui32Addr;
+               s3DCCBCmd.uCmdData.sFreeListGSData.ui32DeltaSize = ui32GrowValue;
+               s3DCCBCmd.uCmdData.sFreeListGSData.ui32NewSize = psFreeList->ui32CurrentFLPages;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError = RGXScheduleCommand(psDevInfo,
+                                                                                               RGXFWIF_DM_3D,
+                                                                                               &s3DCCBCmd,
+                                                                                               sizeof(s3DCCBCmd),
+                                                                                               IMG_FALSE);
+                       if (eError != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+               /* Kernel CCB should never fill up, as the FW is processing them right away  */
+
+               PVR_ASSERT(eError == PVRSRV_OK);
+       }
+       else
+       {
+               /* Should never happen */
+               PVR_DPF((PVR_DBG_ERROR,"FreeList Lookup for FreeList ID 0x%08x failed (Populate)", sLookUp.ui32FreeListID));
+               PVR_ASSERT(IMG_FALSE);
+       }
+}
+
+static IMG_BOOL _RGXCheckFreeListReconstruction(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+
+       PVRSRV_RGXDEV_INFO              *psDevInfo;
+       RGX_FREELIST                    *psFreeList;
+       RGX_PMR_NODE                    *psPMRNode;
+       PVRSRV_ERROR                    eError;
+       IMG_DEVMEM_OFFSET_T             uiOffset;
+       IMG_DEVMEM_SIZE_T               uiLength;
+       IMG_UINT32                              ui32StartPage;
+       IMG_UINT64                              ui64CheckSum;
+
+       psPMRNode = IMG_CONTAINER_OF(psNode, RGX_PMR_NODE, sMemoryBlock);
+       psFreeList = psPMRNode->psFreeList;
+       PVR_ASSERT(psFreeList);
+       psDevInfo = psFreeList->psDevInfo;
+       PVR_ASSERT(psDevInfo);
+
+       uiLength = psPMRNode->ui32NumPages * sizeof(IMG_UINT32);
+       ui32StartPage = (psFreeList->ui32MaxFLPages - psFreeList->ui32CurrentFLPages - psPMRNode->ui32NumPages);
+       uiOffset = psFreeList->uiFreeListPMROffset + (ui32StartPage * sizeof(IMG_UINT32));
+
+       PMRUnwritePMPageList(psPMRNode->psPageList);
+       psPMRNode->psPageList = IMG_NULL;
+       eError = PMRWritePMPageList(
+                                               /* Target PMR, offset, and length */
+                                               psFreeList->psFreeListPMR,
+                                               uiOffset,
+                                               uiLength,
+                                               /* Referenced PMR, and "page" granularity */
+                                               psPMRNode->psPMR,
+                                               RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT,
+                                               &psPMRNode->psPageList,
+                                               &ui64CheckSum);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Error (%u) writing FL 0x%08x", eError, (IMG_UINT32)psFreeList->ui32FreelistID));
+       }
+
+       /* Zeroing physical pages pointed by the reconstructed freelist */
+       if (psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_ZERO_FREELIST)
+       {
+               eError = PMRZeroingPMR(psPMRNode->psPMR, RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"_RGXCheckFreeListReconstruction: Failed to zero PMR %p of freelist %p with Error %d",
+                                                                       psPMRNode->psPMR,
+                                                                       psFreeList,
+                                                                       eError));
+                       PVR_ASSERT(0);
+               }
+       }
+
+       psFreeList->ui32CurrentFLPages += psPMRNode->ui32NumPages;
+
+       return IMG_TRUE;
+}
+
+IMG_VOID RGXProcessRequestFreelistsReconstruction(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               RGXFWIF_DM eDM,
+                                                               IMG_UINT32 ui32FreelistsCount,
+                                                               IMG_UINT32 *paui32Freelists)
+{
+       PVRSRV_ERROR eError;
+       DEVMEM_FREELIST_LOOKUP sLookUp;
+       IMG_UINT32 ui32Loop, ui32Loop2;
+       RGXFWIF_KCCB_CMD s3DCCBCmd;
+       IMG_UINT64 ui64CheckSum;
+       
+       PVR_ASSERT(psDevInfo);
+
+       //PVR_DPF((PVR_DBG_ERROR,"FreeList RECONSTRUCTION: Reconstructing %u freelist(s)", ui32FreelistsCount));
+       
+       for (ui32Loop = 0; ui32Loop < ui32FreelistsCount; ui32Loop++)
+       {
+               /* check if there is more than one occurrence of FL on the list */      
+               for (ui32Loop2 = ui32Loop + 1; ui32Loop2 < ui32FreelistsCount; ui32Loop2++)
+               {
+                       if (paui32Freelists[ui32Loop] == paui32Freelists[ui32Loop2])
+                       {
+                               /* There is a duplicate on a list, skip current Freelist */
+                               break;
+                       }
+               }
+
+               if (ui32Loop2 < ui32FreelistsCount)
+               {
+                       /* There is a duplicate on the list, skip current Freelist */
+                       continue;
+               }
+
+               /* find the freelist with the corresponding ID */
+               sLookUp.ui32FreeListID = paui32Freelists[ui32Loop];
+               sLookUp.psFreeList = IMG_NULL;
+       
+               //PVR_DPF((PVR_DBG_ERROR,"FreeList RECONSTRUCTION: Looking for freelist %08X", (IMG_UINT32)sLookUp.ui32FreeListID));
+               OSLockAcquire(psDevInfo->hLockFreeList);
+               //PVR_DPF((PVR_DBG_ERROR,"FreeList RECONSTRUCTION: Freelist head %08X", (IMG_UINT32)&psDevInfo->sFreeListHead));
+               dllist_foreach_node(&psDevInfo->sFreeListHead, _FindFreeList, (IMG_PVOID)&sLookUp);
+               OSLockRelease(psDevInfo->hLockFreeList);
+
+               if (sLookUp.psFreeList)
+               {
+                       RGX_FREELIST *psFreeList = sLookUp.psFreeList;
+
+                       //PVR_DPF((PVR_DBG_ERROR,"FreeList RECONSTRUCTION: Reconstructing freelist %08X", (IMG_UINT32)psFreeList));
+               
+                       /* Do the FreeList Reconstruction */
+                               
+                       psFreeList->ui32CurrentFLPages = 0;
+
+                       /* Reconstructing Init FreeList pages */
+                       dllist_foreach_node(&psFreeList->sMemoryBlockInitHead,
+                                                       _RGXCheckFreeListReconstruction, 
+                                                       IMG_NULL);
+
+                       /* Reconstructing Grow FreeList pages */
+                       dllist_foreach_node(&psFreeList->sMemoryBlockHead,
+                                                       _RGXCheckFreeListReconstruction, 
+                                                       IMG_NULL);
+
+                       if (psFreeList->bCheckFreelist)
+                       {
+                               /* Get Freelist checksum (as the list is fully populated) */
+                               eError = _FreeListCheckSum(psFreeList,
+                                                                                       &ui64CheckSum);
+                               if (eError != PVRSRV_OK)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR,
+                                                        "RGXProcessRequestFreelistsReconstruction: Failed to get freelist checksum Node %p",
+                                                        psFreeList));
+                                       sleep_for_ever();
+//                                     PVR_ASSERT(0);
+                               }
+
+                               /* Verify checksum with previous value */
+                               if (psFreeList->ui64FreelistChecksum != ui64CheckSum)
+                               {
+                                       PVR_DPF((PVR_DBG_ERROR, "RGXProcessRequestFreelistsReconstruction: Freelist [%p] checksum failed: before reconstruction = 0x%016llx, after reconstruction = 0x%016llx",
+                                                                                       psFreeList,
+                                                                                       psFreeList->ui64FreelistChecksum,
+                                                                                       ui64CheckSum));
+                                       sleep_for_ever();
+                                       //PVR_ASSERT(0);
+                               }
+                       }
+
+                       eError = PVRSRV_OK;
+
+                       if (eError == PVRSRV_OK)
+                       {
+                               /* Freelist reconstruction successful */
+                               s3DCCBCmd.uCmdData.sFreeListsReconstructionData.aui32FreelistIDs[ui32Loop] = 
+                                                                                                       paui32Freelists[ui32Loop];
+                       }
+                       else
+                       {
+                               /* Freelist reconstruction failed */
+                               s3DCCBCmd.uCmdData.sFreeListsReconstructionData.aui32FreelistIDs[ui32Loop] = 
+                                                                                                       paui32Freelists[ui32Loop] | RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG;
+                               
+                               PVR_DPF((PVR_DBG_ERROR,"Reconstructing of FreeList %p failed (error %u)",
+                                                                               psFreeList,
+                                                                               eError));
+                       }
+               }
+               else
+               {
+                       /* Should never happen */
+                       PVR_DPF((PVR_DBG_ERROR,"FreeList Lookup for FreeList ID 0x%08x failed (Freelist reconstruction)", sLookUp.ui32FreeListID));
+                       PVR_ASSERT(IMG_FALSE);
+               }
+       }
+
+       /* send feedback */
+       s3DCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE;
+       s3DCCBCmd.uCmdData.sFreeListsReconstructionData.ui32FreelistsCount = ui32FreelistsCount;
+
+       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+       {
+               eError = RGXScheduleCommand(psDevInfo,
+                                                                                       eDM,
+                                                                                       &s3DCCBCmd,
+                                                                                       sizeof(s3DCCBCmd),
+                                                                                       IMG_FALSE);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       break;
+               }
+               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+       } END_LOOP_UNTIL_TIMEOUT();
+
+       /* Kernel CCB should never fill up, as the FW is processing them right away  */
+       PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+/* Create HWRTDataSet */
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateHWRTData(PVRSRV_DEVICE_NODE      *psDeviceNode,
+                                                          IMG_UINT32                   psRenderTarget, /* FIXME this should not be IMG_UINT32 */
+                                                          IMG_DEV_VIRTADDR             psPMMListDevVAddr,
+                                                          IMG_DEV_VIRTADDR             psVFPPageTableAddr,
+                                                          RGX_FREELIST                 *apsFreeLists[RGXFW_MAX_FREELISTS],
+                                                          RGX_RTDATA_CLEANUP_DATA      **ppsCleanupData,
+                                                          DEVMEM_MEMDESC               **ppsRTACtlMemDesc,
+                                                          IMG_UINT32           ui32PPPScreen,
+                                                          IMG_UINT32           ui32PPPGridOffset,
+                                                          IMG_UINT64           ui64PPPMultiSampleCtl,
+                                                          IMG_UINT32           ui32TPCStride,
+                                                          IMG_DEV_VIRTADDR             sTailPtrsDevVAddr,
+                                                          IMG_UINT32           ui32TPCSize,
+                                                          IMG_UINT32           ui32TEScreen,
+                                                          IMG_UINT32           ui32TEAA,
+                                                          IMG_UINT32           ui32TEMTILE1,
+                                                          IMG_UINT32           ui32TEMTILE2,
+                                                          IMG_UINT32           ui32MTileStride,
+                                                          IMG_UINT32                 ui32ISPMergeLowerX,
+                                                          IMG_UINT32                 ui32ISPMergeLowerY,
+                                                          IMG_UINT32                 ui32ISPMergeUpperX,
+                                                          IMG_UINT32                 ui32ISPMergeUpperY,
+                                                          IMG_UINT32                 ui32ISPMergeScaleX,
+                                                          IMG_UINT32                 ui32ISPMergeScaleY,
+                                                          IMG_UINT16                   ui16MaxRTs,
+                                                          DEVMEM_MEMDESC               **ppsMemDesc,
+                                                          IMG_UINT32                   *puiHWRTData)
+{
+       PVRSRV_ERROR eError;
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+       RGXFWIF_DEV_VIRTADDR pFirmwareAddr;
+       RGXFWIF_HWRTDATA *psHWRTData;
+       RGXFWIF_RTA_CTL *psRTACtl;
+       IMG_UINT32 ui32Loop;
+       RGX_RTDATA_CLEANUP_DATA *psTmpCleanup;
+
+       /* Prepare cleanup struct */
+       psTmpCleanup = OSAllocMem(sizeof(*psTmpCleanup));
+       if (psTmpCleanup == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto AllocError;
+       }
+
+       OSMemSet(psTmpCleanup, 0, sizeof(*psTmpCleanup));
+       *ppsCleanupData = psTmpCleanup;
+
+       /* Allocate cleanup sync */
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psTmpCleanup->psCleanupSync,
+                                                  "HWRTData cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateHWRTData: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto SyncAlloc;
+       }
+
+       psDevInfo = psDeviceNode->pvDevice;
+
+       /*
+        * This FW RT-Data is only mapped into kernel for initialisation.
+        * Otherwise this allocation is only used by the FW.
+        * Therefore the GPU cache doesn't need coherency,
+        * and write-combine is suffice on the CPU side (WC buffer will be flushed at the first TA-kick)
+        */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_HWRTDATA),
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                       PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
+                                                       "FirmwareHWRTData",
+                                                       ppsMemDesc);
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXCreateHWRTData: DevmemAllocate for RGX_FWIF_HWRTDATA failed"));
+               goto FWRTDataAllocateError;
+       }
+
+       psTmpCleanup->psDeviceNode = psDeviceNode;
+       psTmpCleanup->psFWHWRTDataMemDesc = *ppsMemDesc;
+
+       RGXSetFirmwareAddress(&pFirmwareAddr, *ppsMemDesc, 0, RFW_FWADDR_FLAG_NONE);
+
+       *puiHWRTData = pFirmwareAddr.ui32Addr;
+
+       eError = DevmemAcquireCpuVirtAddr(*ppsMemDesc, (IMG_VOID **)&psHWRTData);
+       PVR_LOGG_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", FWRTDataCpuMapError);
+
+       /* FIXME: MList is something that that PM writes physical addresses to,
+        * so ideally its best allocated in kernel */
+       psHWRTData->psPMMListDevVAddr = psPMMListDevVAddr;
+       psHWRTData->psParentRenderTarget.ui32Addr = psRenderTarget;
+       #if defined(SUPPORT_VFP)
+       psHWRTData->sVFPPageTableAddr = psVFPPageTableAddr;
+       #endif
+
+       psHWRTData->ui32PPPScreen         = ui32PPPScreen;
+       psHWRTData->ui32PPPGridOffset     = ui32PPPGridOffset;
+       psHWRTData->ui64PPPMultiSampleCtl = ui64PPPMultiSampleCtl;
+       psHWRTData->ui32TPCStride         = ui32TPCStride;
+       psHWRTData->sTailPtrsDevVAddr     = sTailPtrsDevVAddr;
+       psHWRTData->ui32TPCSize           = ui32TPCSize;
+       psHWRTData->ui32TEScreen          = ui32TEScreen;
+       psHWRTData->ui32TEAA              = ui32TEAA;
+       psHWRTData->ui32TEMTILE1          = ui32TEMTILE1;
+       psHWRTData->ui32TEMTILE2          = ui32TEMTILE2;
+       psHWRTData->ui32MTileStride       = ui32MTileStride;
+       psHWRTData->ui32ISPMergeLowerX = ui32ISPMergeLowerX;
+       psHWRTData->ui32ISPMergeLowerY = ui32ISPMergeLowerY;
+       psHWRTData->ui32ISPMergeUpperX = ui32ISPMergeUpperX;
+       psHWRTData->ui32ISPMergeUpperY = ui32ISPMergeUpperY;
+       psHWRTData->ui32ISPMergeScaleX = ui32ISPMergeScaleX;
+       psHWRTData->ui32ISPMergeScaleY = ui32ISPMergeScaleY;
+
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++)
+       {
+               psTmpCleanup->apsFreeLists[ui32Loop] = apsFreeLists[ui32Loop];
+               psTmpCleanup->apsFreeLists[ui32Loop]->ui32RefCount++;
+               psHWRTData->apsFreeLists[ui32Loop] = *((PRGXFWIF_FREELIST *)&(psTmpCleanup->apsFreeLists[ui32Loop]->sFreeListFWDevVAddr.ui32Addr)); /* FIXME: Fix pointer type casting */
+               /* invalid initial snapshot value, the snapshot is always taken during first kick
+                * and hence the value get replaced during the first kick anyway. So its safe to set it 0.
+               */
+               psHWRTData->aui32FreeListHWRSnapshot[ui32Loop] = 0;
+       }
+       OSLockRelease(psDevInfo->hLockFreeList);
+       
+       PDUMPCOMMENT("Allocate RGXFW RTA control");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                                               sizeof(RGXFWIF_RTA_CTL),
+                                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                                               PVRSRV_MEMALLOCFLAG_UNCACHED |
+                                                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC,
+                                                                               "FirmwareRTAControl",
+                                                                               ppsRTACtlMemDesc);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateHWRTData: Failed to allocate RGX RTA control (%u)",
+                               eError));
+               goto FWRTAAllocateError;
+       }
+       psTmpCleanup->psRTACtlMemDesc = *ppsRTACtlMemDesc;
+       RGXSetFirmwareAddress(&psHWRTData->psRTACtl,
+                                                                  *ppsRTACtlMemDesc,
+                                                                  0, RFW_FWADDR_FLAG_NONE);
+       
+       eError = DevmemAcquireCpuVirtAddr(*ppsRTACtlMemDesc, (IMG_VOID **)&psRTACtl);
+       PVR_LOGG_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", FWRTACpuMapError);
+       psRTACtl->ui32RenderTargetIndex = 0;
+       psRTACtl->ui32ActiveRenderTargets = 0;
+
+       if (ui16MaxRTs > 1)
+       {
+               /* Allocate memory for the checks */
+               PDUMPCOMMENT("Allocate memory for shadow render target cache");
+               eError = DevmemFwAllocate(psDevInfo,
+                                                               ui16MaxRTs * sizeof(IMG_UINT32),
+                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                               PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                               PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                               PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                               PVRSRV_MEMALLOCFLAG_UNCACHED|
+                                                               PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC,
+                                                               "FirmwareShadowRTCache",
+                                                               &psTmpCleanup->psRTArrayMemDesc);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXCreateHWRTData: Failed to allocate %d bytes for render target array (%u)",
+                               ui16MaxRTs, eError));
+                       goto FWAllocateRTArryError;
+               }
+
+               RGXSetFirmwareAddress(&psRTACtl->paui32ValidRenderTargets,
+                                                                               psTmpCleanup->psRTArrayMemDesc,
+                                                                               0, RFW_FWADDR_FLAG_NONE);
+
+               /* Allocate memory for the checks */
+               PDUMPCOMMENT("Allocate memory for tracking renders accumulation");
+               eError = DevmemFwAllocate(psDevInfo,
+                                                        ui16MaxRTs * sizeof(IMG_UINT32),
+                                                        PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                        PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) |
+                                                        PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                        PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                        PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                        PVRSRV_MEMALLOCFLAG_UNCACHED|
+                                                        PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC,
+                                                        "FirmwareRendersAccumulation",
+                                                        &psTmpCleanup->psRendersAccArrayMemDesc);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXCreateHWRTData: Failed to allocate %d bytes for render target array (%u) (renders accumulation)",
+                                                 ui16MaxRTs, eError));
+                       goto FWAllocateRTAccArryError;
+               }
+
+               RGXSetFirmwareAddress(&psRTACtl->paui32NumRenders,
+                                                psTmpCleanup->psRendersAccArrayMemDesc,
+                                                0, RFW_FWADDR_FLAG_NONE);
+               psRTACtl->ui16MaxRTs = ui16MaxRTs;
+       }
+       else
+       {
+               psRTACtl->paui32ValidRenderTargets.ui32Addr = 0;
+               psRTACtl->paui32NumRenders.ui32Addr = 0;
+               psRTACtl->ui16MaxRTs = 1;
+       }
+               
+       PDUMPCOMMENT("Dump HWRTData 0x%08X", *puiHWRTData);
+       DevmemPDumpLoadMem(*ppsMemDesc, 0, sizeof(*psHWRTData), PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("Dump RTACtl");
+       DevmemPDumpLoadMem(*ppsRTACtlMemDesc, 0, sizeof(*psRTACtl), PDUMP_FLAGS_CONTINUOUS);
+
+       DevmemReleaseCpuVirtAddr(*ppsMemDesc);
+       DevmemReleaseCpuVirtAddr(*ppsRTACtlMemDesc);
+       return PVRSRV_OK;
+
+       DevmemFwFree(psTmpCleanup->psRendersAccArrayMemDesc);
+FWAllocateRTAccArryError:
+       DevmemFwFree(psTmpCleanup->psRTArrayMemDesc);
+FWAllocateRTArryError:
+       DevmemReleaseCpuVirtAddr(*ppsRTACtlMemDesc);
+FWRTACpuMapError:
+       RGXUnsetFirmwareAddress(*ppsRTACtlMemDesc);
+       DevmemFwFree(*ppsRTACtlMemDesc);
+FWRTAAllocateError:
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++)
+       {
+               PVR_ASSERT(psTmpCleanup->apsFreeLists[ui32Loop]->ui32RefCount > 0);
+               psTmpCleanup->apsFreeLists[ui32Loop]->ui32RefCount--;
+       }
+       OSLockRelease(psDevInfo->hLockFreeList);
+       DevmemReleaseCpuVirtAddr(*ppsMemDesc);
+FWRTDataCpuMapError:
+       RGXUnsetFirmwareAddress(*ppsMemDesc);
+       DevmemFwFree(*ppsMemDesc);
+FWRTDataAllocateError:
+       SyncPrimFree(psTmpCleanup->psCleanupSync);
+SyncAlloc:
+       *ppsCleanupData = NULL;
+       OSFreeMem(psTmpCleanup);
+
+AllocError:
+       return eError;
+}
+
+/* Destroy HWRTDataSet */
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyHWRTData(RGX_RTDATA_CLEANUP_DATA *psCleanupData)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+       PVRSRV_ERROR eError;
+       PRGXFWIF_HWRTDATA psHWRTData;
+       IMG_UINT32 ui32Loop;
+
+       PVR_ASSERT(psCleanupData);
+
+       RGXSetFirmwareAddress(&psHWRTData, psCleanupData->psFWHWRTDataMemDesc, 0, RFW_FWADDR_NOREF_FLAG);
+
+       /* Cleanup HWRTData in TA */
+       eError = RGXFWRequestHWRTDataCleanUp(psCleanupData->psDeviceNode,
+                                                                                psHWRTData,
+                                                                                psCleanupData->psCleanupSync,
+                                                                                RGXFWIF_DM_TA);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+
+       psDevInfo = psCleanupData->psDeviceNode->pvDevice;
+
+       /* Cleanup HWRTData in 3D */
+       eError = RGXFWRequestHWRTDataCleanUp(psCleanupData->psDeviceNode,
+                                                                                psHWRTData,
+                                                                                psCleanupData->psCleanupSync,
+                                                                                RGXFWIF_DM_3D);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+
+       /* If we got here then TA and 3D operations on this RTData have finished */
+       if(psCleanupData->psRTACtlMemDesc)
+       {
+               RGXUnsetFirmwareAddress(psCleanupData->psRTACtlMemDesc);
+               DevmemFwFree(psCleanupData->psRTACtlMemDesc);
+       }
+       
+       RGXUnsetFirmwareAddress(psCleanupData->psFWHWRTDataMemDesc);
+       DevmemFwFree(psCleanupData->psFWHWRTDataMemDesc);
+       
+       if(psCleanupData->psRTArrayMemDesc)
+       {
+               RGXUnsetFirmwareAddress(psCleanupData->psRTArrayMemDesc);
+               DevmemFwFree(psCleanupData->psRTArrayMemDesc);
+       }
+       if(psCleanupData->psRendersAccArrayMemDesc)
+       {
+               RGXUnsetFirmwareAddress(psCleanupData->psRendersAccArrayMemDesc);
+               DevmemFwFree(psCleanupData->psRendersAccArrayMemDesc);
+       }
+
+
+       SyncPrimFree(psCleanupData->psCleanupSync);
+
+       /* decrease freelist refcount */
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       for (ui32Loop = 0; ui32Loop < RGXFW_MAX_FREELISTS; ui32Loop++)
+       {
+               PVR_ASSERT(psCleanupData->apsFreeLists[ui32Loop]->ui32RefCount > 0);
+               psCleanupData->apsFreeLists[ui32Loop]->ui32RefCount--;
+       }
+       OSLockRelease(psDevInfo->hLockFreeList);
+
+       OSFreeMem(psCleanupData);
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateFreeList(PVRSRV_DEVICE_NODE      *psDeviceNode, 
+                                                          IMG_UINT32                   ui32MaxFLPages,
+                                                          IMG_UINT32                   ui32InitFLPages,
+                                                          IMG_UINT32                   ui32GrowFLPages,
+                                                          IMG_BOOL                             bCheckFreelist,
+                                                          IMG_DEV_VIRTADDR             sFreeListDevVAddr,
+                                                          PMR                                  *psFreeListPMR,
+                                                          IMG_DEVMEM_OFFSET_T  uiFreeListPMROffset,
+                                                          RGX_FREELIST                 **ppsFreeList)
+{
+       PVRSRV_ERROR                            eError;
+       RGXFWIF_FREELIST                        *psFWFreeList;
+       DEVMEM_MEMDESC                          *psFWFreelistMemDesc;
+       RGX_FREELIST                            *psFreeList;
+       PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+
+       /* Allocate kernel freelist struct */
+       psFreeList = OSAllocMem(sizeof(*psFreeList));
+       if (psFreeList == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXCreateFreeList: failed to allocate host data structure"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto ErrorAllocHost;
+       }
+       OSMemSet(psFreeList, 0, sizeof(*psFreeList));
+
+       /* Allocate cleanup sync */
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psFreeList->psCleanupSync,
+                                                  "ta3d free list cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateFreeList: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto SyncAlloc;
+       }
+
+       /*
+        * This FW FreeList context is only mapped into kernel for initialisation.
+        * Otherwise this allocation is only used by the FW.
+        * Therefore the GPU cache doesn't need coherency,
+        * and write-combine is suffice on the CPU side (WC buffer will be flushed at the first TA-kick)
+        */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(*psFWFreeList),
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
+                                                       "FirmwareFreeList",
+                                                       &psFWFreelistMemDesc);
+       if (eError != PVRSRV_OK) 
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXCreateFreeList: DevmemAllocate for RGXFWIF_FREELIST failed"));
+               goto FWFreeListAlloc;
+       }
+
+       /* Initialise host data structures */
+       psFreeList->psDevInfo = psDevInfo;
+       psFreeList->psFreeListPMR = psFreeListPMR;
+       psFreeList->uiFreeListPMROffset = uiFreeListPMROffset;
+       psFreeList->psFWFreelistMemDesc = psFWFreelistMemDesc;
+       RGXSetFirmwareAddress(&psFreeList->sFreeListFWDevVAddr, psFWFreelistMemDesc, 0, RFW_FWADDR_FLAG_NONE);
+       psFreeList->ui32FreelistID = psDevInfo->ui32FreelistCurrID++;
+       psFreeList->ui32MaxFLPages = ui32MaxFLPages;
+       psFreeList->ui32InitFLPages = ui32InitFLPages;
+       psFreeList->ui32GrowFLPages = ui32GrowFLPages;
+       psFreeList->ui32CurrentFLPages = 0;
+       psFreeList->ui64FreelistChecksum = 0;
+       psFreeList->ui32RefCount = 0;
+       psFreeList->bCheckFreelist = bCheckFreelist;
+       dllist_init(&psFreeList->sMemoryBlockHead);
+       dllist_init(&psFreeList->sMemoryBlockInitHead);
+
+
+       /* Add to list of freelists */
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       dllist_add_to_tail(&psDevInfo->sFreeListHead, &psFreeList->sNode);
+       OSLockRelease(psDevInfo->hLockFreeList);
+
+
+       /* Initialise FW data structure */
+       eError = DevmemAcquireCpuVirtAddr(psFreeList->psFWFreelistMemDesc, (IMG_VOID **)&psFWFreeList);
+       PVR_LOGG_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", FWFreeListCpuMap);
+
+       psFWFreeList->ui32MaxPages = ui32MaxFLPages;
+       psFWFreeList->ui32CurrentPages = ui32InitFLPages;
+       psFWFreeList->ui32GrowPages = ui32GrowFLPages;
+       psFWFreeList->ui32CurrentStackTop = ui32InitFLPages - 1;
+       psFWFreeList->psFreeListDevVAddr = sFreeListDevVAddr;
+       psFWFreeList->ui64CurrentDevVAddr = sFreeListDevVAddr.uiAddr + ((ui32MaxFLPages - ui32InitFLPages) * sizeof(IMG_UINT32));
+       psFWFreeList->ui32FreeListID = psFreeList->ui32FreelistID;
+       psFWFreeList->bGrowPending = IMG_FALSE;
+
+       PVR_DPF((PVR_DBG_MESSAGE,"Freelist %p created: Max pages 0x%08x, Init pages 0x%08x, Max FL base address 0x%016llx, Init FL base address 0x%016llx",
+                       psFreeList,
+                       ui32MaxFLPages,
+                       ui32InitFLPages,
+                       sFreeListDevVAddr.uiAddr,
+                       psFWFreeList->psFreeListDevVAddr.uiAddr));
+
+       PDUMPCOMMENT("Dump FW FreeList");
+       DevmemPDumpLoadMem(psFreeList->psFWFreelistMemDesc, 0, sizeof(*psFWFreeList), PDUMP_FLAGS_CONTINUOUS);
+
+       /*
+        * Separate dump of the Freelist's number of Pages and stack pointer.
+        * This allows to easily modify the PB size in the out2.txt files.
+        */
+       PDUMPCOMMENT("FreeList TotalPages");
+       DevmemPDumpLoadMemValue32(psFreeList->psFWFreelistMemDesc,
+                                                       offsetof(RGXFWIF_FREELIST, ui32CurrentPages),
+                                                       psFWFreeList->ui32CurrentPages,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+       PDUMPCOMMENT("FreeList StackPointer");
+       DevmemPDumpLoadMemValue32(psFreeList->psFWFreelistMemDesc,
+                                                       offsetof(RGXFWIF_FREELIST, ui32CurrentStackTop),
+                                                       psFWFreeList->ui32CurrentStackTop,
+                                                       PDUMP_FLAGS_CONTINUOUS);
+
+       DevmemReleaseCpuVirtAddr(psFreeList->psFWFreelistMemDesc);
+
+
+       /* Add initial PB block */
+       eError = RGXGrowFreeList(psFreeList,
+                                                               ui32InitFLPages,
+                                                               &psFreeList->sMemoryBlockInitHead);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "RGXCreateFreeList: failed to allocate initial memory block for free list 0x%016llx (error = %u)",
+                               sFreeListDevVAddr.uiAddr,
+                               eError));
+               goto FWFreeListCpuMap;
+       }
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+                       /* Update Stats */
+                       PVRSRVStatsUpdateFreelistStats(1, /* Add 1 to the appropriate counter (Requests by App)*/
+                                      0,
+                                      psFreeList->ui32InitFLPages,
+                                      psFreeList->ui32NumHighPages,
+                                      psFreeList->ownerPid);
+
+#endif
+
+       psFreeList->ownerPid = OSGetCurrentProcessID();
+       /* return values */
+       *ppsFreeList = psFreeList;
+
+       return PVRSRV_OK;
+
+       /* Error handling */
+
+FWFreeListCpuMap:
+       /* Remove freelists from list  */
+       OSLockAcquire(psDevInfo->hLockFreeList);
+       dllist_remove_node(&psFreeList->sNode);
+       OSLockRelease(psDevInfo->hLockFreeList);
+
+       RGXUnsetFirmwareAddress(psFWFreelistMemDesc);
+       DevmemFwFree(psFWFreelistMemDesc);
+
+FWFreeListAlloc:
+       SyncPrimFree(psFreeList->psCleanupSync);
+
+SyncAlloc:
+       OSFreeMem(psFreeList);
+
+ErrorAllocHost:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+/*
+       RGXDestroyFreeList
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyFreeList(RGX_FREELIST *psFreeList)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT64 ui64CheckSum;
+
+       PVR_ASSERT(psFreeList);
+
+       if (psFreeList->ui32RefCount != 0)
+       {
+               /* Freelist still busy */
+               return PVRSRV_ERROR_RETRY;
+       }
+
+       /* Freelist is not in use => start firmware cleanup */
+       eError = RGXFWRequestFreeListCleanUp(psFreeList->psDevInfo,
+                                                                                psFreeList->sFreeListFWDevVAddr,
+                                                                                psFreeList->psCleanupSync);
+       if(eError != PVRSRV_OK)
+       {
+               /* Can happen if the firmware took too long to handle the cleanup request,
+                * or if SLC-flushes didn't went through (due to some GPU lockup) */
+               return eError;
+       }
+
+       if (psFreeList->bCheckFreelist)
+       {
+               /* Do consistency tests (as the list is fully populated) */
+               eError = _FreeListCheckSum(psFreeList,
+                                                                       &ui64CheckSum);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "RGXDestroyFreeList: Failed to get freelist checksum Node %p",
+                                        psFreeList));
+                       sleep_for_ever();
+//                             PVR_ASSERT(0);
+               }
+
+               if (psFreeList->ui64FreelistChecksum != ui64CheckSum)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "RGXDestroyFreeList: Checksum mismatch [%p]! stored 0x%016llx, verified 0x%016llx %p",
+                                        psFreeList,
+                                        psFreeList->ui64FreelistChecksum,
+                                        ui64CheckSum,
+                                        psFreeList));
+                       sleep_for_ever();
+//                     PVR_ASSERT(0);
+               }
+       }
+
+       /* Destroy FW structures */
+       RGXUnsetFirmwareAddress(psFreeList->psFWFreelistMemDesc);
+       DevmemFwFree(psFreeList->psFWFreelistMemDesc);
+
+       /* Remove grow shrink blocks */
+       while (!dllist_is_empty(&psFreeList->sMemoryBlockHead))
+       {
+               eError = RGXShrinkFreeList(&psFreeList->sMemoryBlockHead, psFreeList);
+               PVR_ASSERT(eError == PVRSRV_OK);
+       }
+
+       /* Remove initial PB block */
+       eError = RGXShrinkFreeList(&psFreeList->sMemoryBlockInitHead, psFreeList);
+       PVR_ASSERT(eError == PVRSRV_OK);
+
+       /* consistency checks */
+       PVR_ASSERT(dllist_is_empty(&psFreeList->sMemoryBlockInitHead));
+       PVR_ASSERT(psFreeList->ui32CurrentFLPages == 0);
+
+       /* Remove FreeList from list */
+       OSLockAcquire(psFreeList->psDevInfo->hLockFreeList);
+       dllist_remove_node(&psFreeList->sNode);
+       OSLockRelease(psFreeList->psDevInfo->hLockFreeList);
+
+       SyncPrimFree(psFreeList->psCleanupSync);
+
+       /* free Freelist */
+       OSFreeMem(psFreeList);
+
+       return eError;
+}
+
+
+
+/*
+       RGXAddBlockToFreeListKM
+*/
+
+IMG_EXPORT
+PVRSRV_ERROR RGXAddBlockToFreeListKM(RGX_FREELIST *psFreeList,
+                                                                               IMG_UINT32 ui32NumPages)
+{
+       PVRSRV_ERROR eError;
+
+       /* Check if we have reference to freelist's PMR */
+       if (psFreeList->psFreeListPMR == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Freelist is not configured for grow"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* grow freelist */
+       eError = RGXGrowFreeList(psFreeList,
+                                                       ui32NumPages,
+                                                       &psFreeList->sMemoryBlockHead);
+       if(eError == PVRSRV_OK)
+       {
+               /* update freelist data in firmware */
+               _UpdateFwFreelistSize(psFreeList, IMG_TRUE, ui32NumPages);
+
+               psFreeList->ui32NumGrowReqByApp++;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+                       /* Update Stats */
+                       PVRSRVStatsUpdateFreelistStats(1, /* Add 1 to the appropriate counter (Requests by App)*/
+                                      0,
+                                      psFreeList->ui32InitFLPages,
+                                      psFreeList->ui32NumHighPages,
+                                      psFreeList->ownerPid);
+
+#endif
+       }
+
+       return eError;
+}
+
+/*
+       RGXRemoveBlockFromFreeListKM
+*/
+
+IMG_EXPORT
+PVRSRV_ERROR RGXRemoveBlockFromFreeListKM(RGX_FREELIST *psFreeList)
+{
+       PVRSRV_ERROR eError;
+
+       /*
+        * Make sure the pages part of the memory block are not in use anymore.
+        * Instruct the firmware to update the freelist pointers accordingly.
+        */
+
+       eError = RGXShrinkFreeList(&psFreeList->sMemoryBlockHead,
+                                                               psFreeList);
+
+       return eError;
+}
+
+
+/*
+       RGXCreateRenderTarget
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateRenderTarget(PVRSRV_DEVICE_NODE  *psDeviceNode, 
+                                                                  IMG_DEV_VIRTADDR             psVHeapTableDevVAddr,
+                                                                  RGX_RT_CLEANUP_DATA  **ppsCleanupData,
+                                                                  IMG_UINT32                   *sRenderTargetFWDevVAddr)
+{
+       PVRSRV_ERROR                    eError = PVRSRV_OK;
+       RGXFWIF_RENDER_TARGET   *psRenderTarget;
+       RGXFWIF_DEV_VIRTADDR    pFirmwareAddr;
+       PVRSRV_RGXDEV_INFO              *psDevInfo = psDeviceNode->pvDevice;
+       RGX_RT_CLEANUP_DATA             *psCleanupData;
+
+       psCleanupData = OSAllocMem(sizeof(*psCleanupData));
+       if (psCleanupData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_out;
+       }
+
+       OSMemSet(psCleanupData, 0, sizeof(*psCleanupData));
+       psCleanupData->psDeviceNode = psDeviceNode;
+       /*
+        * This FW render target context is only mapped into kernel for initialisation.
+        * Otherwise this allocation is only used by the FW.
+        * Therefore the GPU cache doesn't need coherency,
+        * and write-combine is suffice on the CPU side (WC buffer will be flushed at the first TA-kick)
+        */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(*psRenderTarget),
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
+                                                       "FirmwareRenderTarget",
+                                                       &psCleanupData->psRenderTargetMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "RGXCreateRenderTarget: DevmemAllocate for Render Target failed"));
+               goto err_free;
+       }
+       RGXSetFirmwareAddress(&pFirmwareAddr, psCleanupData->psRenderTargetMemDesc, 0, RFW_FWADDR_FLAG_NONE);
+       *sRenderTargetFWDevVAddr = pFirmwareAddr.ui32Addr;
+
+       eError = DevmemAcquireCpuVirtAddr(psCleanupData->psRenderTargetMemDesc, (IMG_VOID **)&psRenderTarget);
+       PVR_LOGG_IF_ERROR(eError, "Devmem AcquireCpuVirtAddr", err_fwalloc);
+
+       psRenderTarget->psVHeapTableDevVAddr = psVHeapTableDevVAddr;
+       psRenderTarget->bTACachesNeedZeroing = IMG_FALSE;
+       PDUMPCOMMENT("Dump RenderTarget");
+       DevmemPDumpLoadMem(psCleanupData->psRenderTargetMemDesc, 0, sizeof(*psRenderTarget), PDUMP_FLAGS_CONTINUOUS);
+       DevmemReleaseCpuVirtAddr(psCleanupData->psRenderTargetMemDesc);
+
+       *ppsCleanupData = psCleanupData;
+
+err_out:
+       return eError;
+
+err_free:
+       OSFreeMem(psCleanupData);
+       goto err_out;
+
+err_fwalloc:
+       DevmemFwFree(psCleanupData->psRenderTargetMemDesc);
+       goto err_free;
+
+}
+
+
+/*
+       RGXDestroyRenderTarget
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyRenderTarget(RGX_RT_CLEANUP_DATA *psCleanupData)
+{
+       RGXUnsetFirmwareAddress(psCleanupData->psRenderTargetMemDesc);
+
+       /*
+               Note:
+               When we get RT cleanup in the FW call that instead
+       */
+       /* Flush the the SLC before freeing */
+       {
+               RGXFWIF_KCCB_CMD sFlushInvalCmd;
+               PVRSRV_ERROR eError;
+               PVRSRV_DEVICE_NODE *psDeviceNode = psCleanupData->psDeviceNode;
+
+               /* Schedule the SLC flush command ... */
+#if defined(PDUMP)
+               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Submit SLC flush and invalidate");
+#endif
+               sFlushInvalCmd.eCmdType = RGXFWIF_KCCB_CMD_SLCFLUSHINVAL;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bInval = IMG_TRUE;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.bDMContext = IMG_FALSE;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.eDM = 0;
+               sFlushInvalCmd.uCmdData.sSLCFlushInvalData.psContext.ui32Addr = 0;
+
+               eError = RGXSendCommandWithPowLock(psDeviceNode->pvDevice,
+                                                                                       RGXFWIF_DM_GP,
+                                                                                       &sFlushInvalCmd,
+                                                                                       sizeof(sFlushInvalCmd),
+                                                                                       IMG_TRUE);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"RGXDestroyRenderTarget: Failed to schedule SLC flush command with error (%u)", eError));
+               }
+               else
+               {
+                       /* Wait for the SLC flush to complete */
+                       eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXDestroyRenderTarget: SLC flush and invalidate aborted with error (%u)", eError));
+                       }
+               }
+       }
+
+       DevmemFwFree(psCleanupData->psRenderTargetMemDesc);
+       OSFreeMem(psCleanupData);
+       return PVRSRV_OK;
+}
+
+/*
+       RGXCreateZSBuffer
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateZSBufferKM(PVRSRV_DEVICE_NODE    *psDeviceNode,
+                                                               DEVMEMINT_RESERVATION   *psReservation,
+                                                               PMR                                     *psPMR,
+                                                               PVRSRV_MEMALLOCFLAGS_T  uiMapFlags,
+                                                               RGX_ZSBUFFER_DATA **ppsZSBuffer,
+                                                               IMG_UINT32 *pui32ZSBufferFWDevVAddr)
+{
+       PVRSRV_ERROR                            eError;
+       PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_FWZSBUFFER                      *psFWZSBuffer;
+       RGX_ZSBUFFER_DATA                       *psZSBuffer;
+       DEVMEM_MEMDESC                          *psFWZSBufferMemDesc;
+       IMG_BOOL                                        bOnDemand = ((uiMapFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) > 0);
+
+       /* Allocate host data structure */
+       psZSBuffer = OSAllocMem(sizeof(*psZSBuffer));
+       if (psZSBuffer == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateZSBufferKM: Failed to allocate cleanup data structure for ZS-Buffer"));
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto ErrorAllocCleanup;
+       }
+       OSMemSet(psZSBuffer, 0, sizeof(*psZSBuffer));
+
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psZSBuffer->psCleanupSync,
+                                                  "ta3d zs buffer cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateZSBufferKM: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto ErrorSyncAlloc;
+       }
+
+       /* Populate Host data */
+       psZSBuffer->psDevInfo = psDevInfo;
+       psZSBuffer->psReservation = psReservation;
+       psZSBuffer->psPMR = psPMR;
+       psZSBuffer->uiMapFlags = uiMapFlags;
+       psZSBuffer->ui32RefCount = 0;
+       psZSBuffer->bOnDemand = bOnDemand;
+    if (bOnDemand)
+    {
+       psZSBuffer->ui32ZSBufferID = psDevInfo->ui32ZSBufferCurrID++;
+       psZSBuffer->psMapping = IMG_NULL;
+
+               OSLockAcquire(psDevInfo->hLockZSBuffer);
+       dllist_add_to_tail(&psDevInfo->sZSBufferHead, &psZSBuffer->sNode);
+               OSLockRelease(psDevInfo->hLockZSBuffer);
+    }
+
+       /* Allocate firmware memory for ZS-Buffer. */
+       PDUMPCOMMENT("Allocate firmware ZS-Buffer data structure");
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(*psFWZSBuffer),
+                                                       PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
+                                                       PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+                                                       PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
+                                                       PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE,
+                                                       "FirmwareZSBuffer",
+                                                       &psFWZSBufferMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateZSBufferKM: Failed to allocate firmware ZS-Buffer (%u)", eError));
+               goto ErrorAllocFWZSBuffer;
+       }
+       psZSBuffer->psZSBufferMemDesc = psFWZSBufferMemDesc;
+
+       /* Temporarily map the firmware render context to the kernel. */
+       eError = DevmemAcquireCpuVirtAddr(psFWZSBufferMemDesc,
+                                      (IMG_VOID **)&psFWZSBuffer);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"RGXCreateZSBufferKM: Failed to map firmware ZS-Buffer (%u)", eError));
+               goto ErrorAcquireFWZSBuffer;
+       }
+
+       /* Populate FW ZS-Buffer data structure */
+       psFWZSBuffer->bOnDemand = bOnDemand;
+       psFWZSBuffer->eState = (bOnDemand) ? RGXFWIF_ZSBUFFER_UNBACKED : RGXFWIF_ZSBUFFER_BACKED;
+       psFWZSBuffer->ui32ZSBufferID = psZSBuffer->ui32ZSBufferID;
+
+       /* Get firmware address of ZS-Buffer. */
+       RGXSetFirmwareAddress(&psZSBuffer->sZSBufferFWDevVAddr, psFWZSBufferMemDesc, 0, RFW_FWADDR_FLAG_NONE);
+
+       /* Dump the ZS-Buffer and the memory content */
+       PDUMPCOMMENT("Dump firmware ZS-Buffer");
+       DevmemPDumpLoadMem(psFWZSBufferMemDesc, 0, sizeof(*psFWZSBuffer), PDUMP_FLAGS_CONTINUOUS);
+
+       /* Release address acquired above. */
+       DevmemReleaseCpuVirtAddr(psFWZSBufferMemDesc);
+
+
+       /* define return value */
+       *ppsZSBuffer = psZSBuffer;
+       *pui32ZSBufferFWDevVAddr = psZSBuffer->sZSBufferFWDevVAddr.ui32Addr;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "ZS-Buffer [%p] created (%s)",
+                                                       psZSBuffer,
+                                                       (bOnDemand) ? "On-Demand": "Up-front"));
+
+       psZSBuffer->owner=OSGetCurrentProcessID();
+
+       return PVRSRV_OK;
+
+       /* error handling */
+
+ErrorAcquireFWZSBuffer:
+       DevmemFwFree(psFWZSBufferMemDesc);
+
+ErrorAllocFWZSBuffer:
+       SyncPrimFree(psZSBuffer->psCleanupSync);
+
+ErrorSyncAlloc:
+       OSFreeMem(psZSBuffer);
+
+ErrorAllocCleanup:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+/*
+       RGXDestroyZSBuffer
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer)
+{
+       POS_LOCK hLockZSBuffer;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psZSBuffer);
+       hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer;
+
+       /* Request ZS Buffer cleanup */
+       eError = RGXFWRequestZSBufferCleanUp(psZSBuffer->psDevInfo,
+                                                                               psZSBuffer->sZSBufferFWDevVAddr,
+                                                                               psZSBuffer->psCleanupSync);
+       if (eError != PVRSRV_ERROR_RETRY)
+       {
+               /* Free the firmware render context. */
+       RGXUnsetFirmwareAddress(psZSBuffer->psZSBufferMemDesc);
+               DevmemFwFree(psZSBuffer->psZSBufferMemDesc);
+
+           /* Remove Deferred Allocation from list */
+               if (psZSBuffer->bOnDemand)
+               {
+                       OSLockAcquire(hLockZSBuffer);
+                       PVR_ASSERT(dllist_node_is_in_list(&psZSBuffer->sNode));
+                       dllist_remove_node(&psZSBuffer->sNode);
+                       OSLockRelease(hLockZSBuffer);
+               }
+
+               SyncPrimFree(psZSBuffer->psCleanupSync);
+
+               PVR_ASSERT(psZSBuffer->ui32RefCount == 0);
+
+               PVR_DPF((PVR_DBG_MESSAGE,"ZS-Buffer [%p] destroyed",psZSBuffer));
+
+               /* Free ZS-Buffer host data structure */
+               OSFreeMem(psZSBuffer);
+
+       }
+
+       return eError;
+}
+
+PVRSRV_ERROR
+RGXBackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer)
+{
+       POS_LOCK hLockZSBuffer;
+       PVRSRV_ERROR eError;
+
+       if (!psZSBuffer)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       if ((psZSBuffer->uiMapFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) == 0)
+       {
+               /* Only deferred allocations can be populated */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE,"ZS Buffer [%p, ID=0x%08x]: Physical backing requested",
+                                                               psZSBuffer,
+                                                               psZSBuffer->ui32ZSBufferID));
+       hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer;
+
+       OSLockAcquire(hLockZSBuffer);
+
+       if (psZSBuffer->ui32RefCount == 0)
+       {
+               if (psZSBuffer->bOnDemand)
+               {
+                       IMG_HANDLE hDevmemHeap;
+
+                       PVR_ASSERT(psZSBuffer->psMapping == IMG_NULL);
+
+                       /* Get Heap */
+                       eError = DevmemServerGetHeapHandle(psZSBuffer->psReservation, &hDevmemHeap);
+                       PVR_ASSERT(psZSBuffer->psMapping == IMG_NULL);
+
+                       eError = DevmemIntMapPMR(hDevmemHeap,
+                                                                       psZSBuffer->psReservation,
+                                                                       psZSBuffer->psPMR,
+                                                                       psZSBuffer->uiMapFlags,
+                                                                       &psZSBuffer->psMapping);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"Unable populate ZS Buffer [%p, ID=0x%08x] with error %u",
+                                                                               psZSBuffer,
+                                                                               psZSBuffer->ui32ZSBufferID,
+                                                                               eError));
+                               OSLockRelease(hLockZSBuffer);
+                               return eError;
+
+                       }
+                       PVR_DPF((PVR_DBG_MESSAGE, "ZS Buffer [%p, ID=0x%08x]: Physical backing acquired",
+                                                                               psZSBuffer,
+                                                                               psZSBuffer->ui32ZSBufferID));
+               }
+       }
+
+       /* Increase refcount*/
+       psZSBuffer->ui32RefCount++;
+
+       OSLockRelease(hLockZSBuffer);
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+RGXPopulateZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer,
+                                       RGX_POPULATION **ppsPopulation)
+{
+       RGX_POPULATION *psPopulation;
+       PVRSRV_ERROR eError;
+
+       psZSBuffer->ui32NumReqByApp++;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       PVRSRVStatsUpdateZSBufferStats(1,0,psZSBuffer->owner);
+#endif
+
+       /* Do the backing */
+       eError = RGXBackingZSBuffer(psZSBuffer);
+       if (eError != PVRSRV_OK)
+       {
+               goto OnErrorBacking;
+       }
+
+       /* Create the handle to the backing */
+       psPopulation = OSAllocMem(sizeof(*psPopulation));
+       if (psPopulation == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto OnErrorAlloc;
+       }
+
+       psPopulation->psZSBuffer = psZSBuffer;
+
+       /* return value */
+       *ppsPopulation = psPopulation;
+
+       return PVRSRV_OK;
+
+OnErrorAlloc:
+       RGXUnbackingZSBuffer(psZSBuffer);
+
+OnErrorBacking:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+PVRSRV_ERROR
+RGXUnbackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer)
+{
+       POS_LOCK hLockZSBuffer;
+       PVRSRV_ERROR eError;
+
+       if (!psZSBuffer)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       PVR_ASSERT(psZSBuffer->ui32RefCount);
+
+       PVR_DPF((PVR_DBG_MESSAGE,"ZS Buffer [%p, ID=0x%08x]: Physical backing removal requested",
+                                                               psZSBuffer,
+                                                               psZSBuffer->ui32ZSBufferID));
+
+       hLockZSBuffer = psZSBuffer->psDevInfo->hLockZSBuffer;
+
+       OSLockAcquire(hLockZSBuffer);
+
+       if (psZSBuffer->bOnDemand)
+       {
+               if (psZSBuffer->ui32RefCount == 1)
+               {
+                       PVR_ASSERT(psZSBuffer->psMapping);
+
+                       eError = DevmemIntUnmapPMR(psZSBuffer->psMapping);
+                       if (eError != PVRSRV_OK)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"Unable to unpopulate ZS Buffer [%p, ID=0x%08x] with error %u",
+                                                                               psZSBuffer,
+                                                                               psZSBuffer->ui32ZSBufferID,
+                                                                               eError));
+                               OSLockRelease(hLockZSBuffer);
+                               return eError;
+                       }
+
+                       PVR_DPF((PVR_DBG_MESSAGE, "ZS Buffer [%p, ID=0x%08x]: Physical backing removed",
+                                                                               psZSBuffer,
+                                                                               psZSBuffer->ui32ZSBufferID));
+               }
+       }
+
+       /* Decrease refcount*/
+       psZSBuffer->ui32RefCount--;
+
+       OSLockRelease(hLockZSBuffer);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+RGXUnpopulateZSBufferKM(RGX_POPULATION *psPopulation)
+{
+       PVRSRV_ERROR eError;
+
+       if (!psPopulation)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       eError = RGXUnbackingZSBuffer(psPopulation->psZSBuffer);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       OSFreeMem(psPopulation);
+
+       return PVRSRV_OK;
+}
+
+static IMG_BOOL _FindZSBuffer(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       DEVMEM_REF_LOOKUP *psRefLookUp = (DEVMEM_REF_LOOKUP *)pvCallbackData;
+       RGX_ZSBUFFER_DATA *psZSBuffer;
+
+       psZSBuffer = IMG_CONTAINER_OF(psNode, RGX_ZSBUFFER_DATA, sNode);
+
+       if (psZSBuffer->ui32ZSBufferID == psRefLookUp->ui32ZSBufferID)
+       {
+               psRefLookUp->psZSBuffer = psZSBuffer;
+               return IMG_FALSE;
+       }
+       else
+       {
+               return IMG_TRUE;
+       }
+}
+
+IMG_VOID RGXProcessRequestZSBufferBacking(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                       IMG_UINT32 ui32ZSBufferID)
+{
+       DEVMEM_REF_LOOKUP sLookUp;
+       RGXFWIF_KCCB_CMD sTACCBCmd;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psDevInfo);
+
+       /* scan all deferred allocations */
+       sLookUp.ui32ZSBufferID = ui32ZSBufferID;
+       sLookUp.psZSBuffer = IMG_NULL;
+
+       OSLockAcquire(psDevInfo->hLockZSBuffer);
+       dllist_foreach_node(&psDevInfo->sZSBufferHead, _FindZSBuffer, (IMG_PVOID)&sLookUp);
+       OSLockRelease(psDevInfo->hLockZSBuffer);
+
+       if (sLookUp.psZSBuffer)
+       {
+               IMG_BOOL bBackingDone = IMG_TRUE;
+
+               /* Populate ZLS */
+               eError = RGXBackingZSBuffer(sLookUp.psZSBuffer);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"Populating ZS-Buffer failed failed with error %u (ID = 0x%08x)", eError, ui32ZSBufferID));
+                       bBackingDone = IMG_FALSE;
+               }
+
+               /* send confirmation */
+               sTACCBCmd.eCmdType = RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE;
+               sTACCBCmd.uCmdData.sZSBufferBackingData.psZSBufferFWDevVAddr = sLookUp.psZSBuffer->sZSBufferFWDevVAddr.ui32Addr;
+               sTACCBCmd.uCmdData.sZSBufferBackingData.bDone = bBackingDone;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError = RGXScheduleCommand(psDevInfo,
+                                                                                               RGXFWIF_DM_TA,
+                                                                                               &sTACCBCmd,
+                                                                                               sizeof(sTACCBCmd),
+                                                                                               IMG_FALSE);
+                       if (eError != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+
+               /* Kernel CCB should never fill up, as the FW is processing them right away  */
+               PVR_ASSERT(eError == PVRSRV_OK);
+
+               sLookUp.psZSBuffer->ui32NumReqByFW++;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+               PVRSRVStatsUpdateZSBufferStats(0,1,sLookUp.psZSBuffer->owner);
+#endif
+
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR,"ZS Buffer Lookup for ZS Buffer ID 0x%08x failed (Populate)", sLookUp.ui32ZSBufferID));
+       }
+}
+
+IMG_VOID RGXProcessRequestZSBufferUnbacking(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                                       IMG_UINT32 ui32ZSBufferID)
+{
+       DEVMEM_REF_LOOKUP sLookUp;
+       RGXFWIF_KCCB_CMD sTACCBCmd;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psDevInfo);
+
+       /* scan all deferred allocations */
+       sLookUp.ui32ZSBufferID = ui32ZSBufferID;
+       sLookUp.psZSBuffer = IMG_NULL;
+
+       OSLockAcquire(psDevInfo->hLockZSBuffer);
+       dllist_foreach_node(&psDevInfo->sZSBufferHead, _FindZSBuffer, (IMG_PVOID)&sLookUp);
+       OSLockRelease(psDevInfo->hLockZSBuffer);
+
+       if (sLookUp.psZSBuffer)
+       {
+               /* Unpopulate ZLS */
+               eError = RGXUnbackingZSBuffer(sLookUp.psZSBuffer);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"UnPopulating ZS-Buffer failed failed with error %u (ID = 0x%08x)", eError, ui32ZSBufferID));
+                       PVR_ASSERT(IMG_FALSE);
+               }
+
+               /* send confirmation */
+               sTACCBCmd.eCmdType = RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE;
+               sTACCBCmd.uCmdData.sZSBufferBackingData.psZSBufferFWDevVAddr = sLookUp.psZSBuffer->sZSBufferFWDevVAddr.ui32Addr;
+               sTACCBCmd.uCmdData.sZSBufferBackingData.bDone = IMG_TRUE;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError = RGXScheduleCommand(psDevInfo,
+                                                                                               RGXFWIF_DM_TA,
+                                                                                               &sTACCBCmd,
+                                                                                               sizeof(sTACCBCmd),
+                                                                                               IMG_FALSE);
+                       if (eError != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+
+               /* Kernel CCB should never fill up, as the FW is processing them right away  */
+               PVR_ASSERT(eError == PVRSRV_OK);
+
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR,"ZS Buffer Lookup for ZS Buffer ID 0x%08x failed (UnPopulate)", sLookUp.ui32ZSBufferID));
+       }
+}
+
+static
+PVRSRV_ERROR _CreateTAContext(CONNECTION_DATA *psConnection,
+                                                         PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                         DEVMEM_MEMDESC *psAllocatedMemDesc,
+                                                         IMG_UINT32 ui32AllocatedOffset,
+                                                         DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                         IMG_DEV_VIRTADDR sVDMCallStackAddr,
+                                                         IMG_UINT32 ui32Priority,
+                                                         RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                         RGX_SERVER_RC_TA_DATA *psTAData)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       RGXFWIF_TACTX_STATE *psContextState;
+       PVRSRV_ERROR eError;
+       /*
+               Allocate device memory for the firmware GPU context suspend state.
+               Note: the FW reads/writes the state to memory by accessing the GPU register interface.
+       */
+       PDUMPCOMMENT("Allocate RGX firmware TA context suspend state");
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         sizeof(RGXFWIF_TACTX_STATE),
+                                                         RGX_FWCOMCTX_ALLOCFLAGS,
+                                                         "FirmwareTAContextState",
+                                                         &psTAData->psContextStateMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to allocate firmware GPU context suspend state (%u)",
+                               eError));
+               goto fail_tacontextsuspendalloc;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psTAData->psContextStateMemDesc,
+                                      (IMG_VOID **)&psContextState);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to map firmware render context state (%u)",
+                               eError));
+               goto fail_suspendcpuvirtacquire;
+       }
+       psContextState->uTAReg_VDM_CALL_STACK_POINTER_Init = sVDMCallStackAddr.uiAddr;
+       DevmemReleaseCpuVirtAddr(psTAData->psContextStateMemDesc);
+
+       eError = FWCommonContextAllocate(psConnection,
+                                                                        psDeviceNode,
+                                                                        "TA",
+                                                                        psAllocatedMemDesc,
+                                                                        ui32AllocatedOffset,
+                                                                        psFWMemContextMemDesc,
+                                                                        psTAData->psContextStateMemDesc,
+                                                                        RGX_CCB_SIZE_LOG2,
+                                                                        ui32Priority,
+                                                                        psInfo,
+                                                                        &psTAData->psServerCommonContext);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to init TA fw common context (%u)",
+                               eError));
+               goto fail_tacommoncontext;
+       }
+       
+       /*
+        * Dump the FW 3D context suspend state buffer
+        */
+       PDUMPCOMMENT("Dump the TA context suspend state buffer");
+       DevmemPDumpLoadMem(psTAData->psContextStateMemDesc,
+                                          0,
+                                          sizeof(RGXFWIF_TACTX_STATE),
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       psTAData->ui32Priority = ui32Priority;
+       return PVRSRV_OK;
+
+fail_tacommoncontext:
+fail_suspendcpuvirtacquire:
+       DevmemFwFree(psTAData->psContextStateMemDesc);
+fail_tacontextsuspendalloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+static
+PVRSRV_ERROR _Create3DContext(CONNECTION_DATA *psConnection,
+                                                         PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                         DEVMEM_MEMDESC *psAllocatedMemDesc,
+                                                         IMG_UINT32 ui32AllocatedOffset,
+                                                         DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                         IMG_UINT32 ui32Priority,
+                                                         RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                         RGX_SERVER_RC_3D_DATA *ps3DData)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_ERROR eError;
+
+       /*
+               Allocate device memory for the firmware GPU context suspend state.
+               Note: the FW reads/writes the state to memory by accessing the GPU register interface.
+       */
+       PDUMPCOMMENT("Allocate RGX firmware 3D context suspend state");
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         sizeof(RGXFWIF_3DCTX_STATE),
+                                                         RGX_FWCOMCTX_ALLOCFLAGS,
+                                                         "Firmware3DContextState",
+                                                         &ps3DData->psContextStateMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to allocate firmware GPU context suspend state (%u)",
+                               eError));
+               goto fail_3dcontextsuspendalloc;
+       }
+
+       eError = FWCommonContextAllocate(psConnection,
+                                                                        psDeviceNode,
+                                                                        "3D",
+                                                                        psAllocatedMemDesc,
+                                                                        ui32AllocatedOffset,
+                                                                        psFWMemContextMemDesc,
+                                                                        ps3DData->psContextStateMemDesc,
+                                                                        RGX_CCB_SIZE_LOG2,
+                                                                        ui32Priority,
+                                                                        psInfo,
+                                                                        &ps3DData->psServerCommonContext);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to init 3D fw common context (%u)",
+                               eError));
+               goto fail_3dcommoncontext;
+       }
+
+       /*
+        * Dump the FW 3D context suspend state buffer
+        */
+       PDUMPCOMMENT("Dump the 3D context suspend state buffer");
+       DevmemPDumpLoadMem(ps3DData->psContextStateMemDesc,
+                                          0,
+                                          sizeof(RGXFWIF_3DCTX_STATE),
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       ps3DData->ui32Priority = ui32Priority;
+       return PVRSRV_OK;
+
+fail_3dcommoncontext:
+       DevmemFwFree(ps3DData->psContextStateMemDesc);
+fail_3dcontextsuspendalloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+
+/*
+ * PVRSRVRGXCreateRenderContextKM
+ */
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateRenderContextKM(CONNECTION_DATA                            *psConnection,
+                                                                                       PVRSRV_DEVICE_NODE                      *psDeviceNode,
+                                                                                       IMG_UINT32                                      ui32Priority,
+                                                                                       IMG_DEV_VIRTADDR                        sMCUFenceAddr,
+                                                                                       IMG_DEV_VIRTADDR                        sVDMCallStackAddr,
+                                                                                       IMG_UINT32                                      ui32FrameworkRegisterSize,
+                                                                                       IMG_PBYTE                                       pabyFrameworkRegisters,
+                                                                                       IMG_HANDLE                                      hMemCtxPrivData,
+                                                                                       RGX_SERVER_RENDER_CONTEXT       **ppsRenderContext)
+{
+       PVRSRV_ERROR                            eError;
+       PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+       RGX_SERVER_RENDER_CONTEXT       *psRenderContext;
+       DEVMEM_MEMDESC                          *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       RGX_COMMON_CONTEXT_INFO         sInfo;
+
+       /* Prepare cleanup structure */
+       *ppsRenderContext = IMG_NULL;
+       psRenderContext = OSAllocMem(sizeof(*psRenderContext));
+       if (psRenderContext == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psRenderContext, 0, sizeof(*psRenderContext));
+       psRenderContext->psDeviceNode = psDeviceNode;
+
+       /*
+               Create the FW render context, this has the TA and 3D FW common
+               contexts embedded within it
+       */
+       eError = DevmemFwAllocate(psDevInfo,
+                                                         sizeof(RGXFWIF_FWRENDERCONTEXT),
+                                                         RGX_FWCOMCTX_ALLOCFLAGS,
+                                                         "FirmwareRenderContext",
+                                                         &psRenderContext->psFWRenderContextMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_fwrendercontext;
+       }
+
+       /*
+               As the common context alloc will dump the TA and 3D common contexts
+               after the've been setup we skip of the 2 common contexts and dump the
+               rest of the structure
+       */
+       PDUMPCOMMENT("Dump shared part of render context context");
+       DevmemPDumpLoadMem(psRenderContext->psFWRenderContextMemDesc,
+                                          (sizeof(RGXFWIF_FWCOMMONCONTEXT) * 2),
+                                          sizeof(RGXFWIF_FWRENDERCONTEXT) - (sizeof(RGXFWIF_FWCOMMONCONTEXT) * 2),
+                                          PDUMP_FLAGS_CONTINUOUS);
+
+       /* Allocate cleanup sync */
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psRenderContext->psCleanupSync,
+                                                  "ta3d render context cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto fail_syncalloc;
+       }
+
+       /* 
+        * Create the FW framework buffer
+        */
+       eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode,
+                                                                               &psRenderContext->psFWFrameworkMemDesc,
+                                                                               ui32FrameworkRegisterSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to allocate firmware GPU framework state (%u)",
+                               eError));
+               goto fail_frameworkcreate;
+       }
+
+       /* Copy the Framework client data into the framework buffer */
+       eError = PVRSRVRGXFrameworkCopyCommand(psRenderContext->psFWFrameworkMemDesc,
+                                                                                  pabyFrameworkRegisters,
+                                                                                  ui32FrameworkRegisterSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateRenderContextKM: Failed to populate the framework buffer (%u)",
+                               eError));
+               goto fail_frameworkcopy;
+       }
+
+       sInfo.psFWFrameworkMemDesc = psRenderContext->psFWFrameworkMemDesc;
+       sInfo.psMCUFenceAddr = &sMCUFenceAddr;
+
+       eError = _CreateTAContext(psConnection,
+                                                         psDeviceNode,
+                                                         psRenderContext->psFWRenderContextMemDesc,
+                                                         offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext),
+                                                         psFWMemContextMemDesc,
+                                                         sVDMCallStackAddr,
+                                                         ui32Priority,
+                                                         &sInfo,
+                                                         &psRenderContext->sTAData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_tacontext;
+       }
+
+       eError = _Create3DContext(psConnection,
+                                                         psDeviceNode,
+                                                         psRenderContext->psFWRenderContextMemDesc,
+                                                         offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext),
+                                                         psFWMemContextMemDesc,
+                                                         ui32Priority,
+                                                         &sInfo,
+                                                         &psRenderContext->s3DData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_3dcontext;
+       }
+
+       SyncAddrListInit(&psRenderContext->sSyncAddrListTAFence);
+       SyncAddrListInit(&psRenderContext->sSyncAddrListTAUpdate);
+       SyncAddrListInit(&psRenderContext->sSyncAddrList3DFence);
+       SyncAddrListInit(&psRenderContext->sSyncAddrList3DUpdate);
+
+       {
+               PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+
+               OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock);
+               dllist_add_to_tail(&(psDevInfo->sRenderCtxtListHead), &(psRenderContext->sListNode));
+               OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock);
+       }
+
+       *ppsRenderContext= psRenderContext;
+       return PVRSRV_OK;
+
+fail_3dcontext:
+       _DestroyTAContext(&psRenderContext->sTAData,
+                                         psDeviceNode,
+                                         psRenderContext->psCleanupSync);
+fail_tacontext:
+fail_frameworkcopy:
+       DevmemFwFree(psRenderContext->psFWFrameworkMemDesc);
+fail_frameworkcreate:
+       SyncPrimFree(psRenderContext->psCleanupSync);
+fail_syncalloc:
+       DevmemFwFree(psRenderContext->psFWRenderContextMemDesc);
+fail_fwrendercontext:
+       OSFreeMem(psRenderContext);
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+/*
+ * PVRSRVRGXDestroyRenderContextKM
+ */
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext)
+{
+       PVRSRV_ERROR                            eError;
+       PVRSRV_RGXDEV_INFO      *psDevInfo = psRenderContext->psDeviceNode->pvDevice;
+
+       /* remove node from list before calling destroy - as destroy, if successful
+        * will invalidate the node
+        * must be re-added if destroy fails
+        */
+       OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock);
+       dllist_remove_node(&(psRenderContext->sListNode));
+       OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock);
+
+       /* Cleanup the TA if we haven't already */
+       if ((psRenderContext->ui32CleanupStatus & RC_CLEANUP_TA_COMPLETE) == 0)
+       {
+               eError = _DestroyTAContext(&psRenderContext->sTAData,
+                                                                  psRenderContext->psDeviceNode,
+                                                                  psRenderContext->psCleanupSync);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       psRenderContext->ui32CleanupStatus |= RC_CLEANUP_TA_COMPLETE;
+               }
+               else
+               {
+                       goto e0;
+               }
+       }
+
+       /* Cleanup the 3D if we haven't already */
+       if ((psRenderContext->ui32CleanupStatus & RC_CLEANUP_3D_COMPLETE) == 0)
+       {
+               eError = _Destroy3DContext(&psRenderContext->s3DData,
+                                                                  psRenderContext->psDeviceNode,
+                                                                  psRenderContext->psCleanupSync);
+               if (eError != PVRSRV_ERROR_RETRY)
+               {
+                       psRenderContext->ui32CleanupStatus |= RC_CLEANUP_3D_COMPLETE;
+               }
+               else
+               {
+                       goto e0;
+               }
+       }
+
+       /*
+               Only if both TA and 3D contexts have been cleaned up can we
+               free the shared resources
+       */
+       if (psRenderContext->ui32CleanupStatus == (RC_CLEANUP_3D_COMPLETE | RC_CLEANUP_TA_COMPLETE))
+       {
+               RGXFWIF_FWRENDERCONTEXT *psFWRenderContext;
+
+               /* Update SPM statistics */
+               eError = DevmemAcquireCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc,
+                                             (IMG_VOID **)&psFWRenderContext);
+               if (eError == PVRSRV_OK)
+               {
+                       DevmemReleaseCpuVirtAddr(psRenderContext->psFWRenderContextMemDesc);
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXDestroyRenderContextKM: Failed to map firmware render context (%u)",
+                                       eError));
+               }
+
+               /* Free the framework buffer */
+               DevmemFwFree(psRenderContext->psFWFrameworkMemDesc);
+       
+               /* Free the firmware render context */
+               DevmemFwFree(psRenderContext->psFWRenderContextMemDesc);
+
+               /* Free the cleanup sync */
+               SyncPrimFree(psRenderContext->psCleanupSync);
+
+               SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAFence);
+               SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAUpdate);
+               SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DFence);
+               SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DUpdate);
+
+               OSFreeMem(psRenderContext);
+       }
+
+       return PVRSRV_OK;
+
+e0:
+       OSWRLockAcquireWrite(psDevInfo->hRenderCtxListLock);
+       dllist_add_to_tail(&(psDevInfo->sRenderCtxtListHead), &(psRenderContext->sListNode));
+       OSWRLockReleaseWrite(psDevInfo->hRenderCtxListLock);
+       return eError;
+}
+
+
+/* TODO !!! this was local on the stack, and we managed to blow the stack for the kernel. 
+ * THIS - 46 argument function needs to be sorted out.
+ */
+/* 1 command for the TA */
+static RGX_CCB_CMD_HELPER_DATA asTACmdHelperData[1];
+/* Up to 3 commands for the 3D (partial render fence, partial reader, and render) */
+static RGX_CCB_CMD_HELPER_DATA as3DCmdHelperData[3];
+
+/*
+ * PVRSRVRGXKickTA3DKM
+ */
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT     *psRenderContext,
+                                                                IMG_UINT32                                     ui32ClientTAFenceCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClientTAFenceSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32ClientTAFenceSyncOffset,
+                                                                IMG_UINT32                                     *paui32ClientTAFenceValue,
+                                                                IMG_UINT32                                     ui32ClientTAUpdateCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClientTAUpdateSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32ClientTAUpdateSyncOffset,
+                                                                IMG_UINT32                                     *paui32ClientTAUpdateValue,
+                                                                IMG_UINT32                                     ui32ServerTASyncPrims,
+                                                                IMG_UINT32                                     *paui32ServerTASyncFlags,
+                                                                SERVER_SYNC_PRIMITIVE          **pasServerTASyncs,
+                                                                IMG_UINT32                                     ui32Client3DFenceCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClient3DFenceSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32Client3DFenceSyncOffset,
+                                                                IMG_UINT32                                     *paui32Client3DFenceValue,
+                                                                IMG_UINT32                                     ui32Client3DUpdateCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClient3DUpdateSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32Client3DUpdateSyncOffset,
+                                                                IMG_UINT32                                     *paui32Client3DUpdateValue,
+                                                                IMG_UINT32                                     ui32Server3DSyncPrims,
+                                                                IMG_UINT32                                     *paui32Server3DSyncFlags,
+                                                                SERVER_SYNC_PRIMITIVE          **pasServer3DSyncs,
+                                                                SYNC_PRIMITIVE_BLOCK                           *psPRFenceSyncPrimBlock,
+                                                                IMG_UINT32                                     ui32PRFenceSyncOffset,
+                                                                IMG_UINT32                                     ui32PRFenceValue,
+                                                                IMG_UINT32                                     ui32NumCheckFenceFDs,
+                                                                IMG_INT32                                      *ai32CheckFenceFDs,
+                                                                IMG_INT32                  i32UpdateFenceFD,
+                                                                IMG_UINT32                                     ui32TACmdSize,
+                                                                IMG_PBYTE                                      pui8TADMCmd,
+                                                                IMG_UINT32                                     ui323DPRCmdSize,
+                                                                IMG_PBYTE                                      pui83DPRDMCmd,
+                                                                IMG_UINT32                                     ui323DCmdSize,
+                                                                IMG_PBYTE                                      pui83DDMCmd,
+                                                                IMG_UINT32                                     ui32ExtJobRef,
+                                                                IMG_UINT32                                     ui32IntJobRef,
+                                                                IMG_BOOL                                       bLastTAInScene,
+                                                                IMG_BOOL                                       bKickTA,
+                                                                IMG_BOOL                                       bKickPR,
+                                                                IMG_BOOL                                       bKick3D,
+                                                                IMG_BOOL                                       bAbort,
+                                                                IMG_BOOL                                       bPDumpContinuous,
+                                                                RGX_RTDATA_CLEANUP_DATA        *psRTDataCleanup,
+                                                                RGX_ZSBUFFER_DATA              *psZBuffer,
+                                                                RGX_ZSBUFFER_DATA              *psSBuffer,
+                                                                IMG_BOOL                       bCommitRefCountsTA,
+                                                                IMG_BOOL                       bCommitRefCounts3D,
+                                                                IMG_BOOL                       *pbCommittedRefCountsTA,
+                                                                IMG_BOOL                       *pbCommittedRefCounts3D)
+{
+
+       IMG_UINT32                              ui32TACmdCount=0;
+       IMG_UINT32                              ui323DCmdCount=0;
+       IMG_BOOL                                bKickTADM = IMG_FALSE;
+       IMG_BOOL                                bKick3DDM = IMG_FALSE;
+       RGXFWIF_UFO                             sPRUFO;
+       IMG_UINT32                              *paui32Server3DSyncFlagsPR = IMG_NULL;
+       IMG_UINT32                              *paui32Server3DSyncFlags3D = IMG_NULL;
+       IMG_UINT32                              i;
+       PVRSRV_ERROR                    eError = PVRSRV_OK;
+       PVRSRV_ERROR                    eError2;
+
+       /* Internal client sync info, used to help with merging of Android fd syncs */
+       IMG_UINT32                              ui32IntClientTAFenceCount = 0;
+       PRGXFWIF_UFO_ADDR               *pauiIntClientTAFenceUFOAddress = IMG_NULL;
+       IMG_UINT32                              *paui32IntClientTAFenceValue = IMG_NULL;
+
+       IMG_UINT32                              ui32NumUpdateSyncs = 0;
+       PRGXFWIF_UFO_ADDR               *puiUpdateFWAddrs = IMG_NULL;
+       IMG_UINT32                              *pui32UpdateValues = IMG_NULL;
+
+       PRGXFWIF_UFO_ADDR                       uiPRFenceUFOAddress;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       /* Android fd sync update info */
+       struct pvr_sync_append_data *psFDData = NULL;
+#endif
+
+       RGXFWIF_DEV_VIRTADDR pPreTimestamp;
+       RGXFWIF_DEV_VIRTADDR pPostTimestamp;
+       PRGXFWIF_UFO_ADDR    pRMWUFOAddr;
+
+       PRGXFWIF_UFO_ADDR                       *pauiClientTAFenceUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *pauiClientTAUpdateUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *pauiClient3DFenceUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *pauiClient3DUpdateUFOAddress;
+
+       *pbCommittedRefCountsTA = IMG_FALSE;
+       *pbCommittedRefCounts3D = IMG_FALSE;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAFence,
+                                                                               ui32ClientTAFenceCount,
+                                                                               apsClientTAFenceSyncPrimBlock,
+                                                                               paui32ClientTAFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAUpdate,
+                                                                               ui32ClientTAUpdateCount,
+                                                                               apsClientTAUpdateSyncPrimBlock,
+                                                                               paui32ClientTAUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClientTAUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DFence,
+                                                                               ui32Client3DFenceCount,
+                                                                               apsClient3DFenceSyncPrimBlock,
+                                                                               paui32Client3DFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DUpdate,
+                                                                               ui32Client3DUpdateCount,
+                                                                               apsClient3DUpdateSyncPrimBlock,
+                                                                               paui32Client3DUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClient3DUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs;
+
+       eError = SyncPrimitiveBlockToFWAddr(psPRFenceSyncPrimBlock,
+                                                                       ui32PRFenceSyncOffset,
+                                                                       &uiPRFenceUFOAddress);
+
+       if(eError != PVRSRV_OK)
+       {
+               goto err_pr_fence_address;
+       }
+
+       /* Sanity check the server fences */
+       for (i=0;i<ui32ServerTASyncPrims;i++)
+       {
+               if (!(paui32ServerTASyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Server fence (on TA) must fence", __FUNCTION__));
+                       return PVRSRV_ERROR_INVALID_SYNC_PRIM_OP;
+               }
+       }
+
+       for (i=0;i<ui32Server3DSyncPrims;i++)
+       {
+               if (!(paui32Server3DSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Server fence (on 3D) must fence", __FUNCTION__));
+                       return PVRSRV_ERROR_INVALID_SYNC_PRIM_OP;
+               }
+       }
+
+       RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psRenderContext->psDeviceNode->pvDevice,
+                                 & pPreTimestamp,
+                                 & pPostTimestamp,
+                                 & pRMWUFOAddr);
+
+       /*
+               Sanity check we have a PR kick if there are client or server fences
+       */
+       if (!bKickPR & ((ui32Client3DFenceCount != 0) || (ui32Server3DSyncPrims != 0)))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: 3D fence (client or server) passed without a PR kick", __FUNCTION__));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       /* Init and acquire to TA command if required */
+       if(bKickTA)
+       {
+               RGX_SERVER_RC_TA_DATA *psTAData = &psRenderContext->sTAData;
+
+               ui32IntClientTAFenceCount = ui32ClientTAFenceCount;
+               pauiIntClientTAFenceUFOAddress = pauiClientTAFenceUFOAddress;
+               paui32IntClientTAFenceValue = paui32ClientTAFenceValue;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+               if (ui32NumCheckFenceFDs || i32UpdateFenceFD >= 0)
+               {
+                       /*
+                               This call is only using the Android fd sync to fence the
+                               TA command. There is an update but this is used to
+                               indicate that the fence has been finished with and so it
+                               can happen after the PR as by then we've finished using
+                               the fd sync
+                       */
+                       eError =
+                         pvr_sync_append_fences("TA",
+                                                ui32NumCheckFenceFDs,
+                                                ai32CheckFenceFDs,
+                                                                        i32UpdateFenceFD,
+                                                ui32NumUpdateSyncs,
+                                                puiUpdateFWAddrs,
+                                                pui32UpdateValues,
+                                                ui32IntClientTAFenceCount,
+                                                pauiIntClientTAFenceUFOAddress,
+                                                paui32IntClientTAFenceValue,
+                                                &psFDData);
+                       if (eError != PVRSRV_OK)
+                       {
+                           goto fail_fdsync;
+                       }
+                       pvr_sync_get_updates(psFDData, &ui32NumUpdateSyncs,
+                               &puiUpdateFWAddrs, &pui32UpdateValues);
+                       pvr_sync_get_checks(psFDData, &ui32IntClientTAFenceCount,
+                               &pauiIntClientTAFenceUFOAddress, &paui32IntClientTAFenceValue);
+               }
+#endif /* defined(SUPPORT_NATIVE_FENCE_SYNC) */
+
+               /* Init the TA command helper */
+               eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(psTAData->psServerCommonContext),
+                                               ui32IntClientTAFenceCount,
+                                               pauiIntClientTAFenceUFOAddress,
+                                               paui32IntClientTAFenceValue,
+                                               ui32ClientTAUpdateCount,
+                                               pauiClientTAUpdateUFOAddress,
+                                               paui32ClientTAUpdateValue,
+                                               ui32ServerTASyncPrims,
+                                               paui32ServerTASyncFlags,
+                                               pasServerTASyncs,
+                                               ui32TACmdSize,
+                                               pui8TADMCmd,
+                                               & pPreTimestamp,
+                                               (bKick3D ? IMG_NULL : & pPostTimestamp),
+                                               (bKick3D ? IMG_NULL : & pRMWUFOAddr),
+                                               RGXFWIF_CCB_CMD_TYPE_TA,
+                                               bPDumpContinuous,
+                                               "TA",
+                                               asTACmdHelperData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_tacmdinit;
+               }
+
+               eError = RGXCmdHelperAcquireCmdCCB(IMG_ARR_NUM_ELEMS(asTACmdHelperData),
+                                                  asTACmdHelperData,
+                                                  &bKickTADM);
+               if (eError != PVRSRV_OK)
+               {
+                       if (!bKickTADM)
+                       {
+                               goto fail_taacquirecmd;
+                       }
+                       else
+                       {
+                               /* commit the TA ref counting next time, when the CCB space is successfully
+                                * acquired
+                                */
+                               bCommitRefCountsTA = IMG_FALSE;
+                       }
+               }
+               else
+               {
+                       ui32TACmdCount++;
+               }
+       }
+
+       /* Only kick the 3D if required */
+       if (eError == PVRSRV_OK)
+       {
+       if (bKickPR)
+       {
+               RGX_SERVER_RC_3D_DATA *ps3DData = &psRenderContext->s3DData;
+
+               if (ui32Server3DSyncPrims)
+               {
+                       /*
+                               The fence (and possible update) straddle multiple commands so
+                               we have to modify the flags to do the right things at the right
+                               time.
+                               At this stage we should only fence, any updates will happen with
+                               the normal 3D command.
+                       */
+                       paui32Server3DSyncFlagsPR = OSAllocMem(sizeof(IMG_UINT32) * ui32Server3DSyncPrims);
+                       if (paui32Server3DSyncFlagsPR == IMG_NULL)
+                       {
+                               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                               goto fail_prserversyncflagsallocpr;
+                       }
+
+                       /* Copy only the fence flag across */
+                       for (i=0;i<ui32Server3DSyncPrims;i++)
+                       {
+                               paui32Server3DSyncFlagsPR[i] = paui32Server3DSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK;
+                       }
+               }
+
+               /*
+                       The command helper doesn't know about the PR fence so create
+                       the command with all the fences against it and later create
+                       the PR command itself which _must_ come after the PR fence.
+               */
+               sPRUFO.puiAddrUFO = uiPRFenceUFOAddress;
+               sPRUFO.ui32Value = ui32PRFenceValue;
+
+               /* Init the PR fence command helper */
+               eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext),
+                                                                               ui32Client3DFenceCount,
+                                                                               pauiClient3DFenceUFOAddress,
+                                                                               paui32Client3DFenceValue,
+                                                                               0,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               (bKick3D ? ui32Server3DSyncPrims : 0),
+                                                                               paui32Server3DSyncFlagsPR,
+                                                                               pasServer3DSyncs,
+                                                                               sizeof(sPRUFO),
+                                                                               (IMG_UINT8*) &sPRUFO,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               RGXFWIF_CCB_CMD_TYPE_FENCE_PR,
+                                                                               bPDumpContinuous,
+                                                                               "3D-PR-Fence",
+                                                                               &as3DCmdHelperData[ui323DCmdCount++]);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_prfencecmdinit;
+               }
+
+               /* Init the 3D PR command helper */
+               /*
+                       See note above PVRFDSyncQueryFencesKM as to why updates for android
+                       syncs are passed in with the PR
+               */
+               eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext),
+                                                                               0,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               ui32NumUpdateSyncs,
+                                                                               puiUpdateFWAddrs,
+                                                                               pui32UpdateValues,
+                                                                               0,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               ui323DPRCmdSize,
+                                                                               pui83DPRDMCmd,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               IMG_NULL,
+                                                                               RGXFWIF_CCB_CMD_TYPE_3D_PR,
+                                                                               bPDumpContinuous,
+                                                                               "3D-PR",
+                                                                               &as3DCmdHelperData[ui323DCmdCount++]);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_prcmdinit;
+               }
+       }
+
+       if (bKick3D || bAbort)
+       {
+               RGX_SERVER_RC_3D_DATA *ps3DData = &psRenderContext->s3DData;
+
+               if (ui32Server3DSyncPrims)
+               {
+                       /*
+                               Copy only the update flags for the 3D as the fences will be in
+                               the PR command created above
+                       */
+                       paui32Server3DSyncFlags3D = OSAllocMem(sizeof(IMG_UINT32) * ui32Server3DSyncPrims);
+                       if (paui32Server3DSyncFlags3D == IMG_NULL)
+                       {
+                               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                               goto fail_prserversyncflagsalloc3d;
+                       }
+
+                       /* Copy only the update flag across */
+                       for (i=0;i<ui32Server3DSyncPrims;i++)
+                       {
+                               paui32Server3DSyncFlags3D[i] = paui32Server3DSyncFlags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE;
+                       }
+               }
+
+               /* Init the 3D command helper */
+               eError = RGXCmdHelperInitCmdCCB(FWCommonContextGetClientCCB(ps3DData->psServerCommonContext),
+                                               0,
+                                               IMG_NULL,
+                                               IMG_NULL,
+                                               ui32Client3DUpdateCount,
+                                               pauiClient3DUpdateUFOAddress,
+                                               paui32Client3DUpdateValue,
+                                               ui32Server3DSyncPrims,
+                                               paui32Server3DSyncFlags3D,
+                                               pasServer3DSyncs,
+                                               ui323DCmdSize,
+                                               pui83DDMCmd,
+                                               (bKickTA ? IMG_NULL : & pPreTimestamp),
+                                               & pPostTimestamp,
+                                               & pRMWUFOAddr,
+                                               RGXFWIF_CCB_CMD_TYPE_3D,
+                                               bPDumpContinuous,
+                                               "3D",
+                                               &as3DCmdHelperData[ui323DCmdCount++]);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_3dcmdinit;
+               }
+       }
+
+       /* Protect against array overflow in RGXCmdHelperAcquireCmdCCB() */
+       if (ui323DCmdCount > IMG_ARR_NUM_ELEMS(as3DCmdHelperData))
+       {
+               goto fail_3dcmdinit;
+       }
+
+       if (ui323DCmdCount)
+       {
+               PVR_ASSERT(bKickPR || bKick3D);
+
+               /* Acquire space for all the 3D command(s) */
+               eError = RGXCmdHelperAcquireCmdCCB(ui323DCmdCount,
+                                                                                  as3DCmdHelperData,
+                                                                                  &bKick3DDM);
+               if (eError != PVRSRV_OK)
+               {
+                       /* If RGXCmdHelperAcquireCmdCCB fails we skip the scheduling
+                        * of a new TA command with the same Write offset in Kernel CCB.
+                        */
+                       goto fail_3dacquirecmd;
+               }
+       }
+       }
+
+       /*
+               We should acquire the space in the kernel CCB here as after this point
+               we release the commands which will take operations on server syncs
+               which can't be undone
+       */
+
+       /*
+               Everything is ready to go now, release the commands
+       */
+       if (ui32TACmdCount)
+       {
+               RGXCmdHelperReleaseCmdCCB(ui32TACmdCount,
+                                                                 asTACmdHelperData,
+                                                                 "TA",
+                                                                 FWCommonContextGetFWAddress(psRenderContext->sTAData.psServerCommonContext).ui32Addr);
+       }
+
+       if (ui323DCmdCount)
+       {
+               RGXCmdHelperReleaseCmdCCB(ui323DCmdCount,
+                                                                 as3DCmdHelperData,
+                                                                 "3D",
+                                                                 FWCommonContextGetFWAddress(psRenderContext->s3DData.psServerCommonContext).ui32Addr);
+       }
+
+       if (bKickTADM)
+       {
+               RGXFWIF_KCCB_CMD sTAKCCBCmd;
+
+               /* Construct the kernel TA CCB command. */
+               sTAKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+               sTAKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psRenderContext->sTAData.psServerCommonContext);
+               sTAKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->sTAData.psServerCommonContext));
+
+               if(bCommitRefCountsTA)
+               {
+                       AttachKickResourcesCleanupCtls((PRGXFWIF_CLEANUP_CTL *) &sTAKCCBCmd.uCmdData.sCmdKickData.apsCleanupCtl,
+                                                                               &sTAKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl,
+                                                                               RGXFWIF_DM_TA,
+                                                                               bKickTA,
+                                                                               psRTDataCleanup,
+                                                                               psZBuffer,
+                                                                               psSBuffer);
+                       *pbCommittedRefCountsTA = IMG_TRUE;
+               }
+               else
+               {
+                       sTAKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+               }
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError2 = RGXScheduleCommand(psRenderContext->psDeviceNode->pvDevice,
+                                                                               RGXFWIF_DM_TA,
+                                                                               &sTAKCCBCmd,
+                                                                               sizeof(sTAKCCBCmd),
+                                                                               bPDumpContinuous);
+                       if (eError2 != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+               RGXHWPerfFTraceGPUEnqueueEvent(psRenderContext->psDeviceNode->pvDevice,
+                               ui32ExtJobRef, ui32IntJobRef, "TA3D");
+#endif
+
+       }
+       
+       if (bKick3DDM)
+       {
+               RGXFWIF_KCCB_CMD s3DKCCBCmd;
+
+               /* Construct the kernel 3D CCB command. */
+               s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+               s3DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psRenderContext->s3DData.psServerCommonContext);
+               s3DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psRenderContext->s3DData.psServerCommonContext));
+
+               if(bCommitRefCounts3D)
+               {
+                       AttachKickResourcesCleanupCtls((PRGXFWIF_CLEANUP_CTL *) &s3DKCCBCmd.uCmdData.sCmdKickData.apsCleanupCtl,
+                                                                                       &s3DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl,
+                                                                                       RGXFWIF_DM_3D,
+                                                                                       bKick3D,
+                                                                                       psRTDataCleanup,
+                                                                                       psZBuffer,
+                                                                                       psSBuffer);
+                       *pbCommittedRefCounts3D = IMG_TRUE;
+               }
+               else
+               {
+                       s3DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+               }
+
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError2 = RGXScheduleCommand(psRenderContext->psDeviceNode->pvDevice,
+                                                                               RGXFWIF_DM_3D,
+                                                                               &s3DKCCBCmd,
+                                                                               sizeof(s3DKCCBCmd),
+                                                                               bPDumpContinuous);
+                       if (eError2 != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+       }
+
+       /*
+        * Now check eError (which may have returned an error from our earlier calls
+        * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first
+        * so we check it now...
+        */
+       if (eError != PVRSRV_OK )
+       {
+               goto fail_3dacquirecmd;
+       }
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#if defined(NO_HARDWARE)
+       pvr_sync_nohw_complete_fences(psFDData);
+#endif
+       pvr_sync_free_append_fences_data(psFDData);
+
+#endif
+       if(paui32Server3DSyncFlags3D)
+       {
+               OSFreeMem(paui32Server3DSyncFlags3D);
+       }
+
+       if(paui32Server3DSyncFlagsPR)
+       {
+               OSFreeMem(paui32Server3DSyncFlagsPR);
+       }
+
+       return PVRSRV_OK;
+
+fail_3dacquirecmd:
+fail_3dcmdinit:
+       if (paui32Server3DSyncFlags3D)
+       {
+               OSFreeMem(paui32Server3DSyncFlags3D);
+       }
+fail_prserversyncflagsalloc3d:
+fail_prcmdinit:
+fail_prfencecmdinit:
+       if (paui32Server3DSyncFlagsPR)
+       {
+               OSFreeMem(paui32Server3DSyncFlagsPR);
+       }
+fail_prserversyncflagsallocpr:
+fail_taacquirecmd:
+fail_tacmdinit:
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       pvr_sync_rollback_append_fences(psFDData);
+       pvr_sync_free_append_fences_data(psFDData);
+fail_fdsync:
+#endif
+err_pr_fence_address:
+err_populate_sync_addr_list:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXSetRenderContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                RGX_SERVER_RENDER_CONTEXT *psRenderContext,
+                                                                                                IMG_UINT32 ui32Priority)
+{
+       PVRSRV_ERROR eError;
+
+       if (psRenderContext->sTAData.ui32Priority != ui32Priority)
+       {
+               eError = ContextSetPriority(psRenderContext->sTAData.psServerCommonContext,
+                                                                       psConnection,
+                                                                       psRenderContext->psDeviceNode->pvDevice,
+                                                                       ui32Priority,
+                                                                       RGXFWIF_DM_TA);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the TA part of the rendercontext (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_tacontext;
+               }
+               psRenderContext->sTAData.ui32Priority = ui32Priority;
+       }
+
+       if (psRenderContext->s3DData.ui32Priority != ui32Priority)
+       {
+               eError = ContextSetPriority(psRenderContext->s3DData.psServerCommonContext,
+                                                                       psConnection,
+                                                                       psRenderContext->psDeviceNode->pvDevice,
+                                                                       ui32Priority,
+                                                                       RGXFWIF_DM_3D);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the 3D part of the rendercontext (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_3dcontext;
+               }
+               psRenderContext->s3DData.ui32Priority = ui32Priority;
+       }
+       return PVRSRV_OK;
+
+fail_3dcontext:
+fail_tacontext:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+/*
+ * PVRSRVRGXGetLastResetReason
+ */
+PVRSRV_ERROR PVRSRVRGXGetLastRenderContextResetReasonKM(RGX_SERVER_RENDER_CONTEXT      *psRenderContext,
+                                                        IMG_UINT32 *peLastResetReason)
+{
+       RGX_SERVER_RC_TA_DATA         *psRenderCtxTAData = &(psRenderContext->sTAData);
+       RGX_SERVER_COMMON_CONTEXT     *psCurrentServerTACommonCtx = psRenderCtxTAData->psServerCommonContext;
+       RGX_SERVER_RC_3D_DATA         *psRenderCtx3DData = &(psRenderContext->s3DData);
+       RGX_SERVER_COMMON_CONTEXT     *psCurrentServer3DCommonCtx = psRenderCtx3DData->psServerCommonContext;
+       RGXFWIF_CONTEXT_RESET_REASON  eLastTAResetReason, eLast3DResetReason;
+       
+       PVR_ASSERT(psRenderContext != IMG_NULL);
+       PVR_ASSERT(peLastResetReason != IMG_NULL);
+       
+       /* Get the last reset reasons from both the TA and 3D so they are reset... */
+       eLastTAResetReason = FWCommonContextGetLastResetReason(psCurrentServerTACommonCtx);
+       eLast3DResetReason = FWCommonContextGetLastResetReason(psCurrentServer3DCommonCtx);
+
+       /* Combine the reset reason from TA and 3D into one... */
+       *peLastResetReason = (IMG_UINT32) eLast3DResetReason;
+       if (eLast3DResetReason == RGXFWIF_CONTEXT_RESET_REASON_NONE  ||
+           ((eLast3DResetReason == RGXFWIF_CONTEXT_RESET_REASON_INNOCENT_LOCKUP  ||
+             eLast3DResetReason == RGXFWIF_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING)  &&
+            (eLastTAResetReason == RGXFWIF_CONTEXT_RESET_REASON_GUILTY_LOCKUP  ||
+             eLastTAResetReason == RGXFWIF_CONTEXT_RESET_REASON_GUILTY_OVERRUNING)))
+       {
+               *peLastResetReason = (IMG_UINT32) eLastTAResetReason;
+       }
+
+       return PVRSRV_OK;
+}
+
+
+/*
+ * PVRSRVRGXGetPartialRenderCountKM
+ */
+PVRSRV_ERROR PVRSRVRGXGetPartialRenderCountKM(DEVMEM_MEMDESC *psHWRTDataMemDesc,
+                                                                                         IMG_UINT32 *pui32NumPartialRenders)
+{
+       RGXFWIF_HWRTDATA *psHWRTData;
+       PVRSRV_ERROR eError;
+
+       eError = DevmemAcquireCpuVirtAddr(psHWRTDataMemDesc, (IMG_VOID **)&psHWRTData);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVRGXGetPartialRenderCountKM: Failed to map Firmware Render Target Data (%u)", eError));
+               return eError;
+       }
+
+       *pui32NumPartialRenders = psHWRTData->ui32NumPartialRenders;
+
+       DevmemReleaseCpuVirtAddr(psHWRTDataMemDesc);
+
+       return PVRSRV_OK;
+}
+
+
+static IMG_BOOL CheckForStalledRenderCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       RGX_SERVER_RENDER_CONTEXT               *psCurrentServerRenderCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_RENDER_CONTEXT, sListNode);
+       RGX_SERVER_RC_TA_DATA                   *psRenderCtxTAData = &(psCurrentServerRenderCtx->sTAData);
+       RGX_SERVER_COMMON_CONTEXT               *psCurrentServerTACommonCtx = psRenderCtxTAData->psServerCommonContext;
+       RGX_SERVER_RC_3D_DATA                   *psRenderCtx3DData = &(psCurrentServerRenderCtx->s3DData);
+       RGX_SERVER_COMMON_CONTEXT               *psCurrentServer3DCommonCtx = psRenderCtx3DData->psServerCommonContext;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = pvCallbackData;
+
+
+       DumpStalledFWCommonContext(psCurrentServerTACommonCtx, pfnDumpDebugPrintf);
+       DumpStalledFWCommonContext(psCurrentServer3DCommonCtx, pfnDumpDebugPrintf);
+
+       return IMG_TRUE;
+}
+IMG_VOID CheckForStalledRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                  DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       OSWRLockAcquireRead(psDevInfo->hRenderCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sRenderCtxtListHead),
+                                               CheckForStalledRenderCtxtCommand, pfnDumpDebugPrintf);
+       OSWRLockReleaseRead(psDevInfo->hRenderCtxListLock);
+}
+
+static IMG_BOOL CheckForStalledClientRenderCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       PVRSRV_ERROR *peError = (PVRSRV_ERROR*)pvCallbackData;
+       RGX_SERVER_RENDER_CONTEXT               *psCurrentServerRenderCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_RENDER_CONTEXT, sListNode);
+       RGX_SERVER_RC_TA_DATA                   *psRenderCtxTAData = &(psCurrentServerRenderCtx->sTAData);
+       RGX_SERVER_COMMON_CONTEXT               *psCurrentServerTACommonCtx = psRenderCtxTAData->psServerCommonContext;
+       RGX_SERVER_RC_3D_DATA                   *psRenderCtx3DData = &(psCurrentServerRenderCtx->s3DData);
+       RGX_SERVER_COMMON_CONTEXT               *psCurrentServer3DCommonCtx = psRenderCtx3DData->psServerCommonContext;
+
+       if (PVRSRV_ERROR_CCCB_STALLED == CheckStalledClientCommonContext(psCurrentServerTACommonCtx))
+       {
+               *peError = PVRSRV_ERROR_CCCB_STALLED;
+       }
+       if (PVRSRV_ERROR_CCCB_STALLED == CheckStalledClientCommonContext(psCurrentServer3DCommonCtx))
+       {
+               *peError = PVRSRV_ERROR_CCCB_STALLED;
+       }
+
+       return IMG_TRUE;
+}
+IMG_BOOL CheckForStalledClientRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       OSWRLockAcquireRead(psDevInfo->hRenderCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sRenderCtxtListHead),
+                                               CheckForStalledClientRenderCtxtCommand, &eError);
+       OSWRLockReleaseRead(psDevInfo->hRenderCtxListLock);
+       return (PVRSRV_ERROR_CCCB_STALLED == eError)? IMG_TRUE: IMG_FALSE;
+}
+
+IMG_EXPORT PVRSRV_ERROR 
+PVRSRVRGXKickSyncTAKM(RGX_SERVER_RENDER_CONTEXT  *psRenderContext,
+                       IMG_UINT32                  ui32TAClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsTAClientFenceSyncPrimBlock,
+                       IMG_UINT32                                      *paui32TAClientFenceSyncOffset,
+                       IMG_UINT32                  *paui32TAClientFenceValue,
+                       IMG_UINT32                  ui32TAClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsTAClientUpdateSyncPrimBlock,
+                       IMG_UINT32                                      *paui32TAClientUpdateSyncOffset,
+                       IMG_UINT32                  *paui32TAClientUpdateValue,
+                       IMG_UINT32                  ui32TAServerSyncPrimsCount,
+                       IMG_UINT32                  *paui32TAServerSyncFlags,
+                       SERVER_SYNC_PRIMITIVE       **pasTAServerSyncs,
+                                          IMG_UINT32                  ui323DClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK                            **aps3DClientFenceSyncPrimBlock,
+                       IMG_UINT32                                      *paui323DClientFenceSyncOffset,
+                                          IMG_UINT32                  *paui323DClientFenceValue,
+                                          IMG_UINT32                  ui323DClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK                            **aps3DClientUpdateSyncPrimBlock,
+                       IMG_UINT32                                      *paui323DClientUpdateSyncOffset,
+                                          IMG_UINT32                  *paui323DClientUpdateValue,
+                                          IMG_UINT32                  ui323DServerSyncPrimsCount,
+                                          IMG_UINT32                  *paui323DServerSyncFlags,
+                                          SERVER_SYNC_PRIMITIVE       **pas3DServerSyncs,
+                                          IMG_UINT32                              ui32NumFenceFDs,
+                                          IMG_INT32                               *pai32FenceFDs,
+                                          IMG_INT32                   i32UpdateFenceFD,
+                       IMG_BOOL                    bPDumpContinuous)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PRGXFWIF_UFO_ADDR                       *pauiTAClientFenceUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *pauiTAClientUpdateUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *paui3DClientFenceUFOAddress;
+       PRGXFWIF_UFO_ADDR                       *paui3DClientUpdateUFOAddress;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       /* Android fd sync update info */
+       struct pvr_sync_append_data *psFDData = NULL;
+#endif
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAFence,
+                                                                               ui32TAClientFenceCount,
+                                                                               apsTAClientFenceSyncPrimBlock,
+                                                                               paui32TAClientFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiTAClientFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAUpdate,
+                                                                               ui32TAClientUpdateCount,
+                                                                               apsTAClientUpdateSyncPrimBlock,
+                                                                               paui32TAClientUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiTAClientUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DFence,
+                                                                               ui323DClientFenceCount,
+                                                                               aps3DClientFenceSyncPrimBlock,
+                                                                               paui323DClientFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       paui3DClientFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DUpdate,
+                                                                               ui323DClientUpdateCount,
+                                                                               aps3DClientUpdateSyncPrimBlock,
+                                                                               paui323DClientUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       paui3DClientUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       /* Android FD fences are hardcoded to updates (IMG_TRUE below), Fences go to the TA and updates to the 3D */
+       if (ui32NumFenceFDs || i32UpdateFenceFD >= 0)
+       {
+               eError =
+               pvr_sync_append_fences("TA",
+                                                                         ui32NumFenceFDs,
+                                                                         pai32FenceFDs,
+                                                                         i32UpdateFenceFD,
+                                                                         ui323DClientUpdateCount,
+                                                                         paui3DClientUpdateUFOAddress,
+                                                                         paui323DClientUpdateValue,
+                                                                         ui323DClientFenceCount,
+                                                                         paui3DClientFenceUFOAddress,
+                                                                         paui323DClientFenceValue,
+                                                                         &psFDData);
+               if (eError != PVRSRV_OK)
+               {
+                   goto fail_fdsync;
+               }
+               pvr_sync_get_updates(psFDData, &ui323DClientUpdateCount,
+                       &paui3DClientUpdateUFOAddress, &paui323DClientUpdateValue);
+               pvr_sync_get_checks(psFDData, &ui323DClientFenceCount,
+                       &paui3DClientFenceUFOAddress, &paui323DClientFenceValue);
+       }
+#endif
+
+       /* send one command through the TA */
+       if ((ui32TAClientFenceCount + ui32TAClientUpdateCount + ui32TAServerSyncPrimsCount) > 0)
+       {
+               eError = RGXKickSyncKM(psRenderContext->psDeviceNode,
+                                    psRenderContext->sTAData.psServerCommonContext,
+                                    RGXFWIF_DM_TA,
+                                                        "SyncTA",
+                                    ui32TAClientFenceCount,
+                                    pauiTAClientFenceUFOAddress,
+                                    paui32TAClientFenceValue,
+                                    ui32TAClientUpdateCount,
+                                    pauiTAClientUpdateUFOAddress,
+                                    paui32TAClientUpdateValue,
+                                    ui32TAServerSyncPrimsCount,
+                                    paui32TAServerSyncFlags,
+                                    pasTAServerSyncs,
+                                    bPDumpContinuous);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to send TA sync command (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_kickTA;
+               }
+       }
+
+       /* and another one through the 3D */
+       if ((ui323DClientFenceCount + ui323DClientUpdateCount + ui323DServerSyncPrimsCount) > 0)
+       {
+               eError = RGXKickSyncKM(psRenderContext->psDeviceNode,
+                                    psRenderContext->s3DData.psServerCommonContext,
+                                    RGXFWIF_DM_3D,
+                                                        "Sync3D",
+                                    ui323DClientFenceCount,
+                                    paui3DClientFenceUFOAddress,
+                                    paui323DClientFenceValue,
+                                    ui323DClientUpdateCount,
+                                    paui3DClientUpdateUFOAddress,
+                                    paui323DClientUpdateValue,
+                                    ui323DServerSyncPrimsCount,
+                                    paui323DServerSyncFlags,
+                                    pas3DServerSyncs,
+                                    bPDumpContinuous);
+
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to send 3D sync command (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_kick3D;
+               }
+       }
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#if defined(NO_HARDWARE)
+       pvr_sync_nohw_complete_fences(psFDData);
+#endif
+       pvr_sync_free_append_fences_data(psFDData);
+#endif
+
+       return eError;
+
+fail_kick3D:
+fail_kickTA:
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       pvr_sync_rollback_append_fences(psFDData);
+       pvr_sync_free_append_fences_data(psFDData);
+fail_fdsync:
+#endif
+err_populate_sync_addr_list:
+       return eError;
+}
+/******************************************************************************
+ End of file (rgxta3d.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxta3d.h
new file mode 100644 (file)
index 0000000..8f93140
--- /dev/null
@@ -0,0 +1,478 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX TA and 3D Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX TA and 3D Functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXTA3D_H__)
+#define __RGXTA3D_H__
+
+#include "devicemem.h"
+#include "devicemem_server.h"
+#include "device.h"
+#include "rgxdevice.h"
+#include "rgx_fwif_shared.h"
+#include "rgx_fwif_resetframework.h"
+#include "sync_server.h"
+#include "connection_server.h"
+#include "rgxdebug.h"
+
+typedef struct _RGX_SERVER_RENDER_CONTEXT_ RGX_SERVER_RENDER_CONTEXT;
+typedef struct _RGX_FREELIST_ RGX_FREELIST;
+typedef struct _RGX_PMR_NODE_ RGX_PMR_NODE;
+
+typedef struct {
+       PVRSRV_DEVICE_NODE              *psDeviceNode;
+       DEVMEM_MEMDESC                  *psFWHWRTDataMemDesc;
+       DEVMEM_MEMDESC                  *psRTACtlMemDesc;
+       DEVMEM_MEMDESC                  *psRTArrayMemDesc;
+       DEVMEM_MEMDESC                  *psRendersAccArrayMemDesc;
+       RGX_FREELIST                    *apsFreeLists[RGXFW_MAX_FREELISTS];
+       PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync;
+} RGX_RTDATA_CLEANUP_DATA;
+
+struct _RGX_FREELIST_ {
+       PVRSRV_RGXDEV_INFO              *psDevInfo;
+
+       /* Free list PMR */
+       PMR                                             *psFreeListPMR;
+       IMG_DEVMEM_OFFSET_T             uiFreeListPMROffset;
+
+       /* Freelist config */
+       IMG_UINT32                              ui32MaxFLPages;
+       IMG_UINT32                              ui32InitFLPages;
+       IMG_UINT32                              ui32CurrentFLPages;
+       IMG_UINT32                              ui32GrowFLPages;
+       IMG_UINT32                              ui32FreelistID;
+       IMG_UINT64                              ui64FreelistChecksum;   /* checksum over freelist content */
+       IMG_BOOL                                bCheckFreelist;                 /* freelist check enabled */
+       IMG_UINT32                              ui32RefCount;                   /* freelist reference counting */
+
+       IMG_UINT32                              ui32NumGrowReqByApp;    /* Total number of grow requests by Application*/
+       IMG_UINT32                              ui32NumGrowReqByFW;             /* Total Number of grow requests by Firmware */
+       IMG_UINT32                              ui32NumHighPages;               /* High Mark of pages in the freelist */
+
+       IMG_PID                                 ownerPid;                       /* Pid of the owner of the list */
+
+       /* Memory Blocks */
+       DLLIST_NODE                             sMemoryBlockHead;
+       DLLIST_NODE                             sMemoryBlockInitHead;
+       DLLIST_NODE                             sNode;
+
+       /* FW data structures */
+       DEVMEM_MEMDESC                  *psFWFreelistMemDesc;
+       RGXFWIF_DEV_VIRTADDR    sFreeListFWDevVAddr;
+
+       PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync;
+} ;
+
+struct _RGX_PMR_NODE_ {
+       RGX_FREELIST                    *psFreeList;
+       PMR                                             *psPMR;
+       PMR_PAGELIST                    *psPageList;
+       DLLIST_NODE                             sMemoryBlock;
+       IMG_UINT32                              ui32NumPages;
+       IMG_BOOL                                bInternal;
+} ;
+
+typedef struct {
+       PVRSRV_DEVICE_NODE              *psDeviceNode;
+       DEVMEM_MEMDESC                  *psRenderTargetMemDesc;
+} RGX_RT_CLEANUP_DATA;
+
+typedef struct {
+       PVRSRV_RGXDEV_INFO              *psDevInfo;
+       DEVMEM_MEMDESC                  *psZSBufferMemDesc;
+       RGXFWIF_DEV_VIRTADDR    sZSBufferFWDevVAddr;
+
+       DEVMEMINT_RESERVATION   *psReservation;
+       PMR                                     *psPMR;
+       DEVMEMINT_MAPPING               *psMapping;
+       PVRSRV_MEMALLOCFLAGS_T  uiMapFlags;
+       IMG_UINT32                              ui32ZSBufferID;
+       IMG_UINT32                              ui32RefCount;
+       IMG_BOOL                                bOnDemand;
+
+       IMG_BOOL                                ui32NumReqByApp;                /* Number of Backing Requests from  Application */
+       IMG_BOOL                                ui32NumReqByFW;                 /* Number of Backing Requests from Firmware */
+
+       IMG_PID                                 owner;
+
+       DLLIST_NODE     sNode;
+
+       PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync;
+}RGX_ZSBUFFER_DATA;
+
+typedef struct {
+       RGX_ZSBUFFER_DATA               *psZSBuffer;
+} RGX_POPULATION;
+
+/* Dump the physical pages of a freelist */
+IMG_BOOL RGXDumpFreeListPageList(RGX_FREELIST *psFreeList);
+
+
+/* Create HWRTDataSet */
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateHWRTData(PVRSRV_DEVICE_NODE      *psDeviceNode, 
+                                                          IMG_UINT32                   psRenderTarget,
+                                                          IMG_DEV_VIRTADDR             psPMMListDevVAddr,
+                                                          IMG_DEV_VIRTADDR             psVFPPageTableAddr,
+                                                          RGX_FREELIST                 *apsFreeLists[RGXFW_MAX_FREELISTS],
+                                                          RGX_RTDATA_CLEANUP_DATA      **ppsCleanupData,
+                                                          DEVMEM_MEMDESC                       **ppsRTACtlMemDesc,
+                                                          IMG_UINT32           ui32PPPScreen,
+                                                          IMG_UINT32           ui32PPPGridOffset,
+                                                          IMG_UINT64           ui64PPPMultiSampleCtl,
+                                                          IMG_UINT32           ui32TPCStride,
+                                                          IMG_DEV_VIRTADDR             sTailPtrsDevVAddr,
+                                                          IMG_UINT32           ui32TPCSize,
+                                                          IMG_UINT32           ui32TEScreen,
+                                                          IMG_UINT32           ui32TEAA,
+                                                          IMG_UINT32           ui32TEMTILE1,
+                                                          IMG_UINT32           ui32TEMTILE2,
+                                                          IMG_UINT32           ui32MTileStride,
+                                                          IMG_UINT32                 ui32ISPMergeLowerX,
+                                                          IMG_UINT32                 ui32ISPMergeLowerY,
+                                                          IMG_UINT32                 ui32ISPMergeUpperX,
+                                                          IMG_UINT32                 ui32ISPMergeUpperY,
+                                                          IMG_UINT32                 ui32ISPMergeScaleX,
+                                                          IMG_UINT32                 ui32ISPMergeScaleY,
+                                                          IMG_UINT16                   ui16MaxRTs,
+                                                          DEVMEM_MEMDESC               **psMemDesc,
+                                                          IMG_UINT32                   *puiHWRTData);
+
+/* Destroy HWRTData */
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyHWRTData(RGX_RTDATA_CLEANUP_DATA *psCleanupData);
+
+/* Create Render Target */
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateRenderTarget(PVRSRV_DEVICE_NODE  *psDeviceNode,
+                                                                  IMG_DEV_VIRTADDR             psVHeapTableDevVAddr,
+                                                                  RGX_RT_CLEANUP_DATA  **ppsCleanupData,
+                                                                  IMG_UINT32                   *sRenderTargetFWDevVAddr);
+
+/* Destroy render target */
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyRenderTarget(RGX_RT_CLEANUP_DATA *psCleanupData);
+
+
+/*
+       RGXCreateZSBuffer
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateZSBufferKM(PVRSRV_DEVICE_NODE                            *psDeviceNode,
+                                                               DEVMEMINT_RESERVATION   *psReservation,
+                                                               PMR                                     *psPMR,
+                                                               PVRSRV_MEMALLOCFLAGS_T  uiMapFlags,
+                                                               RGX_ZSBUFFER_DATA                       **ppsZSBuffer,
+                                                               IMG_UINT32                                      *sRenderTargetFWDevVAddr);
+
+/*
+       RGXDestroyZSBuffer
+*/
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer);
+
+
+/*
+ * RGXBackingZSBuffer()
+ *
+ * Backs ZS-Buffer with physical pages
+ */
+PVRSRV_ERROR
+RGXBackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer);
+
+/*
+ * RGXPopulateZSBufferKM()
+ *
+ * Backs ZS-Buffer with physical pages (called by Bridge calls)
+ */
+IMG_EXPORT
+PVRSRV_ERROR RGXPopulateZSBufferKM(RGX_ZSBUFFER_DATA *psZSBuffer,
+                                                                       RGX_POPULATION **ppsPopulation);
+
+/*
+ * RGXUnbackingZSBuffer()
+ *
+ * Frees ZS-Buffer's physical pages
+ */
+IMG_EXPORT
+PVRSRV_ERROR RGXUnbackingZSBuffer(RGX_ZSBUFFER_DATA *psZSBuffer);
+
+/*
+ * RGXUnpopulateZSBufferKM()
+ *
+ * Frees ZS-Buffer's physical pages (called by Bridge calls )
+ */
+IMG_EXPORT
+PVRSRV_ERROR RGXUnpopulateZSBufferKM(RGX_POPULATION *psPopulation);
+
+/*
+       RGXProcessRequestZSBufferBacking
+*/
+IMG_EXPORT
+IMG_VOID RGXProcessRequestZSBufferBacking(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                               IMG_UINT32 ui32ZSBufferID);
+
+/*
+       RGXProcessRequestZSBufferUnbacking
+*/
+IMG_EXPORT
+IMG_VOID RGXProcessRequestZSBufferUnbacking(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                               IMG_UINT32 ui32ZSBufferID);
+
+/*
+       RGXGrowFreeList
+*/
+IMG_INTERNAL
+PVRSRV_ERROR RGXGrowFreeList(RGX_FREELIST *psFreeList,
+                                                                       IMG_UINT32 ui32NumPages,
+                                                                       PDLLIST_NODE pListHeader);
+
+/* Create free list */
+IMG_EXPORT
+PVRSRV_ERROR RGXCreateFreeList(PVRSRV_DEVICE_NODE      *psDeviceNode, 
+                                                          IMG_UINT32                   ui32MaxFLPages,
+                                                          IMG_UINT32                   ui32InitFLPages,
+                                                          IMG_UINT32                   ui32GrowFLPages,
+                                                          IMG_BOOL                             bCheckFreelist,
+                                                          IMG_DEV_VIRTADDR             sFreeListDevVAddr,
+                                                          PMR                                  *psFreeListPMR,
+                                                          IMG_DEVMEM_OFFSET_T  uiFreeListPMROffset,
+                                                          RGX_FREELIST                 **ppsFreeList);
+
+/* Destroy free list */
+IMG_EXPORT
+PVRSRV_ERROR RGXDestroyFreeList(RGX_FREELIST *psFreeList);
+
+/*
+       RGXProcessRequestGrow
+*/
+IMG_EXPORT
+IMG_VOID RGXProcessRequestGrow(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               IMG_UINT32 ui32FreelistID);
+
+
+/* Grow free list */
+IMG_EXPORT
+PVRSRV_ERROR RGXAddBlockToFreeListKM(RGX_FREELIST *psFreeList,
+                                                                               IMG_UINT32 ui32NumPages);
+
+/* Shrink free list */
+IMG_EXPORT
+PVRSRV_ERROR RGXRemoveBlockFromFreeListKM(RGX_FREELIST *psFreeList);
+
+
+/* Reconstruct free list after Hardware Recovery */
+IMG_VOID RGXProcessRequestFreelistsReconstruction(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                               RGXFWIF_DM eDM,
+                                                               IMG_UINT32 ui32FreelistsCount,
+                                                               IMG_UINT32 *paui32Freelists);
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXCreateRenderContextKM
+
+ @Description
+       Server-side implementation of RGXCreateRenderContext
+
+ @Input pvDeviceNode - device node
+ @Input psTACCBMemDesc - TA CCB Memory descriptor
+ @Input psTACCBCtlMemDesc - TA CCB Ctrl Memory descriptor
+ @Input ps3DCCBMemDesc - 3D CCB Memory descriptor
+ @Input ps3DCCBCtlMemDesc - 3D CCB Ctrl Memory descriptor
+ @Input ui32Priority - context priority
+ @Input sMCUFenceAddr - MCU Fence device virtual address
+ @Input psVDMStackPointer - VDM call stack device virtual address
+ @Input ui32FrameworkRegisterSize - framework register size
+ @Input pbyFrameworkRegisters - ptr to framework register
+ @Input hMemCtxPrivData - memory context private data
+ @Output ppsCleanupData - clean up data
+ @Output ppsFWRenderContextMemDesc - firmware render context memory descriptor
+ @Output ppsFWContextStateMemDesc - firmware context state memory descriptor
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateRenderContextKM(CONNECTION_DATA                            *psConnection,
+                                                                                       PVRSRV_DEVICE_NODE                      *psDeviceNode,
+                                                                                       IMG_UINT32                                      ui32Priority,
+                                                                                       IMG_DEV_VIRTADDR                        sMCUFenceAddr,
+                                                                                       IMG_DEV_VIRTADDR                        sVDMCallStackAddr,
+                                                                                       IMG_UINT32                                      ui32FrameworkCommandSize,
+                                                                                       IMG_PBYTE                                       pabyFrameworkCommand,
+                                                                                       IMG_HANDLE                                      hMemCtxPrivData,
+                                                                                       RGX_SERVER_RENDER_CONTEXT       **ppsRenderContext);
+
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXDestroyRenderContextKM
+
+ @Description
+       Server-side implementation of RGXDestroyRenderContext
+
+ @Input psCleanupData - clean up data
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext);
+
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXKickTA3DKM
+
+ @Description
+       Server-side implementation of RGXKickTA3D
+
+ @Input psRTDataCleanup - RT data associated with the kick (or NULL)
+ @Input psZBuffer - Z-buffer associated with the kick (or NULL)
+ @Input psSBuffer - S-buffer associated with the kick (or NULL)
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT     *psRenderContext,
+                                                                IMG_UINT32                                     ui32ClientTAFenceCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClientTAFenceSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32ClientTAFenceSyncOffset,
+                                                                IMG_UINT32                                     *paui32ClientTAFenceValue,
+                                                                IMG_UINT32                                     ui32ClientTAUpdateCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClientUpdateSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32ClientUpdateSyncOffset,
+                                                                IMG_UINT32                                     *paui32ClientTAUpdateValue,
+                                                                IMG_UINT32                                     ui32ServerTASyncPrims,
+                                                                IMG_UINT32                                     *paui32ServerTASyncFlags,
+                                                                SERVER_SYNC_PRIMITIVE          **pasServerTASyncs,
+                                                                IMG_UINT32                                     ui32Client3DFenceCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClient3DFenceSyncPrimBlock,
+                                                                IMG_UINT32                                     *pauiClient3DFenceSyncOffset,
+                                                                IMG_UINT32                                     *paui32Client3DFenceValue,
+                                                                IMG_UINT32                                     ui32Client3DUpdateCount,
+                                                                SYNC_PRIMITIVE_BLOCK                           **apsClient3DUpdateSyncPrimBlock,
+                                                                IMG_UINT32                                     *paui32Client3DUpdateSyncOffset,
+                                                                IMG_UINT32                                     *paui32Client3DUpdateValue,
+                                                                IMG_UINT32                                     ui32Server3DSyncPrims,
+                                                                IMG_UINT32                                     *paui32Server3DSyncFlags,
+                                                                SERVER_SYNC_PRIMITIVE          **pasServer3DSyncs,
+                                                                SYNC_PRIMITIVE_BLOCK                           *psPRSyncPrimBlock,
+                                                                IMG_UINT32                                     ui32PRSyncOffset,
+                                                                IMG_UINT32                                     ui32PRFenceValue,
+                                                                IMG_UINT32                                     ui32NumCheckFenceFDs,
+                                                                IMG_INT32                                      *pai32CheckFenceFDs,
+                                                                IMG_INT32                  i32UpdateFenceFD,
+                                                                IMG_UINT32                                     ui32TACmdSize,
+                                                                IMG_PBYTE                                      pui8TADMCmd,
+                                                                IMG_UINT32                                     ui323DPRCmdSize,
+                                                                IMG_PBYTE                                      pui83DPRDMCmd,
+                                                                IMG_UINT32                                     ui323DCmdSize,
+                                                                IMG_PBYTE                                      pui83DDMCmd,
+                                                                IMG_UINT32                                     TAFrameNum,
+                                                                IMG_UINT32                                     TARTData,
+                                                                IMG_BOOL                                       bLastTAInScene,
+                                                                IMG_BOOL                                       bKickTA,
+                                                                IMG_BOOL                                       bKickPR,
+                                                                IMG_BOOL                                       bKick3D,
+                                                                IMG_BOOL                                       bAbort,
+                                                                IMG_BOOL                                       bPDumpContinuous,
+                                                                RGX_RTDATA_CLEANUP_DATA        *psRTDataCleanup,
+                                                                RGX_ZSBUFFER_DATA              *psZBuffer,
+                                                                RGX_ZSBUFFER_DATA              *psSBuffer,
+                                                                IMG_BOOL                       bCommitRefCountsTA,
+                                                                IMG_BOOL                       bCommitRefCounts3D,
+                                                                IMG_BOOL                       *pbCommittedRefCountsTA,
+                                                                IMG_BOOL                       *pbCommittedRefCounts3D);
+
+PVRSRV_ERROR PVRSRVRGXSetRenderContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                RGX_SERVER_RENDER_CONTEXT *psRenderContext,
+                                                                                                IMG_UINT32 ui32Priority);
+
+PVRSRV_ERROR PVRSRVRGXGetLastRenderContextResetReasonKM(RGX_SERVER_RENDER_CONTEXT      *psRenderContext,
+                                                        IMG_UINT32 *peLastResetReason);
+
+PVRSRV_ERROR PVRSRVRGXGetPartialRenderCountKM(DEVMEM_MEMDESC *psHWRTDataMemDesc,
+                                                                                         IMG_UINT32 *pui32NumPartialRenders);
+
+/* Debug - check if render context is waiting on a fence */
+IMG_VOID CheckForStalledRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                  DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/* Debug/Watchdog - check if client contexts are stalled */
+IMG_BOOL CheckForStalledClientRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXKickSyncTAKM(RGX_SERVER_RENDER_CONTEXT  *psRenderContext,
+                       IMG_UINT32                  ui32TAClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsClientTAFenceSyncPrimBlock,
+                       IMG_UINT32                                      *paui32ClientTAFenceSyncOffset,
+                       IMG_UINT32                  *paui32TAClientFenceValue,
+                       IMG_UINT32                  ui32TAClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsClientTAUpdateSyncPrimBlock,
+                       IMG_UINT32                                      *paui32ClientTAUpdateSyncOffset,
+                       IMG_UINT32                  *paui32TAClientUpdateValue,
+                       IMG_UINT32                  ui32TAServerSyncPrimsCount,
+                       IMG_UINT32                  *paui32TAServerSyncFlags,
+                       SERVER_SYNC_PRIMITIVE       **pasTAServerSyncs,
+                                          IMG_UINT32                  ui323DClientFenceCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsClient3DFenceSyncPrimBlock,
+                       IMG_UINT32                                      *paui32Client3DFenceSyncOffset,
+                                          IMG_UINT32                  *paui323DClientFenceValue,
+                                          IMG_UINT32                  ui323DClientUpdateCount,
+                       SYNC_PRIMITIVE_BLOCK                            **apsClient3DUpdateSyncPrimBlock,
+                       IMG_UINT32                                      *paui32Client3DUpdateSyncOffset,
+                                          IMG_UINT32                  *paui323DClientUpdateValue,
+                                          IMG_UINT32                  ui323DServerSyncPrims,
+                                          IMG_UINT32                  *paui323DServerSyncFlags,
+                                          SERVER_SYNC_PRIMITIVE       **pas3DServerSyncs,
+                                          IMG_UINT32                              ui32NumFenceFDs,
+                                          IMG_INT32                               *pai32FenceFDs,
+                                          IMG_INT32                   i32UpdateFenceFD,
+                       IMG_BOOL                    bPDumpContinuous);
+
+#endif /* __RGXTA3D_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.c
new file mode 100644 (file)
index 0000000..567f2f6
--- /dev/null
@@ -0,0 +1,306 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific time correlation and calibration routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific time correlation and calibration routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "rgxtimecorr.h"
+#include "rgxfwutils.h"
+
+/******************************************************************************
+ *
+ * - A calibration period is started on power-on and after a DVFS transition,
+ *   and it's closed before a power-off and before a DVFS transition
+ *   (so power-on -> dfvs -> dvfs -> power-off , power on -> dvfs -> dvfs...,
+ *   where each arrow is a calibration period)
+ *
+ * - The timers on the Host and on the FW are correlated at the beginning of
+ *   each period together with the (possibly calibrated) current GPU frequency
+ *
+ * - If the frequency has not changed since the last power-off/on sequence or
+ *   before/after a DVFS transition (-> the transition didn't really happen)
+ *   then multiple consecutive periods are merged (the higher the numbers the
+ *   better the accuracy in the computed clock speed)
+ *
+ * - Correlation and calibration are also done more or less periodically
+ *   (using a best effort approach)
+ *
+ *****************************************************************************/
+
+static IMG_VOID _RGXMakeTimeCorrData(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+       PVRSRV_RGXDEV_INFO    *psDevInfo     = psDeviceNode->pvDevice;
+       RGXFWIF_GPU_UTIL_FWCB *psGpuUtilFWCB = psDevInfo->psRGXFWIfGpuUtilFWCb;
+       RGX_GPU_DVFS_TABLE    *psGpuDVFSTable = psDevInfo->psGpuDVFSTable;
+       RGXFWIF_TIME_CORR     *psTimeCorr;
+       IMG_UINT32            ui32NewSeqCount;
+       IMG_UINT32            ui32CoreClockSpeed;
+       IMG_UINT32            ui32Remainder;
+
+       ui32CoreClockSpeed = psGpuDVFSTable->aui32DVFSClock[psGpuDVFSTable->ui32CurrentDVFSId];
+
+       ui32NewSeqCount = psGpuUtilFWCB->ui32TimeCorrSeqCount + 1;
+       psTimeCorr = &psGpuUtilFWCB->sTimeCorr[RGXFWIF_TIME_CORR_CURR_INDEX(ui32NewSeqCount)];
+
+       psTimeCorr->ui64CRTimeStamp    = RGXReadHWTimerReg(psDevInfo);
+       psTimeCorr->ui64OSTimeStamp    = OSClockns64();
+       psTimeCorr->ui32CoreClockSpeed = ui32CoreClockSpeed;
+       psTimeCorr->ui32CRDeltaToOSDeltaKNs =
+           RGXFWIF_GET_CRDELTA_TO_OSDELTA_K_NS(ui32CoreClockSpeed, ui32Remainder);
+
+       /* Make sure the values are written to memory before updating the index of the current entry */
+       OSWriteMemoryBarrier();
+
+       /* Update the index of the current entry in the timer correlation array */
+       psGpuUtilFWCB->ui32TimeCorrSeqCount = ui32NewSeqCount;
+
+       PVR_DPF((PVR_DBG_MESSAGE,"RGXMakeTimeCorrData: Correlated OS timestamp %llu (ns) with CR timestamp %llu, GPU clock speed %uHz",
+                psTimeCorr->ui64OSTimeStamp, psTimeCorr->ui64CRTimeStamp, psTimeCorr->ui32CoreClockSpeed));
+}
+
+
+static IMG_VOID _RGXGPUFreqCalibrationPeriodStart(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_GPU_DVFS_TABLE *psGpuDVFSTable)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo         = psDeviceNode->pvDevice;
+       RGX_DATA           *psRGXData         = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
+       IMG_UINT32         ui32CoreClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
+       IMG_UINT32         ui32Index          = RGX_GPU_DVFS_GET_INDEX(ui32CoreClockSpeed);
+
+       IMG_UINT64 ui64CRTimestamp = RGXReadHWTimerReg(psDevInfo);
+       IMG_UINT64 ui64OSTimestamp = OSClockus64();
+
+       psGpuDVFSTable->ui64CalibrationCRTimestamp = ui64CRTimestamp;
+       psGpuDVFSTable->ui64CalibrationOSTimestamp = ui64OSTimestamp;
+
+       /* Set the time needed to (re)calibrate the GPU frequency */
+       if((psGpuDVFSTable->aui32DVFSClock[ui32Index] == 0) ||                /* We never met this frequency */
+          (psGpuDVFSTable->aui32DVFSClock[ui32Index] == ui32CoreClockSpeed)) /* We weren't able to calibrate this frequency previously */
+       {
+               psGpuDVFSTable->aui32DVFSClock[ui32Index] = ui32CoreClockSpeed;
+               psGpuDVFSTable->ui32CalibrationPeriod     = RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US;
+
+               PVR_DPF((PVR_DBG_MESSAGE, "RGXGPUFreqCalibrationStart: using uncalibrated GPU frequency %u", ui32CoreClockSpeed));
+       }
+       else if(psGpuDVFSTable->ui32CalibrationPeriod == RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US)
+       {
+               psGpuDVFSTable->ui32CalibrationPeriod = RGX_GPU_DVFS_TRANSITION_CALIBRATION_TIME_US;
+       }
+       else
+       {
+               psGpuDVFSTable->ui32CalibrationPeriod = RGX_GPU_DVFS_PERIODIC_CALIBRATION_TIME_US;
+       }
+
+       /* Update the index to the DVFS table */
+       psGpuDVFSTable->ui32CurrentDVFSId = ui32Index;
+}
+
+
+static IMG_VOID _RGXGPUFreqCalibrationPeriodStop(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_GPU_DVFS_TABLE *psGpuDVFSTable)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+       IMG_UINT64 ui64CRTimestamp = RGXReadHWTimerReg(psDevInfo);
+       IMG_UINT64 ui64OSTimestamp = OSClockus64();
+
+       if(!psGpuDVFSTable->bAccumulatePeriod)
+       {
+               psGpuDVFSTable->ui64CalibrationCRTimediff = 0;
+               psGpuDVFSTable->ui64CalibrationOSTimediff = 0;
+       }
+
+       psGpuDVFSTable->ui64CalibrationCRTimediff += ui64CRTimestamp - psGpuDVFSTable->ui64CalibrationCRTimestamp;
+       psGpuDVFSTable->ui64CalibrationOSTimediff += ui64OSTimestamp - psGpuDVFSTable->ui64CalibrationOSTimestamp;
+}
+
+
+static IMG_UINT32 _RGXGPUFreqCalibrationCalculate(PVRSRV_DEVICE_NODE *psDeviceNode, RGX_GPU_DVFS_TABLE *psGpuDVFSTable)
+{
+       IMG_UINT32 ui32CalibratedClockSpeed;
+       IMG_UINT32 ui32Remainder;
+
+       ui32CalibratedClockSpeed =
+           RGXFWIF_GET_GPU_CLOCK_FREQUENCY_HZ(psGpuDVFSTable->ui64CalibrationCRTimediff, psGpuDVFSTable->ui64CalibrationOSTimediff, ui32Remainder);
+
+       PVR_DPF((PVR_DBG_MESSAGE, "GPU frequency calibration: %u -> %u done over %llu us",
+                psGpuDVFSTable->aui32DVFSClock[psGpuDVFSTable->ui32CurrentDVFSId],
+                ui32CalibratedClockSpeed,
+                psGpuDVFSTable->ui64CalibrationOSTimediff));
+
+       psGpuDVFSTable->aui32DVFSClock[psGpuDVFSTable->ui32CurrentDVFSId] = ui32CalibratedClockSpeed;
+
+       return ui32CalibratedClockSpeed;
+}
+
+
+/*
+       RGXGPUFreqCalibratePrePowerState
+*/
+IMG_VOID RGXGPUFreqCalibratePrePowerState(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_DEVICE_NODE  *psDeviceNode   = hDevHandle;
+       PVRSRV_RGXDEV_INFO  *psDevInfo      = psDeviceNode->pvDevice;
+       RGX_GPU_DVFS_TABLE  *psGpuDVFSTable = psDevInfo->psGpuDVFSTable;
+
+       _RGXGPUFreqCalibrationPeriodStop(psDeviceNode, psGpuDVFSTable);
+
+       if(psGpuDVFSTable->ui64CalibrationOSTimediff >= psGpuDVFSTable->ui32CalibrationPeriod)
+       {
+               _RGXGPUFreqCalibrationCalculate(psDeviceNode, psGpuDVFSTable);
+       }
+}
+
+
+/*
+       RGXGPUFreqCalibratePostPowerState
+*/
+IMG_VOID RGXGPUFreqCalibratePostPowerState(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_DEVICE_NODE  *psDeviceNode      = hDevHandle;
+       PVRSRV_RGXDEV_INFO  *psDevInfo         = psDeviceNode->pvDevice;
+       RGX_GPU_DVFS_TABLE  *psGpuDVFSTable    = psDevInfo->psGpuDVFSTable;
+       RGX_DATA            *psRGXData         = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
+       IMG_UINT32          ui32CoreClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
+
+       /* If the frequency hasn't changed then accumulate the time diffs to get a better result */
+       psGpuDVFSTable->bAccumulatePeriod = (RGX_GPU_DVFS_GET_INDEX(ui32CoreClockSpeed) == psGpuDVFSTable->ui32CurrentDVFSId);
+
+       _RGXGPUFreqCalibrationPeriodStart(psDeviceNode, psGpuDVFSTable);
+
+       /* Update the timer correlation data */
+       _RGXMakeTimeCorrData(psDeviceNode);
+}
+
+
+/*
+       RGXGPUFreqCalibratePreClockSpeedChange
+*/
+IMG_VOID RGXGPUFreqCalibratePreClockSpeedChange(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_DEVICE_NODE  *psDeviceNode   = hDevHandle;
+       PVRSRV_RGXDEV_INFO  *psDevInfo      = psDeviceNode->pvDevice;
+       RGX_GPU_DVFS_TABLE  *psGpuDVFSTable = psDevInfo->psGpuDVFSTable;
+
+       _RGXGPUFreqCalibrationPeriodStop(psDeviceNode, psGpuDVFSTable);
+
+       /* Wait until RGXPostClockSpeedChange() to do anything as the GPU frequency may be left
+        * unchanged (in that case we delay calibration/correlation to get a better result later) */
+}
+
+
+/*
+       RGXGPUFreqCalibratePostClockSpeedChange
+*/
+IMG_UINT32 RGXGPUFreqCalibratePostClockSpeedChange(IMG_HANDLE hDevHandle, IMG_UINT32 ui32NewClockSpeed)
+{
+       PVRSRV_DEVICE_NODE  *psDeviceNode          = hDevHandle;
+       PVRSRV_RGXDEV_INFO  *psDevInfo             = psDeviceNode->pvDevice;
+       RGX_GPU_DVFS_TABLE  *psGpuDVFSTable        = psDevInfo->psGpuDVFSTable;
+       IMG_UINT32          ui32ReturnedClockSpeed = ui32NewClockSpeed;
+
+       if(RGX_GPU_DVFS_GET_INDEX(ui32NewClockSpeed) != psGpuDVFSTable->ui32CurrentDVFSId)
+       {
+               /* Only calibrate if the last period was long enough */
+               if(psGpuDVFSTable->ui64CalibrationOSTimediff >= RGX_GPU_DVFS_TRANSITION_CALIBRATION_TIME_US)
+               {
+                       ui32ReturnedClockSpeed = _RGXGPUFreqCalibrationCalculate(psDeviceNode, psGpuDVFSTable);
+               }
+
+               _RGXGPUFreqCalibrationPeriodStart(psDeviceNode, psGpuDVFSTable);
+
+               /* Update the timer correlation data */
+               _RGXMakeTimeCorrData(psDeviceNode);
+
+               psGpuDVFSTable->bAccumulatePeriod = IMG_FALSE;
+       }
+       else
+       {
+               psGpuDVFSTable->bAccumulatePeriod = IMG_TRUE;
+       }
+
+       return ui32ReturnedClockSpeed;
+}
+
+
+/*
+       RGXGPUFreqCalibrateCorrelatePeriodic
+*/
+IMG_VOID RGXGPUFreqCalibrateCorrelatePeriodic(IMG_HANDLE hDevHandle)
+{
+       PVRSRV_DEVICE_NODE     *psDeviceNode   = hDevHandle;
+       PVRSRV_RGXDEV_INFO     *psDevInfo      = psDeviceNode->pvDevice;
+       RGX_GPU_DVFS_TABLE     *psGpuDVFSTable = psDevInfo->psGpuDVFSTable;
+       PVRSRV_DATA            *psPVRSRVData;
+       IMG_UINT64             ui64TimeNow     = OSClockus64();
+       PVRSRV_DEV_POWER_STATE ePowerState;
+
+       /* Check if it's the right time to recalibrate the GPU clock frequency */
+       if((ui64TimeNow - psGpuDVFSTable->ui64CalibrationOSTimestamp) < psGpuDVFSTable->ui32CalibrationPeriod) return;
+
+       /* Try to acquire the powerlock, if not possible then don't wait */
+       psPVRSRVData     = PVRSRVGetPVRSRVData();
+       if (OSLockIsLocked(psPVRSRVData->hPowerLock)) return; /* Better to not wait here if possible */
+       /* There's a chance that the powerlock could be taken here, it's not that bad even if not desirable
+          (TODO use OSTryLockAcquire, currently implemented under Linux only) */
+       if (PVRSRVPowerLock() != PVRSRV_OK) return;
+
+       /* If the GPU is off then we can't do anything */
+       PVRSRVGetDevicePowerState(psDeviceNode->sDevId.ui32DeviceIndex, &ePowerState);
+       if (ePowerState != PVRSRV_DEV_POWER_STATE_ON)
+       {
+               PVRSRVPowerUnlock();
+               return;
+       }
+
+       /* All checks passed, we can calibrate and correlate */
+       _RGXGPUFreqCalibrationPeriodStop(psDeviceNode, psGpuDVFSTable);
+       _RGXGPUFreqCalibrationCalculate(psDeviceNode, psGpuDVFSTable);
+       _RGXGPUFreqCalibrationPeriodStart(psDeviceNode, psGpuDVFSTable);
+       _RGXMakeTimeCorrData(psDeviceNode);
+
+       /* Force Accumulate Period to false to not trigger a periodic calibration over and over again */
+       psGpuDVFSTable->bAccumulatePeriod = IMG_FALSE;
+
+       PVRSRVPowerUnlock();
+}
+
+
+/******************************************************************************
+ End of file (rgxtimecorr.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimecorr.h
new file mode 100644 (file)
index 0000000..da40189
--- /dev/null
@@ -0,0 +1,125 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX time correlation and calibration header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX time correlation and calibration routines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXTIMECORR_H__)
+#define __RGXTIMECORR_H__
+
+#include "img_types.h"
+
+/*!
+******************************************************************************
+
+ @Function    RGXGPUFreqCalibratePrePowerState
+
+ @Description Manage GPU frequency and timer correlation data
+              before a power off.
+
+ @Input       hDevHandle : RGX Device Node
+
+ @Return      IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXGPUFreqCalibratePrePowerState(IMG_HANDLE hDevHandle);
+
+/*!
+******************************************************************************
+
+ @Function    RGXGPUFreqCalibratePostPowerState
+
+ @Description Manage GPU frequency and timer correlation data
+              after a power on.
+
+ @Input       hDevHandle : RGX Device Node
+
+ @Return      IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXGPUFreqCalibratePostPowerState(IMG_HANDLE hDevHandle);
+
+/*!
+******************************************************************************
+
+ @Function    RGXGPUFreqCalibratePreClockSpeedChange
+
+ @Description Manage GPU frequency and timer correlation data
+              before a DVFS transition.
+
+ @Input       hDevHandle : RGX Device Node
+
+ @Return      IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXGPUFreqCalibratePreClockSpeedChange(IMG_HANDLE hDevHandle);
+
+/*!
+******************************************************************************
+
+ @Function    RGXGPUFreqCalibratePostClockSpeedChange
+
+ @Description Manage GPU frequency and timer correlation data
+              after a DVFS transition.
+
+ @Input       hDevHandle        : RGX Device Node
+ @Input       ui32NewClockSpeed : GPU clock speed after the DVFS transition
+
+ @Return      IMG_UINT32 : Calibrated GPU clock speed after the DVFS transition
+
+******************************************************************************/
+IMG_UINT32 RGXGPUFreqCalibratePostClockSpeedChange(IMG_HANDLE hDevHandle, IMG_UINT32 ui32NewClockSpeed);
+
+/*!
+******************************************************************************
+
+ @Function    RGXGPUFreqCalibratePeriodic
+
+ @Description Calibrate the GPU clock speed and correlate the timers
+              at regular intervals.
+
+ @Input       hDevHandle : RGX Device Node
+
+ @Return      IMG_VOID
+
+******************************************************************************/
+IMG_VOID RGXGPUFreqCalibrateCorrelatePeriodic(IMG_HANDLE hDevHandle);
+
+#endif /* __RGXTIMECORR_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.c
new file mode 100644 (file)
index 0000000..2d822cc
--- /dev/null
@@ -0,0 +1,243 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Timer queries
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    RGX Timer queries
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "rgxtimerquery.h"
+#include "rgxdevice.h"
+
+#include "rgxfwutils.h"
+#include "pdump_km.h"
+
+PVRSRV_ERROR
+PVRSRVRGXBeginTimerQueryKM(PVRSRV_DEVICE_NODE * psDeviceNode,
+                           IMG_UINT32         ui32QueryId)
+{
+       PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice;
+
+       if (ui32QueryId >= RGX_MAX_TIMER_QUERIES)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psDevInfo->bSaveStart = IMG_TRUE;
+       psDevInfo->bSaveEnd   = IMG_TRUE;
+
+       /* clear the stamps, in case there is no Kick */
+       psDevInfo->pasStartTimeById[ui32QueryId].ui64Timestamp = 0UL;
+       psDevInfo->pasEndTimeById[ui32QueryId].ui64Timestamp   = 0UL;
+
+       /* save of the active query index */
+       psDevInfo->ui32ActiveQueryId = ui32QueryId;
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+PVRSRVRGXEndTimerQueryKM(PVRSRV_DEVICE_NODE * psDeviceNode)
+{
+       PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice;
+
+       /* clear off the flags set by Begin(). Note that _START_TIME is
+        * probably already cleared by Kick()
+        */
+       psDevInfo->bSaveStart = IMG_FALSE;
+       psDevInfo->bSaveEnd   = IMG_FALSE;
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+PVRSRVRGXQueryTimerKM(PVRSRV_DEVICE_NODE * psDeviceNode,
+                      IMG_UINT32         ui32QueryId,
+                      IMG_UINT64         * pui64StartTime,
+                      IMG_UINT64         * pui64EndTime)
+{
+       PVRSRV_RGXDEV_INFO * psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice;
+       IMG_UINT32         ui32Scheduled;
+       IMG_UINT32         ui32Completed;
+
+       if (ui32QueryId >= RGX_MAX_TIMER_QUERIES)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       ui32Scheduled = psDevInfo->aui32ScheduledOnId[ui32QueryId];
+       ui32Completed = psDevInfo->pui32CompletedById[ui32QueryId];
+
+       /* if there was no kick since the Begin() on this id we return 0-s as Begin cleared
+        * the stamps. If there was no begin the returned data is undefined - but still
+        * safe from services pov
+        */
+       if (ui32Completed >= ui32Scheduled)
+       {
+               RGXFWIF_TIMESTAMP * psTimestamp;
+               RGXFWIF_TIME_CORR * psTimeCorr;
+               IMG_UINT64        ui64CRTimeDiff;
+
+               psTimestamp = &psDevInfo->pasStartTimeById[ui32QueryId];
+
+               /* If the start time is 0 then don't attempt to compute the absolute
+                * timestamp, it could end up with a division by zero.
+                * Not necessary to repeat the check on the end time, when we enter
+                * this case the time has been updated by the Firmware.
+                */
+               if(psTimestamp->ui64Timestamp == 0)
+               {
+                       * pui64StartTime = 0;
+                       * pui64EndTime = 0;
+                       return PVRSRV_OK;
+               }
+
+               psTimeCorr       = &psTimestamp->sTimeCorr;
+               ui64CRTimeDiff   = psTimestamp->ui64Timestamp - psTimeCorr->ui64CRTimeStamp;
+               * pui64StartTime = psTimeCorr->ui64OSTimeStamp +
+                                  RGXFWIF_GET_DELTA_OSTIME_NS(ui64CRTimeDiff, psTimeCorr->ui32CRDeltaToOSDeltaKNs);
+
+               psTimestamp      = &psDevInfo->pasEndTimeById[ui32QueryId];
+               psTimeCorr       = &psTimestamp->sTimeCorr;
+               ui64CRTimeDiff   = psTimestamp->ui64Timestamp - psTimeCorr->ui64CRTimeStamp;
+               * pui64EndTime   = psTimeCorr->ui64OSTimeStamp +
+                                  RGXFWIF_GET_DELTA_OSTIME_NS(ui64CRTimeDiff, psTimeCorr->ui32CRDeltaToOSDeltaKNs);
+
+               return PVRSRV_OK;
+       }
+       else
+       {
+               return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+       }
+}
+
+
+PVRSRV_ERROR
+PVRSRVRGXCurrentTime(PVRSRV_DEVICE_NODE * psDeviceNode,
+                     IMG_UINT64         * pui64Time)
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+       *pui64Time = OSClockns64();
+
+       return PVRSRV_OK;
+}
+
+
+
+/******************************************************************************
+ NOT BRIDGED/EXPORTED FUNCS
+******************************************************************************/
+/* writes a time stamp command in the client CCB */
+IMG_VOID
+RGXWriteTimestampCommand(IMG_PBYTE            * ppbyPtr,
+                         RGXFWIF_CCB_CMD_TYPE eCmdType,
+                         RGXFWIF_DEV_VIRTADDR pTimestamp)
+{
+       RGXFWIF_CCB_CMD_HEADER * psHeader;
+
+       psHeader = (RGXFWIF_CCB_CMD_HEADER *) (*ppbyPtr);
+
+       PVR_ASSERT(eCmdType == RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP
+                  || eCmdType == RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP);
+
+       psHeader->eCmdType    = eCmdType;
+       psHeader->ui32CmdSize = (sizeof(RGXFWIF_DEV_VIRTADDR) + RGXFWIF_FWALLOC_ALIGN - 1) & ~(RGXFWIF_FWALLOC_ALIGN  - 1);
+
+       (*ppbyPtr) += sizeof(RGXFWIF_CCB_CMD_HEADER);
+
+       (*(RGXFWIF_DEV_VIRTADDR*)*ppbyPtr) = pTimestamp;
+
+       (*ppbyPtr) += psHeader->ui32CmdSize;
+}
+
+
+IMG_VOID
+RGX_GetTimestampCmdHelper(PVRSRV_RGXDEV_INFO   * psDevInfo,
+                          RGXFWIF_DEV_VIRTADDR * ppPreTimestamp,
+                          RGXFWIF_DEV_VIRTADDR * ppPostTimestamp,
+                          PRGXFWIF_UFO_ADDR    * ppUpdate)
+{
+       if (ppPreTimestamp != IMG_NULL)
+       {
+               if (psDevInfo->bSaveStart)
+               {
+                       /* drop the SaveStart on the first Kick */
+                       psDevInfo->bSaveStart = IMG_FALSE;
+
+                       RGXSetFirmwareAddress(ppPreTimestamp,
+                                             psDevInfo->psStartTimeMemDesc,
+                                             sizeof(RGXFWIF_TIMESTAMP) * psDevInfo->ui32ActiveQueryId,
+                                             RFW_FWADDR_NOREF_FLAG);
+               }
+               else
+               {
+                       ppPreTimestamp->ui32Addr = 0;
+               }
+       }
+
+       if (ppPostTimestamp != IMG_NULL && ppUpdate != IMG_NULL)
+       {
+               if (psDevInfo->bSaveEnd)
+               {
+                       RGXSetFirmwareAddress(ppPostTimestamp,
+                                             psDevInfo->psEndTimeMemDesc,
+                                             sizeof(RGXFWIF_TIMESTAMP) * psDevInfo->ui32ActiveQueryId,
+                                             RFW_FWADDR_NOREF_FLAG);
+
+                       psDevInfo->aui32ScheduledOnId[psDevInfo->ui32ActiveQueryId]++;
+
+                       RGXSetFirmwareAddress(ppUpdate,
+                                             psDevInfo->psCompletedMemDesc,
+                                             sizeof(IMG_UINT32) * psDevInfo->ui32ActiveQueryId,
+                                             RFW_FWADDR_NOREF_FLAG);
+               }
+               else
+               {
+                       ppUpdate->ui32Addr        = 0;
+                       ppPostTimestamp->ui32Addr = 0;
+               }
+       }
+}
+
+
+/******************************************************************************
+ End of file (rgxtimerquery.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtimerquery.h
new file mode 100644 (file)
index 0000000..14d8118
--- /dev/null
@@ -0,0 +1,129 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Timer queries
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX Timer queries functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if ! defined (_RGX_TIMERQUERIES_H_)
+#define _RGX_TIMERQUERIES_H_
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "device.h"
+#include "rgxdevice.h"
+
+/**************************************************************************/ /*!
+@Function       PVRSRVRGXBeginTimerQuery
+@Description    Opens a new timer query.
+
+@Input          ui32QueryId an identifier between [ 0 and RGX_MAX_TIMER_QUERIES - 1 ]
+@Return         PVRSRV_OK on success.
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVRGXBeginTimerQueryKM(PVRSRV_DEVICE_NODE * psDeviceNode,
+                           IMG_UINT32         ui32QueryId);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVRGXEndTimerQuery
+@Description    Closes a timer query
+
+                The lack of ui32QueryId argument expresses the fact that there can't
+                be overlapping queries open.
+@Return         PVRSRV_OK on success.
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVRGXEndTimerQueryKM(PVRSRV_DEVICE_NODE * psDeviceNode);
+
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVRGXQueryTimer
+@Description    Queries the state of the specified timer
+
+@Input          ui32QueryId an identifier between [ 0 and RGX_MAX_TIMER_QUERIES - 1 ]
+@Out            pui64StartTime
+@Out            pui64EndTime
+@Return         PVRSRV_OK                         on success.
+                PVRSRV_ERROR_RESOURCE_UNAVAILABLE if the device is still busy with
+                                                  operations from the queried period
+                other error code                  otherwise
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVRGXQueryTimerKM(PVRSRV_DEVICE_NODE * psDeviceNode,
+                      IMG_UINT32         ui32QueryId,
+                      IMG_UINT64         * pui64StartTime,
+                      IMG_UINT64         * pui64EndTime);
+
+
+/**************************************************************************/ /*!
+@Function       PVRSRVRGXCurrentTime
+@Description    Returns the current state of the timer used in timer queries
+@Input          psDevData  Device data.
+@Out            pui64Time
+@Return         PVRSRV_OK on success.
+*/ /***************************************************************************/
+PVRSRV_ERROR
+PVRSRVRGXCurrentTime(PVRSRV_DEVICE_NODE * psDeviceNode,
+                     IMG_UINT64         * pui64Time);
+
+
+/******************************************************************************
+ NON BRIDGED/EXPORTED interface
+******************************************************************************/
+
+/* write the timestamp cmd from the helper*/
+IMG_VOID
+RGXWriteTimestampCommand(IMG_PBYTE            * ppui8CmdPtr,
+                         RGXFWIF_CCB_CMD_TYPE eCmdType,
+                         RGXFWIF_DEV_VIRTADDR pTimestamp);
+
+/* get the relevant data from the Kick to the helper*/
+IMG_VOID
+RGX_GetTimestampCmdHelper(PVRSRV_RGXDEV_INFO   * psDevInfo,
+                          RGXFWIF_DEV_VIRTADDR * ppPreTimestamp,
+                          RGXFWIF_DEV_VIRTADDR * ppPostTimestamp,
+                          PRGXFWIF_UFO_ADDR    * ppUpdate);
+
+#endif /* _RGX_TIMERQUERIES_H_ */
+
+/******************************************************************************
+ End of file (rgxtimerquery.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.c
new file mode 100644 (file)
index 0000000..4f5d343
--- /dev/null
@@ -0,0 +1,1127 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific transfer queue routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pdump_km.h"
+#include "rgxdevice.h"
+#include "rgxccb.h"
+#include "rgxutils.h"
+#include "rgxfwutils.h"
+#include "rgxtransfer.h"
+#include "rgx_tq_shared.h"
+#include "rgxmem.h"
+#include "allocmem.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+#include "pvrsrv.h"
+#include "rgx_fwif_resetframework.h"
+#include "rgx_memallocflags.h"
+#include "rgxccb.h"
+#include "rgxtimerquery.h"
+#include "rgxhwperf.h"
+#include "rgxsync.h"
+
+#include "sync_server.h"
+#include "sync_internal.h"
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#include "pvr_sync.h"
+#endif
+
+typedef struct {
+       DEVMEM_MEMDESC                          *psFWContextStateMemDesc;
+       RGX_SERVER_COMMON_CONTEXT       *psServerCommonContext;
+       IMG_UINT32                                      ui32Priority;
+} RGX_SERVER_TQ_3D_DATA;
+
+typedef struct {
+       RGX_SERVER_COMMON_CONTEXT       *psServerCommonContext;
+       IMG_UINT32                                      ui32Priority;
+} RGX_SERVER_TQ_2D_DATA;
+
+struct _RGX_SERVER_TQ_CONTEXT_ {
+       PVRSRV_DEVICE_NODE                      *psDeviceNode;
+       DEVMEM_MEMDESC                          *psFWFrameworkMemDesc;
+       IMG_UINT32                                      ui32Flags;
+#define RGX_SERVER_TQ_CONTEXT_FLAGS_2D         (1<<0)
+#define RGX_SERVER_TQ_CONTEXT_FLAGS_3D         (1<<1)
+       RGX_SERVER_TQ_3D_DATA           s3DData;
+       RGX_SERVER_TQ_2D_DATA           s2DData;
+       PVRSRV_CLIENT_SYNC_PRIM         *psCleanupSync;
+       DLLIST_NODE                                     sListNode;
+       SYNC_ADDR_LIST                  sSyncAddrListFence;
+       SYNC_ADDR_LIST                  sSyncAddrListUpdate;
+};
+
+/*
+       Static functions used by transfer context code
+*/
+
+static PVRSRV_ERROR _Create3DTransferContext(CONNECTION_DATA *psConnection,
+                                                                                        PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                        DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                                                        IMG_UINT32 ui32Priority,
+                                                                                        RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                                                        RGX_SERVER_TQ_3D_DATA *ps3DData)
+{
+       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+       PVRSRV_ERROR eError;
+
+       /*
+               Allocate device memory for the firmware GPU context suspend state.
+               Note: the FW reads/writes the state to memory by accessing the GPU register interface.
+       */
+       PDUMPCOMMENT("Allocate RGX firmware TQ/3D context suspend state");
+
+       eError = DevmemFwAllocate(psDevInfo,
+                                                       sizeof(RGXFWIF_3DCTX_STATE),
+                                                       RGX_FWCOMCTX_ALLOCFLAGS,
+                                                       "FirmwareTQ3DContext",
+                                                       &ps3DData->psFWContextStateMemDesc);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_contextswitchstate;
+       }
+
+       eError = FWCommonContextAllocate(psConnection,
+                                                                        psDeviceNode,
+                                                                        "TQ_3D",
+                                                                        IMG_NULL,
+                                                                        0,
+                                                                        psFWMemContextMemDesc,
+                                                                        ps3DData->psFWContextStateMemDesc,
+                                                                        RGX_CCB_SIZE_LOG2,
+                                                                        ui32Priority,
+                                                                        psInfo,
+                                                                        &ps3DData->psServerCommonContext);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_contextalloc;
+       }
+
+
+       PDUMPCOMMENT("Dump 3D context suspend state buffer");
+       DevmemPDumpLoadMem(ps3DData->psFWContextStateMemDesc, 0, sizeof(RGXFWIF_3DCTX_STATE), PDUMP_FLAGS_CONTINUOUS);
+
+       ps3DData->ui32Priority = ui32Priority;
+       return PVRSRV_OK;
+
+fail_contextalloc:
+       DevmemFwFree(ps3DData->psFWContextStateMemDesc);
+fail_contextswitchstate:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static PVRSRV_ERROR _Create2DTransferContext(CONNECTION_DATA *psConnection,
+                                                                                        PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                        DEVMEM_MEMDESC *psFWMemContextMemDesc,
+                                                                                        IMG_UINT32 ui32Priority,
+                                                                                        RGX_COMMON_CONTEXT_INFO *psInfo,
+                                                                                        RGX_SERVER_TQ_2D_DATA *ps2DData)
+{
+       PVRSRV_ERROR eError;
+
+       eError = FWCommonContextAllocate(psConnection,
+                                                                        psDeviceNode,
+                                                                        "TQ_2D",
+                                                                        IMG_NULL,
+                                                                        0,
+                                                                        psFWMemContextMemDesc,
+                                                                        IMG_NULL,
+                                                                        RGX_CCB_SIZE_LOG2,
+                                                                        ui32Priority,
+                                                                        psInfo,
+                                                                        &ps2DData->psServerCommonContext);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_contextalloc;
+       }
+
+       ps2DData->ui32Priority = ui32Priority;
+       return PVRSRV_OK;
+
+fail_contextalloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+static PVRSRV_ERROR _Destroy2DTransferContext(RGX_SERVER_TQ_2D_DATA *ps2DData,
+                                                                                         PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                         PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync)
+{
+       PVRSRV_ERROR eError;
+
+       /* Check if the FW has finished with this resource ... */
+       eError = RGXFWRequestCommonContextCleanUp(psDeviceNode,
+                                                                                         FWCommonContextGetFWAddress(ps2DData->psServerCommonContext),
+                                                                                         psCleanupSync,
+                                                                                         RGXFWIF_DM_2D);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+       else if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
+                                __FUNCTION__,
+                                PVRSRVGetErrorStringKM(eError)));
+       }
+
+       /* ... it has so we can free it's resources */
+       FWCommonContextFree(ps2DData->psServerCommonContext);
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _Destroy3DTransferContext(RGX_SERVER_TQ_3D_DATA *ps3DData,
+                                                                                         PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                         PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync)
+{
+       PVRSRV_ERROR eError;
+
+       /* Check if the FW has finished with this resource ... */
+       eError = RGXFWRequestCommonContextCleanUp(psDeviceNode,
+                                                                                         FWCommonContextGetFWAddress(ps3DData->psServerCommonContext),
+                                                                                         psCleanupSync,
+                                                                                         RGXFWIF_DM_3D);
+       if (eError == PVRSRV_ERROR_RETRY)
+       {
+               return eError;
+       }
+       else if (eError != PVRSRV_OK)
+       {
+               PVR_LOG(("%s: Unexpected error from RGXFWRequestCommonContextCleanUp (%s)",
+                                __FUNCTION__,
+                                PVRSRVGetErrorStringKM(eError)));
+       }
+
+       /* ... it has so we can free it's resources */
+       DevmemFwFree(ps3DData->psFWContextStateMemDesc);
+       FWCommonContextFree(ps3DData->psServerCommonContext);
+
+       return PVRSRV_OK;
+}
+
+/*
+ * PVRSRVCreateTransferContextKM
+ */
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA          *psConnection,
+                                                                                  PVRSRV_DEVICE_NODE           *psDeviceNode,
+                                                                                  IMG_UINT32                           ui32Priority,
+                                                                                  IMG_DEV_VIRTADDR                     sMCUFenceAddr,
+                                                                                  IMG_UINT32                           ui32FrameworkCommandSize,
+                                                                                  IMG_PBYTE                            pabyFrameworkCommand,
+                                                                                  IMG_HANDLE                           hMemCtxPrivData,
+                                                                                  RGX_SERVER_TQ_CONTEXT        **ppsTransferContext)
+{
+       RGX_SERVER_TQ_CONTEXT   *psTransferContext;
+       DEVMEM_MEMDESC                  *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData);
+       RGX_COMMON_CONTEXT_INFO sInfo;
+       PVRSRV_ERROR                    eError = PVRSRV_OK;
+
+       /* Allocate the server side structure */
+       *ppsTransferContext = IMG_NULL;
+       psTransferContext = OSAllocMem(sizeof(*psTransferContext));
+       if (psTransferContext == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       OSMemSet(psTransferContext, 0, sizeof(*psTransferContext));
+
+       psTransferContext->psDeviceNode = psDeviceNode;
+
+       /* Allocate cleanup sync */
+       eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext,
+                                                  &psTransferContext->psCleanupSync,
+                                                  "transfer context cleanup");
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to allocate cleanup sync (0x%x)",
+                               eError));
+               goto fail_syncalloc;
+       }
+
+       /* 
+        * Create the FW framework buffer
+        */
+       eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode,
+                                                                               &psTransferContext->psFWFrameworkMemDesc,
+                                                                               ui32FrameworkCommandSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to allocate firmware GPU framework state (%u)",
+                               eError));
+               goto fail_frameworkcreate;
+       }
+
+       /* Copy the Framework client data into the framework buffer */
+       eError = PVRSRVRGXFrameworkCopyCommand(psTransferContext->psFWFrameworkMemDesc,
+                                                                                  pabyFrameworkCommand,
+                                                                                  ui32FrameworkCommandSize);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateTransferContextKM: Failed to populate the framework buffer (%u)",
+                               eError));
+               goto fail_frameworkcopy;
+       }
+
+       sInfo.psFWFrameworkMemDesc = psTransferContext->psFWFrameworkMemDesc;
+       sInfo.psMCUFenceAddr = &sMCUFenceAddr;
+
+       eError = _Create3DTransferContext(psConnection,
+                                                                         psDeviceNode,
+                                                                         psFWMemContextMemDesc,
+                                                                         ui32Priority,
+                                                                         &sInfo,
+                                                                         &psTransferContext->s3DData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_3dtransfercontext;
+       }
+       psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_3D;
+
+       eError = _Create2DTransferContext(psConnection,
+                                                                         psDeviceNode,
+                                                                         psFWMemContextMemDesc,
+                                                                         ui32Priority,
+                                                                         &sInfo,
+                                                                         &psTransferContext->s2DData);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_2dtransfercontext;
+       }
+       psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_2D;
+
+       SyncAddrListInit(&psTransferContext->sSyncAddrListFence);
+       SyncAddrListInit(&psTransferContext->sSyncAddrListUpdate);
+
+       {
+               PVRSRV_RGXDEV_INFO                      *psDevInfo = psDeviceNode->pvDevice;
+
+               OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock);
+               dllist_add_to_tail(&(psDevInfo->sTransferCtxtListHead), &(psTransferContext->sListNode));
+               OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock);
+               *ppsTransferContext = psTransferContext;
+       }
+
+       *ppsTransferContext = psTransferContext;
+       return PVRSRV_OK;
+
+fail_2dtransfercontext:
+       _Destroy3DTransferContext(&psTransferContext->s3DData,
+                                                         psTransferContext->psDeviceNode,
+                                                         psTransferContext->psCleanupSync);
+fail_3dtransfercontext:
+fail_frameworkcopy:
+       DevmemFwFree(psTransferContext->psFWFrameworkMemDesc);
+fail_frameworkcreate:
+       SyncPrimFree(psTransferContext->psCleanupSync);
+fail_syncalloc:
+       OSFreeMem(psTransferContext);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       *ppsTransferContext = IMG_NULL;
+       return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransferContext)
+{
+       PVRSRV_ERROR eError;
+       PVRSRV_RGXDEV_INFO *psDevInfo = psTransferContext->psDeviceNode->pvDevice;
+
+       /* remove node from list before calling destroy - as destroy, if successful
+        * will invalidate the node
+        * must be re-added if destroy fails
+        */
+       OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock);
+       dllist_remove_node(&(psTransferContext->sListNode));
+       OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock);
+
+       if (psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_2D)
+       {
+               eError = _Destroy2DTransferContext(&psTransferContext->s2DData,
+                                                                                  psTransferContext->psDeviceNode,
+                                                                                  psTransferContext->psCleanupSync);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_destroy2d;
+               }
+               /* We've freed the 2D context, don't try to free it again */
+               psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_2D;
+       }
+
+       if (psTransferContext->ui32Flags & RGX_SERVER_TQ_CONTEXT_FLAGS_3D)
+       {
+               eError = _Destroy3DTransferContext(&psTransferContext->s3DData,
+                                                                                  psTransferContext->psDeviceNode,
+                                                                                  psTransferContext->psCleanupSync);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_destroy3d;
+               }
+               /* We've freed the 3D context, don't try to free it again */
+               psTransferContext->ui32Flags &= ~RGX_SERVER_TQ_CONTEXT_FLAGS_3D;
+       }
+
+       DevmemFwFree(psTransferContext->psFWFrameworkMemDesc);
+       SyncPrimFree(psTransferContext->psCleanupSync);
+
+       SyncAddrListDeinit(&psTransferContext->sSyncAddrListFence);
+       SyncAddrListDeinit(&psTransferContext->sSyncAddrListUpdate);
+
+       OSFreeMem(psTransferContext);
+
+       return PVRSRV_OK;
+
+fail_destroy2d:
+fail_destroy3d:
+       OSWRLockAcquireWrite(psDevInfo->hTransferCtxListLock);
+       dllist_add_to_tail(&(psDevInfo->sTransferCtxtListHead), &(psTransferContext->sListNode));
+       OSWRLockReleaseWrite(psDevInfo->hTransferCtxListLock);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*
+ * PVRSRVSubmitTQ3DKickKM
+ */
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT   *psTransferContext,
+                                                                          IMG_UINT32                           ui32PrepareCount,
+                                                                          IMG_UINT32                           *paui32ClientFenceCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         ***papauiClientFenceUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           **papaui32ClientFenceSyncOffset,
+                                                                          IMG_UINT32                           **papaui32ClientFenceValue,
+                                                                          IMG_UINT32                           *paui32ClientUpdateCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         ***papauiClientUpdateUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           **papaui32ClientUpdateSyncOffset,
+                                                                          IMG_UINT32                           **papaui32ClientUpdateValue,
+                                                                          IMG_UINT32                           *paui32ServerSyncCount,
+                                                                          IMG_UINT32                           **papaui32ServerSyncFlags,
+                                                                          SERVER_SYNC_PRIMITIVE        ***papapsServerSyncs,
+                                                                          IMG_UINT32                           ui32NumCheckFenceFDs,
+                                                                          IMG_INT32                            *pai32CheckFenceFDs,
+                                                                          IMG_INT32                            i32UpdateFenceFD,
+                                                                          IMG_UINT32                           *paui32FWCommandSize,
+                                                                          IMG_UINT8                            **papaui8FWCommand,
+                                                                          IMG_UINT32                           *pui32TQPrepareFlags,
+                                                                          IMG_UINT32                           ui32ExtJobRef,
+                                                                          IMG_UINT32                           ui32IntJobRef)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode = psTransferContext->psDeviceNode;
+       RGX_CCB_CMD_HELPER_DATA *pas3DCmdHelper;
+       RGX_CCB_CMD_HELPER_DATA *pas2DCmdHelper;
+       IMG_UINT32 ui323DCmdCount = 0;
+       IMG_UINT32 ui322DCmdCount = 0;
+       IMG_BOOL bKick2D = IMG_FALSE;
+       IMG_BOOL bKick3D = IMG_FALSE;
+       IMG_BOOL bPDumpContinuous = IMG_FALSE;
+       IMG_UINT32 i;
+       IMG_UINT32 ui32IntClientFenceCount = 0;
+       PRGXFWIF_UFO_ADDR *pauiIntFenceUFOAddress = IMG_NULL;
+       IMG_UINT32 *paui32IntFenceValue = IMG_NULL;
+       IMG_UINT32 ui32IntClientUpdateCount = 0;
+       PRGXFWIF_UFO_ADDR *pauiIntUpdateUFOAddress = IMG_NULL;
+       IMG_UINT32 *paui32IntUpdateValue = IMG_NULL;
+       PVRSRV_ERROR eError;
+       PVRSRV_ERROR eError2;
+
+       RGXFWIF_DEV_VIRTADDR pPreTimestamp;
+       RGXFWIF_DEV_VIRTADDR pPostTimestamp;
+       PRGXFWIF_UFO_ADDR    pRMWUFOAddr;
+
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       struct pvr_sync_append_data *psFDFenceData = NULL;
+#endif
+
+       if (ui32PrepareCount == 0)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       if (ui32NumCheckFenceFDs != 0 || i32UpdateFenceFD >= 0)
+       {
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+               /* Fence FD's are only valid in the 3D case with no batching */
+               if ((ui32PrepareCount !=1) && (!TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[0], 3D)))
+               {
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+               }
+
+#else
+               /* We only support Fence FD's if built with SUPPORT_NATIVE_FENCE_SYNC */
+               return PVRSRV_ERROR_INVALID_PARAMS;
+#endif
+       }
+
+       /* We can't allocate the required amount of stack space on all consumer architectures */
+       pas3DCmdHelper = OSAllocMem(sizeof(*pas3DCmdHelper) * ui32PrepareCount);
+       if (pas3DCmdHelper == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc3dhelper;
+       }
+       pas2DCmdHelper = OSAllocMem(sizeof(*pas2DCmdHelper) * ui32PrepareCount);
+       if (pas2DCmdHelper == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc2dhelper;
+       }
+
+       /*
+               Ensure we do the right thing for server syncs which cross call bounderies
+       */
+       for (i=0;i<ui32PrepareCount;i++)
+       {
+               IMG_BOOL bHaveStartPrepare = pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_START;
+               IMG_BOOL bHaveEndPrepare = IMG_FALSE;
+
+               if (bHaveStartPrepare)
+               {
+                       IMG_UINT32 k;
+                       /*
+                               We've at the start of a transfer operation (which might be made
+                               up of multiple HW operations) so check if we also have then
+                               end of the transfer operation in the batch
+                       */
+                       for (k=i;k<ui32PrepareCount;k++)
+                       {
+                               if (pui32TQPrepareFlags[k] & TQ_PREP_FLAGS_END)
+                               {
+                                       bHaveEndPrepare = IMG_TRUE;
+                                       break;
+                               }
+                       }
+
+                       if (!bHaveEndPrepare)
+                       {
+                               /*
+                                       We don't have the complete command passed in this call
+                                       so drop the update request. When we get called again with
+                                       the last HW command in this transfer operation we'll do
+                                       the update at that point.
+                               */
+                               for (k=0;k<paui32ServerSyncCount[i];k++)
+                               {
+                                       papaui32ServerSyncFlags[i][k] &= ~PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE;
+                               }
+                       }
+               }
+       }
+
+
+       /*
+               Init the command helper commands for all the prepares
+       */
+       for (i=0;i<ui32PrepareCount;i++)
+       {
+               RGX_CLIENT_CCB *psClientCCB;
+               RGX_SERVER_COMMON_CONTEXT *psServerCommonCtx;
+               IMG_CHAR *pszCommandName;
+               RGX_CCB_CMD_HELPER_DATA *psCmdHelper;
+               RGXFWIF_CCB_CMD_TYPE eType;
+
+               if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 3D))
+               {
+                       psServerCommonCtx = psTransferContext->s3DData.psServerCommonContext;
+                       psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx);
+                       pszCommandName = "TQ-3D";
+                       psCmdHelper = &pas3DCmdHelper[ui323DCmdCount++];
+                       eType = RGXFWIF_CCB_CMD_TYPE_TQ_3D;
+               }
+               else if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 2D))
+               {
+                       psServerCommonCtx = psTransferContext->s2DData.psServerCommonContext;
+                       psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx);
+                       pszCommandName = "TQ-2D";
+                       psCmdHelper = &pas2DCmdHelper[ui322DCmdCount++];
+                       eType = RGXFWIF_CCB_CMD_TYPE_TQ_2D;
+               }
+               else
+               {
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+                       goto fail_cmdtype;
+               }
+
+               if (i == 0)
+               {
+                       bPDumpContinuous = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS);
+                       PDUMPCOMMENTWITHFLAGS((bPDumpContinuous) ? PDUMP_FLAGS_CONTINUOUS : 0,
+                                       "%s Command Server Submit on FWCtx %08x", pszCommandName, FWCommonContextGetFWAddress(psServerCommonCtx).ui32Addr);
+               }
+               else
+               {
+                       IMG_BOOL bNewPDumpContinuous = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS);
+
+                       if (bNewPDumpContinuous != bPDumpContinuous)
+                       {
+                               eError = PVRSRV_ERROR_INVALID_PARAMS;
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Mixing of continuous and non-continuous command in a batch is not permitted", __FUNCTION__));
+                               goto fail_pdumpcheck;
+                       }
+               }
+
+               ui32IntClientFenceCount  = paui32ClientFenceCount[i];
+               eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListFence,
+                                                                               ui32IntClientFenceCount,
+                                                                               papauiClientFenceUFOSyncPrimBlock[i],
+                                                                               papaui32ClientFenceSyncOffset[i]);
+               if(eError != PVRSRV_OK)
+               {
+                       goto fail_populate_sync_addr_list;
+               }
+               pauiIntFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs;
+
+               paui32IntFenceValue      = papaui32ClientFenceValue[i];
+               ui32IntClientUpdateCount = paui32ClientUpdateCount[i];
+               eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListUpdate,
+                                                                               ui32IntClientUpdateCount,
+                                                                               papauiClientUpdateUFOSyncPrimBlock[i],
+                                                                               papaui32ClientUpdateSyncOffset[i]);
+               if(eError != PVRSRV_OK)
+               {
+                       goto fail_populate_sync_addr_list;
+               }
+               pauiIntUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs;
+               paui32IntUpdateValue     = papaui32ClientUpdateValue[i];
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       if (ui32NumCheckFenceFDs || i32UpdateFenceFD >= 0)
+       {
+               eError =
+                 pvr_sync_append_fences("TQ",
+                                              ui32NumCheckFenceFDs,
+                                              pai32CheckFenceFDs,
+                                              i32UpdateFenceFD,
+                                              ui32IntClientUpdateCount,
+                                              pauiIntUpdateUFOAddress,
+                                              paui32IntUpdateValue,
+                                              ui32IntClientFenceCount,
+                                              pauiIntFenceUFOAddress,
+                                              paui32IntFenceValue,
+                                              &psFDFenceData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_syncinit;
+               }
+               pvr_sync_get_updates(psFDFenceData, &ui32IntClientUpdateCount,
+                       &pauiIntUpdateUFOAddress, &paui32IntUpdateValue);
+               pvr_sync_get_checks(psFDFenceData, &ui32IntClientFenceCount,
+                       &pauiIntFenceUFOAddress, &paui32IntFenceValue);
+       }
+#endif
+
+               RGX_GetTimestampCmdHelper((PVRSRV_RGXDEV_INFO*) psTransferContext->psDeviceNode->pvDevice,
+                                         & pPreTimestamp,
+                                         & pPostTimestamp,
+                                         & pRMWUFOAddr);
+
+               /*
+                       Create the command helper data for this command
+               */
+               eError = RGXCmdHelperInitCmdCCB(psClientCCB,
+                                               ui32IntClientFenceCount,
+                                               pauiIntFenceUFOAddress,
+                                               paui32IntFenceValue,
+                                               ui32IntClientUpdateCount,
+                                               pauiIntUpdateUFOAddress,
+                                               paui32IntUpdateValue,
+                                               paui32ServerSyncCount[i],
+                                               papaui32ServerSyncFlags[i],
+                                               papapsServerSyncs[i],
+                                               paui32FWCommandSize[i],
+                                               papaui8FWCommand[i],
+                                               & pPreTimestamp,
+                                               & pPostTimestamp,
+                                               & pRMWUFOAddr,
+                                               eType,
+                                               bPDumpContinuous,
+                                               pszCommandName,
+                                               psCmdHelper);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_initcmd;
+               }
+       }
+
+       /*
+               Acquire space for all the commands in one go
+       */
+       if (ui323DCmdCount)
+       {
+               
+               eError = RGXCmdHelperAcquireCmdCCB(ui323DCmdCount,
+                                                                                  &pas3DCmdHelper[0],
+                                                                                  &bKick3D);
+               if (eError != PVRSRV_OK)
+               {
+                       if (bKick3D)
+                       {
+                               ui323DCmdCount = 0;
+                               ui322DCmdCount = 0;
+                       }
+                       else
+                       {
+                               goto fail_3dcmdacquire;
+                       }
+               }
+       }
+
+       if (ui322DCmdCount)
+       {
+               eError = RGXCmdHelperAcquireCmdCCB(ui322DCmdCount,
+                                                                                  &pas2DCmdHelper[0],
+                                                                                  &bKick2D);
+       
+               if (eError != PVRSRV_OK)
+               {
+                       if (bKick2D || bKick3D)
+                       {
+                               ui323DCmdCount = 0;
+                               ui322DCmdCount = 0;
+                       }
+                       else
+                       {
+                               goto fail_2dcmdacquire;
+                       }
+               }
+       }
+
+       /*
+               We should acquire the kernel CCB(s) space here as the schedule could fail
+               and we would have to roll back all the syncs
+       */
+
+       /*
+               Only do the command helper release (which takes the server sync
+               operations if the acquire succeeded
+       */
+       if (ui323DCmdCount)
+       {
+               RGXCmdHelperReleaseCmdCCB(ui323DCmdCount,
+                                                                 &pas3DCmdHelper[0],
+                                                                 "TQ_3D",
+                                                                 FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext).ui32Addr);
+               
+       }
+
+       if (ui322DCmdCount)
+       {
+               RGXCmdHelperReleaseCmdCCB(ui322DCmdCount,
+                                                                 &pas2DCmdHelper[0],
+                                                                 "TQ_2D",
+                                                                 FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext).ui32Addr);
+       }
+
+       /*
+               Even if we failed to acquire the client CCB space we might still need
+               to kick the HW to process a padding packet to release space for us next
+               time round
+       */
+       if (bKick3D)
+       {
+               RGXFWIF_KCCB_CMD s3DKCCBCmd;
+
+               /* Construct the kernel 3D CCB command. */
+               s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+               s3DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext);
+               s3DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s3DData.psServerCommonContext));
+               s3DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError2 = RGXScheduleCommand(psDeviceNode->pvDevice,
+                                                                               RGXFWIF_DM_3D,
+                                                                               &s3DKCCBCmd,
+                                                                               sizeof(s3DKCCBCmd),
+                                                                               bPDumpContinuous);
+                       if (eError2 != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+               RGXHWPerfFTraceGPUEnqueueEvent(psDeviceNode->pvDevice,
+                               ui32ExtJobRef, ui32IntJobRef, "TQ3D");
+#endif
+       }
+
+       if (bKick2D)
+       {
+               RGXFWIF_KCCB_CMD s2DKCCBCmd;
+
+               /* Construct the kernel 3D CCB command. */
+               s2DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
+               s2DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext);
+               s2DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s2DData.psServerCommonContext));
+               s2DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
+
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+               {
+                       eError2 = RGXScheduleCommand(psDeviceNode->pvDevice,
+                                                                               RGXFWIF_DM_2D,
+                                                                               &s2DKCCBCmd,
+                                                                               sizeof(s2DKCCBCmd),
+                                                                               bPDumpContinuous);
+                       if (eError2 != PVRSRV_ERROR_RETRY)
+                       {
+                               break;
+                       }
+                       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+               } END_LOOP_UNTIL_TIMEOUT();
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+               RGXHWPerfFTraceGPUEnqueueEvent(psDeviceNode->pvDevice,
+                               ui32ExtJobRef, ui32IntJobRef, "TQ2D");
+#endif
+       }
+
+       /*
+        * Now check eError (which may have returned an error from our earlier calls
+        * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first
+        * so we check it now...
+        */
+       if (eError != PVRSRV_OK )
+       {
+               goto fail_2dcmdacquire;
+       }
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#if defined(NO_HARDWARE)
+       pvr_sync_nohw_complete_fences(psFDFenceData);
+#endif
+       /*
+               Free the merged sync memory if required
+       */
+       pvr_sync_free_append_fences_data(psFDFenceData);
+#endif
+
+       OSFreeMem(pas2DCmdHelper);
+       OSFreeMem(pas3DCmdHelper);
+
+       return PVRSRV_OK;
+
+/*
+       No resources are created in this function so there is nothing to free
+       unless we had to merge syncs.
+       If we fail after the client CCB acquire there is still nothing to do
+       as only the client CCB release will modify the client CCB
+*/
+fail_2dcmdacquire:
+fail_3dcmdacquire:
+
+fail_initcmd:
+
+fail_pdumpcheck:
+fail_cmdtype:
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+fail_syncinit:
+       /* Relocated cleanup here as the loop could fail after the first iteration
+        * at the above goto tags at which point the psFDCheckData memory would
+        * have been allocated.
+        */
+       if (psFDFenceData)
+       {
+               pvr_sync_rollback_append_fences(psFDFenceData);
+               pvr_sync_free_append_fences_data(psFDFenceData);
+               psFDFenceData = NULL;
+       }
+#endif
+fail_populate_sync_addr_list:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       OSFreeMem(pas2DCmdHelper);
+fail_alloc2dhelper:
+       OSFreeMem(pas3DCmdHelper);
+fail_alloc3dhelper:
+       return eError;
+}
+
+PVRSRV_ERROR PVRSRVRGXSetTransferContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                  RGX_SERVER_TQ_CONTEXT *psTransferContext,
+                                                                                                  IMG_UINT32 ui32Priority)
+{
+       PVRSRV_ERROR eError;
+
+       if (psTransferContext->s2DData.ui32Priority != ui32Priority)
+       {
+               eError = ContextSetPriority(psTransferContext->s2DData.psServerCommonContext,
+                                                                       psConnection,
+                                                                       psTransferContext->psDeviceNode->pvDevice,
+                                                                       ui32Priority,
+                                                                       RGXFWIF_DM_2D);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the 2D part of the transfercontext (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_2dcontext;
+               }
+               psTransferContext->s2DData.ui32Priority = ui32Priority;
+       }
+
+       if (psTransferContext->s3DData.ui32Priority != ui32Priority)
+       {
+               eError = ContextSetPriority(psTransferContext->s3DData.psServerCommonContext,
+                                                                       psConnection,
+                                                                       psTransferContext->psDeviceNode->pvDevice,
+                                                                       ui32Priority,
+                                                                       RGXFWIF_DM_3D);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to set the priority of the 3D part of the transfercontext (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+                       goto fail_3dcontext;
+               }
+               psTransferContext->s3DData.ui32Priority = ui32Priority;
+       }
+       return PVRSRV_OK;
+
+fail_3dcontext:
+fail_2dcontext:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static IMG_BOOL CheckForStalledTransferCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       RGX_SERVER_TQ_CONTEXT           *psCurrentServerTransferCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_CONTEXT, sListNode);
+       RGX_SERVER_TQ_2D_DATA           *psTransferCtx2DData = &(psCurrentServerTransferCtx->s2DData);
+       RGX_SERVER_COMMON_CONTEXT       *psCurrentServerTQ2DCommonCtx = psTransferCtx2DData->psServerCommonContext;
+       RGX_SERVER_TQ_3D_DATA           *psTransferCtx3DData = &(psCurrentServerTransferCtx->s3DData);
+       RGX_SERVER_COMMON_CONTEXT       *psCurrentServerTQ3DCommonCtx = psTransferCtx3DData->psServerCommonContext;
+       DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf = pvCallbackData;
+
+
+       DumpStalledFWCommonContext(psCurrentServerTQ2DCommonCtx, pfnDumpDebugPrintf);
+       DumpStalledFWCommonContext(psCurrentServerTQ3DCommonCtx, pfnDumpDebugPrintf);
+
+       return IMG_TRUE;
+}
+IMG_VOID CheckForStalledTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                        DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       OSWRLockAcquireRead(psDevInfo->hTransferCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sTransferCtxtListHead),
+                                               CheckForStalledTransferCtxtCommand, pfnDumpDebugPrintf);
+       OSWRLockReleaseRead(psDevInfo->hTransferCtxListLock);
+}
+
+static IMG_BOOL CheckForStalledClientTransferCtxtCommand(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData)
+{
+       PVRSRV_ERROR *peError = (PVRSRV_ERROR*)pvCallbackData;
+       RGX_SERVER_TQ_CONTEXT           *psCurrentServerTransferCtx = IMG_CONTAINER_OF(psNode, RGX_SERVER_TQ_CONTEXT, sListNode);
+       RGX_SERVER_TQ_2D_DATA           *psTransferCtx2DData = &(psCurrentServerTransferCtx->s2DData);
+       RGX_SERVER_COMMON_CONTEXT       *psCurrentServerTQ2DCommonCtx = psTransferCtx2DData->psServerCommonContext;
+       RGX_SERVER_TQ_3D_DATA           *psTransferCtx3DData = &(psCurrentServerTransferCtx->s3DData);
+       RGX_SERVER_COMMON_CONTEXT       *psCurrentServerTQ3DCommonCtx = psTransferCtx3DData->psServerCommonContext;
+
+       if (PVRSRV_ERROR_CCCB_STALLED == CheckStalledClientCommonContext(psCurrentServerTQ2DCommonCtx))
+       {
+               *peError = PVRSRV_ERROR_CCCB_STALLED;
+       }
+       if (PVRSRV_ERROR_CCCB_STALLED == CheckStalledClientCommonContext(psCurrentServerTQ3DCommonCtx))
+       {
+               *peError = PVRSRV_ERROR_CCCB_STALLED;
+       }
+
+       return IMG_TRUE;
+}
+IMG_BOOL CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       OSWRLockAcquireRead(psDevInfo->hTransferCtxListLock);
+       dllist_foreach_node(&(psDevInfo->sTransferCtxtListHead), 
+                                               CheckForStalledClientTransferCtxtCommand, &eError);
+       OSWRLockReleaseRead(psDevInfo->hTransferCtxListLock);
+       return (PVRSRV_ERROR_CCCB_STALLED == eError)? IMG_TRUE: IMG_FALSE;
+}
+
+PVRSRV_ERROR PVRSRVRGXKickSyncTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext,
+                                                                          IMG_UINT32                           ui32ClientFenceCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         **pauiClientFenceUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           *paui32ClientFenceSyncOffset,
+                                                                          IMG_UINT32                           *paui32ClientFenceValue,
+                                                                          IMG_UINT32                           ui32ClientUpdateCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         **pauiClientUpdateUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           *paui32ClientUpdateSyncOffset,
+                                                                          IMG_UINT32                           *paui32ClientUpdateValue,
+                                                                          IMG_UINT32                           ui32ServerSyncCount,
+                                                                          IMG_UINT32                           *pui32ServerSyncFlags,
+                                                                          SERVER_SYNC_PRIMITIVE        **pasServerSyncs,
+                                                                          IMG_UINT32                           ui32NumCheckFenceFDs,
+                                                                          IMG_INT32                            *pai32CheckFenceFDs,
+                                                                          IMG_INT32                            i32UpdateFenceFD,
+                                                                          IMG_UINT32                           ui32TQPrepareFlags)
+{
+       PVRSRV_ERROR                eError;
+       RGX_SERVER_COMMON_CONTEXT   *psServerCommonCtx;
+       IMG_CHAR                    *pszCommandName;
+       RGXFWIF_DM                  eDM;
+       IMG_BOOL                    bPDumpContinuous;
+
+       PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress;
+       PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       /* Android fd sync update info */
+       struct pvr_sync_append_data *psFDFenceData = NULL;
+#endif
+
+       eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListFence,
+                                                                       ui32ClientFenceCount,
+                                                                       pauiClientFenceUFOSyncPrimBlock,
+                                                                       paui32ClientFenceSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClientFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs;
+
+       eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListUpdate,
+                                                                       ui32ClientUpdateCount,
+                                                                       pauiClientUpdateUFOSyncPrimBlock,
+                                                                       paui32ClientUpdateSyncOffset);
+       if(eError != PVRSRV_OK)
+       {
+               goto err_populate_sync_addr_list;
+       }
+
+       pauiClientUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs;
+
+
+       bPDumpContinuous = ((ui32TQPrepareFlags & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS);
+
+       if (TQ_PREP_FLAGS_COMMAND_IS(ui32TQPrepareFlags, 3D))
+       {
+               psServerCommonCtx = psTransferContext->s3DData.psServerCommonContext;
+               pszCommandName = "SyncTQ-3D";
+               eDM = RGXFWIF_DM_3D;
+       }
+       else if (TQ_PREP_FLAGS_COMMAND_IS(ui32TQPrepareFlags, 2D))
+       {
+               psServerCommonCtx = psTransferContext->s2DData.psServerCommonContext;
+               pszCommandName = "SyncTQ-2D";
+               eDM = RGXFWIF_DM_2D;
+       }
+       else
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       /* Android FD fences are hardcoded to updates (IMG_TRUE below), Fences go to the TA and updates to the 3D */
+       if (ui32NumCheckFenceFDs || i32UpdateFenceFD >= 0)
+       {
+               eError =
+                 pvr_sync_append_fences("TQ",
+                                        ui32NumCheckFenceFDs,
+                                        pai32CheckFenceFDs,
+                                        i32UpdateFenceFD,
+                                        ui32ClientUpdateCount,
+                                        pauiClientUpdateUFOAddress,
+                                        paui32ClientUpdateValue,
+                                        ui32ClientFenceCount,
+                                        pauiClientFenceUFOAddress,
+                                        paui32ClientFenceValue,
+                                        &psFDFenceData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto fail_fdsync;
+               }
+               pvr_sync_get_updates(psFDFenceData, &ui32ClientUpdateCount,
+                       &pauiClientUpdateUFOAddress, &paui32ClientUpdateValue);
+               pvr_sync_get_checks(psFDFenceData, &ui32ClientFenceCount,
+                       &pauiClientFenceUFOAddress, &paui32ClientFenceValue);
+       }
+#endif /* defined(SUPPORT_NATIVE_FENCE_SYNC) */
+
+       eError = 
+               RGXKickSyncKM(psTransferContext->psDeviceNode,
+                                     psServerCommonCtx,
+                                     eDM,
+                                     pszCommandName,
+                                     ui32ClientFenceCount,
+                                     pauiClientFenceUFOAddress,
+                                     paui32ClientFenceValue,
+                                     ui32ClientUpdateCount,
+                                     pauiClientUpdateUFOAddress,
+                                     paui32ClientUpdateValue,
+                                     ui32ServerSyncCount,
+                                     pui32ServerSyncFlags,
+                                     pasServerSyncs,
+                                     bPDumpContinuous);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Error calling RGXKickSyncKM (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError)));
+               goto fail_kicksync;
+       }
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#if defined(NO_HARDWARE)
+       pvr_sync_nohw_complete_fences(psFDFenceData);
+#endif
+       pvr_sync_free_append_fences_data(psFDFenceData);
+#endif
+
+       return eError;
+
+fail_kicksync:
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       pvr_sync_rollback_append_fences(psFDFenceData);
+       pvr_sync_free_append_fences_data(psFDFenceData);
+fail_fdsync:
+#endif
+err_populate_sync_addr_list:
+       return eError;
+}
+
+/**************************************************************************//**
+ End of file (rgxtransfer.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxtransfer.h
new file mode 100644 (file)
index 0000000..89cd0de
--- /dev/null
@@ -0,0 +1,164 @@
+/*************************************************************************/ /*!
+@File
+@Title          RGX Transfer queue Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the RGX Transfer queue Functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__RGXTRANSFER_H__)
+#define __RGXTRANSFER_H__
+
+#include "devicemem.h"
+#include "device.h"
+#include "rgxdevice.h"
+#include "rgxfwutils.h"
+#include "rgx_fwif_resetframework.h"
+#include "rgxdebug.h"
+
+#include "sync_server.h"
+#include "connection_server.h"
+
+typedef struct _RGX_SERVER_TQ_CONTEXT_ RGX_SERVER_TQ_CONTEXT;
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXCreateTransferContextKM
+
+ @Description
+       Server-side implementation of RGXCreateTransferContext
+
+ @Input pvDeviceNode - device node
+FIXME fill this in
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA                  *psConnection,
+                                                                                  PVRSRV_DEVICE_NODE           *psDeviceNode,
+                                                                                  IMG_UINT32                           ui32Priority,
+                                                                                  IMG_DEV_VIRTADDR                     sMCUFenceAddr,
+                                                                                  IMG_UINT32                           ui32FrameworkCommandSize,
+                                                                                  IMG_PBYTE                            pabyFrameworkCommand,
+                                                                                  IMG_HANDLE                           hMemCtxPrivData,
+                                                                                  RGX_SERVER_TQ_CONTEXT        **ppsTransferContext);
+
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVRGXDestroyTransferContextKM
+
+ @Description
+       Server-side implementation of RGXDestroyTransferContext
+
+ @Input psTransferContext - Transfer context
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransferContext);
+
+/*!
+*******************************************************************************
+
+ @Function     PVRSRVSubmitTransferKM
+
+ @Description
+       Schedules one or more 2D or 3D HW commands on the firmware
+
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT   *psTransferContext,
+                                                                       IMG_UINT32                              ui32PrepareCount,
+                                                                       IMG_UINT32                              *paui32ClientFenceCount,
+                                                                       SYNC_PRIMITIVE_BLOCK            ***papauiClientFenceUFOSyncPrimBlock,
+                                                                       IMG_UINT32                              **papaui32ClientFenceSyncOffset,
+                                                                       IMG_UINT32                              **papaui32ClientFenceValue,
+                                                                       IMG_UINT32                              *paui32ClientUpdateCount,
+                                                                       SYNC_PRIMITIVE_BLOCK            ***papauiClientUpdateUFOSyncPrimBlock,
+                                                                       IMG_UINT32                              **papaui32ClientUpdateSyncOffset,
+                                                                       IMG_UINT32                              **papaui32ClientUpdateValue,
+                                                                       IMG_UINT32                              *paui32ServerSyncCount,
+                                                                       IMG_UINT32                              **papaui32ServerSyncFlags,
+                                                                       SERVER_SYNC_PRIMITIVE   ***papapsServerSyncs,
+                                                                       IMG_UINT32                              ui32NumCheckFenceFDs,
+                                                                       IMG_INT32                               *paui32CheckFenceFDs,
+                                                                       IMG_INT32                               i32UpdateFenceFD,
+                                                                       IMG_UINT32                              *paui32FWCommandSize,
+                                                                       IMG_UINT8                               **papaui8FWCommand,
+                                                                       IMG_UINT32                              *pui32TQPrepareFlags,
+                                                                       IMG_UINT32                              ui32ExtJobRef,
+                                                                       IMG_UINT32                              ui32IntJobRef);
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRGXSetTransferContextPriorityKM(CONNECTION_DATA *psConnection,
+                                                                                                  RGX_SERVER_TQ_CONTEXT *psTransferContext,
+                                                                                                  IMG_UINT32 ui32Priority);
+
+/* Debug - check if transfer context is waiting on a fence */
+IMG_VOID CheckForStalledTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo,
+                                                                        DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/* Debug/Watchdog - check if client transfer contexts are stalled */
+IMG_BOOL CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo);
+
+PVRSRV_ERROR PVRSRVRGXKickSyncTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext,
+                                                                          IMG_UINT32                           ui32ClientFenceCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         **pauiClientFenceUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           *paui32ClientFenceSyncOffset,
+                                                                          IMG_UINT32                           *paui32ClientFenceValue,
+                                                                          IMG_UINT32                           ui32ClientUpdateCount,
+                                                                          SYNC_PRIMITIVE_BLOCK         **pauiClientUpdateUFOSyncPrimBlock,
+                                                                          IMG_UINT32                           *paui32ClientUpdateSyncOffset,
+                                                                          IMG_UINT32                           *paui32ClientUpdateValue,
+                                                                          IMG_UINT32                           ui32ServerSyncCount,
+                                                                          IMG_UINT32                           *pui32ServerSyncFlags,
+                                                                          SERVER_SYNC_PRIMITIVE        **pasServerSyncs,
+                                                                          IMG_UINT32                           ui32NumCheckFenceFDs,
+                                                                          IMG_INT32                            *paui32CheckFenceFDs,
+                                                                          IMG_INT32                            i32UpdateFenceFD,
+                                                                          IMG_UINT32                           ui32TQPrepareFlags);
+#endif /* __RGXTRANSFER_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.c b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.c
new file mode 100644 (file)
index 0000000..e3d9f2a
--- /dev/null
@@ -0,0 +1,287 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific utility routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "rgx_fwif_km.h"
+#include "pdump_km.h"
+#include "osfunc.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "rgxutils.h"
+#include "power.h"
+#include "pvrsrv.h"
+#include "sync_internal.h"
+#include "rgxfwutils.h"
+
+/*
+ * RGXRunScript
+ */
+PVRSRV_ERROR RGXRunScript(PVRSRV_RGXDEV_INFO   *psDevInfo,
+                                                RGX_INIT_COMMAND               *psScript,
+                                                IMG_UINT32                             ui32NumCommands,
+                                                IMG_UINT32                             ui32PdumpFlags,
+                                                DUMPDEBUG_PRINTF_FUNC  *pfnDumpDebugPrintf)
+{
+       IMG_UINT32 ui32PC;
+#if !defined(NO_HARDWARE)
+       IMG_UINT32 ui32LastLoopPoint = 0xFFFFFFFF;
+#endif /* NO_HARDWARE */
+
+       for (ui32PC = 0;  ui32PC < ui32NumCommands;  ui32PC++)
+       {
+               RGX_INIT_COMMAND *psComm = &psScript[ui32PC];
+
+               switch (psComm->eOp)
+               {
+                       case RGX_INIT_OP_DBG_READ32_HW_REG:
+                       {
+                               IMG_UINT32      ui32RegVal;
+                               ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM,  psComm->sDBGReadHWReg.ui32Offset);
+                               PVR_DUMPDEBUG_LOG(("%s: 0x%08X", psComm->sDBGReadHWReg.aszName, ui32RegVal));
+                               break;
+                       }
+                       case RGX_INIT_OP_DBG_READ64_HW_REG:
+                       {
+                               IMG_UINT64      ui64RegVal;
+                               ui64RegVal = OSReadHWReg64(psDevInfo->pvRegsBaseKM, psComm->sDBGReadHWReg.ui32Offset);
+                               PVR_DUMPDEBUG_LOG(("%s: 0x%016llX", psComm->sDBGReadHWReg.aszName, ui64RegVal));
+                               break;
+                       }
+                       case RGX_INIT_OP_WRITE_HW_REG:
+                       {
+                               if( !(ui32PdumpFlags & PDUMP_FLAGS_NOHW) )
+                               {
+                                       OSWriteHWReg32(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+                               }
+                               PDUMPCOMMENT("RGXRunScript: Write HW reg operation");
+                               PDUMPREG32(RGX_PDUMPREG_NAME,
+                                               psComm->sWriteHWReg.ui32Offset,
+                                               psComm->sWriteHWReg.ui32Value,
+                                               ui32PdumpFlags);
+                               break;
+                       }
+                       case RGX_INIT_OP_PDUMP_HW_REG:
+                       {
+                               PDUMPCOMMENT("RGXRunScript: Dump HW reg operation");
+                               PDUMPREG32(RGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset,
+                                               psComm->sPDumpHWReg.ui32Value, ui32PdumpFlags);
+                               break;
+                       }
+                       case RGX_INIT_OP_COND_POLL_HW_REG:
+                       {
+#if !defined(NO_HARDWARE)
+                               IMG_UINT32      ui32RegVal;
+
+                               if( !(ui32PdumpFlags & PDUMP_FLAGS_NOHW) )
+                               {
+                                       /* read the register used as condition */
+                                       ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM,  psComm->sCondPollHWReg.ui32CondOffset);
+
+                                       /* if the conditions succeeds, poll the register */
+                                       if ((ui32RegVal & psComm->sCondPollHWReg.ui32CondMask) == psComm->sCondPollHWReg.ui32CondValue)
+                                       {
+                                               if (PVRSRVPollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + psComm->sCondPollHWReg.ui32Offset),
+                                                               psComm->sCondPollHWReg.ui32Value,
+                                                               psComm->sCondPollHWReg.ui32Mask) != PVRSRV_OK)
+                                               {
+                                                       PVR_DPF((PVR_DBG_ERROR, "RGXRunScript: Cond Poll for Reg (0x%x) failed -> Cancel script.", psComm->sCondPollHWReg.ui32Offset));
+                                                       return PVRSRV_ERROR_TIMEOUT;
+                                               }
+
+                                       }
+                                       else
+                                       {
+                                               PVR_DPF((PVR_DBG_WARNING, 
+                                               "RGXRunScript: Skipping Poll for Reg (0x%x) because the condition is not met (Reg 0x%x ANDed with mask 0x%x equal to 0x%x but value 0x%x found instead).",
+                                               psComm->sCondPollHWReg.ui32Offset,
+                                               psComm->sCondPollHWReg.ui32CondOffset,
+                                               psComm->sCondPollHWReg.ui32CondMask,
+                                               psComm->sCondPollHWReg.ui32CondValue,
+                                               ui32RegVal));
+                                       }
+                               }
+#endif
+                               break;
+                       }
+                       case RGX_INIT_OP_POLL_64_HW_REG:
+                       {
+                               /* Split lower and upper words */
+                               IMG_UINT32 ui32UpperValue = (IMG_UINT32) (psComm->sPoll64HWReg.ui64Value >> 32);
+                               IMG_UINT32 ui32LowerValue = (IMG_UINT32) (psComm->sPoll64HWReg.ui64Value);
+
+                               IMG_UINT32 ui32UpperMask = (IMG_UINT32) (psComm->sPoll64HWReg.ui64Mask >> 32);
+                               IMG_UINT32 ui32LowerMask = (IMG_UINT32) (psComm->sPoll64HWReg.ui64Mask);
+
+                               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXRunScript: 64 bit HW offset: %x", psComm->sPoll64HWReg.ui32Offset);
+
+                               if( !(ui32PdumpFlags & PDUMP_FLAGS_NOHW) )
+                               {
+                                       if (PVRSRVPollForValueKM((IMG_UINT32 *)(((IMG_UINT8*)psDevInfo->pvRegsBaseKM) + psComm->sPoll64HWReg.ui32Offset + 4),
+                                                                                ui32UpperValue,
+                                                                                ui32UpperMask) != PVRSRV_OK)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR, "RGXRunScript: Poll for upper part of Reg (0x%x) failed -> Cancel script.", psComm->sPoll64HWReg.ui32Offset));
+                                               return PVRSRV_ERROR_TIMEOUT;
+                                       }
+                               }
+                               PDUMPREGPOL(RGX_PDUMPREG_NAME,
+                                                       psComm->sPoll64HWReg.ui32Offset + 4,
+                                                       ui32UpperValue,
+                                                       ui32UpperMask,
+                                                       ui32PdumpFlags,
+                                                       PDUMP_POLL_OPERATOR_EQUAL);
+
+                               if( !(ui32PdumpFlags & PDUMP_FLAGS_NOHW) )
+                               {
+                                       if (PVRSRVPollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + psComm->sPoll64HWReg.ui32Offset),
+                                                                                ui32LowerValue,
+                                                                                ui32LowerMask) != PVRSRV_OK)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR, "RGXRunScript: Poll for lower part of Reg (0x%x) failed -> Cancel script.", psComm->sPoll64HWReg.ui32Offset));
+                                               return PVRSRV_ERROR_TIMEOUT;
+                                       }
+                               }
+                               PDUMPREGPOL(RGX_PDUMPREG_NAME,
+                                                       psComm->sPoll64HWReg.ui32Offset,
+                                                       ui32LowerValue,
+                                                       ui32LowerMask,
+                                                       ui32PdumpFlags,
+                                                       PDUMP_POLL_OPERATOR_EQUAL);
+
+                               break;
+                       }
+                       case RGX_INIT_OP_POLL_HW_REG:
+                       {
+                               if( !(ui32PdumpFlags & PDUMP_FLAGS_NOHW) )
+                               {
+                                       if (PVRSRVPollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + psComm->sPollHWReg.ui32Offset),
+                                                                                psComm->sPollHWReg.ui32Value,
+                                                                                psComm->sPollHWReg.ui32Mask) != PVRSRV_OK)
+                                       {
+                                               PVR_DPF((PVR_DBG_ERROR, "RGXRunScript: Poll for Reg (0x%x) failed -> Cancel script.", psComm->sPollHWReg.ui32Offset));
+                                               return PVRSRV_ERROR_TIMEOUT;
+                                       }
+                               }
+                               PDUMPREGPOL(RGX_PDUMPREG_NAME,
+                                                       psComm->sPollHWReg.ui32Offset,
+                                                       psComm->sPollHWReg.ui32Value,
+                                                       psComm->sPollHWReg.ui32Mask,
+                                                       ui32PdumpFlags,
+                                                       PDUMP_POLL_OPERATOR_EQUAL);
+
+                               break;
+                       }
+
+                       case RGX_INIT_OP_LOOP_POINT:
+                       {
+#if !defined(NO_HARDWARE)
+                               ui32LastLoopPoint = ui32PC;
+#endif /* NO_HARDWARE */
+                               break;
+                       }
+
+                       case RGX_INIT_OP_COND_BRANCH:
+                       {
+#if !defined(NO_HARDWARE)
+                               IMG_UINT32 ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM,
+                                                                                                         psComm->sConditionalBranchPoint.ui32Offset);
+
+                               if((ui32RegVal & psComm->sConditionalBranchPoint.ui32Mask) != psComm->sConditionalBranchPoint.ui32Value)
+                               {
+                                       ui32PC = ui32LastLoopPoint - 1;
+                               }
+#endif /* NO_HARDWARE */
+
+                               PDUMPIDLWITHFLAGS(30, ui32PdumpFlags);
+                               break;
+                       }
+                       case RGX_INIT_OP_DBG_CALC:
+                       {
+                               IMG_UINT32 ui32RegVal1;
+                               IMG_UINT32 ui32RegVal2;
+                               IMG_UINT32 ui32RegVal3;
+                               ui32RegVal1 = OSReadHWReg32(psDevInfo->pvRegsBaseKM,  psComm->sDBGCalc.ui32Offset1);
+                               ui32RegVal2 = OSReadHWReg32(psDevInfo->pvRegsBaseKM,  psComm->sDBGCalc.ui32Offset2);
+                               ui32RegVal3 = OSReadHWReg32(psDevInfo->pvRegsBaseKM,  psComm->sDBGCalc.ui32Offset3);
+                               if (ui32RegVal1 + ui32RegVal2 > ui32RegVal3)
+                               {
+                                       PVR_DUMPDEBUG_LOG(("%s: 0x%08X", psComm->sDBGCalc.aszName, ui32RegVal1 + ui32RegVal2 - ui32RegVal3));
+                               }
+                               else
+                               {
+                                       PVR_DUMPDEBUG_LOG(("%s: 0x%08X", psComm->sDBGCalc.aszName, 0));
+                               }
+                               break;
+                       }
+                       case RGX_INIT_OP_DBG_WAIT:
+                       {
+                               OSWaitus(psComm->sDBGWait.ui32WaitInUs);
+                               break;
+                       }
+                       case RGX_INIT_OP_DBG_STRING:
+                       {
+                               PVR_DUMPDEBUG_LOG(("%s", psComm->sDBGString.aszString));
+                               break;
+                       }
+                       case RGX_INIT_OP_HALT:
+                       {
+                               return PVRSRV_OK;
+                       }
+                       case RGX_INIT_OP_ILLEGAL:
+                       /* FALLTHROUGH */
+                       default:
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,"RGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
+                               return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+                       }
+               }
+
+       }
+
+       return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+}
+
+/******************************************************************************
+ End of file (rgxutils.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.h b/drivers/gpu/rogue_m/services/server/devices/rgx/rgxutils.h
new file mode 100644 (file)
index 0000000..f075f43
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device specific utility routines declarations
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Inline functions/structures specific to RGX
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "device.h"
+#include "rgxdevice.h"
+#include "rgxdebug.h"
+#include "pvrsrv.h"
+
+/*!
+******************************************************************************
+
+ @Function     RGXRunScript
+
+ @Description Execute the commands in the script
+
+ @Input 
+
+ @Return   PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR RGXRunScript(PVRSRV_RGXDEV_INFO   *psDevInfo,
+                                                RGX_INIT_COMMAND       *psScript,
+                                                IMG_UINT32                     ui32NumCommands,
+                                                IMG_UINT32                             ui32PdumpFlags,
+                                                DUMPDEBUG_PRINTF_FUNC  *pfnDumpDebugPrintf);
+
+/******************************************************************************
+ End of file (rgxutils.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/Kbuild.mk b/drivers/gpu/rogue_m/services/server/env/linux/Kbuild.mk
new file mode 100644 (file)
index 0000000..4ab8dfc
--- /dev/null
@@ -0,0 +1,581 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm-y += \
+ services/server/env/linux/event.o \
+ services/server/env/linux/mm.o \
+ services/server/env/linux/mmap.o \
+ services/server/env/linux/module_common.o \
+ services/server/env/linux/devicemem_mmap_stub.o \
+ services/server/env/linux/osfunc.o \
+ services/server/env/linux/allocmem.o \
+ services/server/env/linux/osconnection_server.o \
+ services/server/env/linux/pdump.o \
+ services/server/env/linux/physmem_osmem_linux.o \
+ services/server/env/linux/pvr_debugfs.o \
+ services/server/env/linux/pvr_bridge_k.o \
+ services/server/env/linux/pvr_debug.o \
+ services/server/env/linux/physmem_tdmetacode_linux.o \
+ services/server/env/linux/physmem_tdsecbuf_linux.o \
+ services/server/common/devicemem_heapcfg.o \
+ services/shared/common/devicemem.o \
+ services/shared/common/devicemem_utils.o \
+ services/shared/common/hash.o \
+ services/shared/common/ra.o \
+ services/shared/common/sync.o \
+ services/shared/common/dllist.o \
+ services/shared/common/mem_utils.o \
+ services/server/common/devicemem_server.o \
+ services/server/common/handle.o \
+ services/server/common/lists.o \
+ services/server/common/mmu_common.o \
+ services/server/common/connection_server.o \
+ services/server/common/physheap.o \
+ services/server/common/physmem.o \
+ services/server/common/physmem_lma.o \
+ services/server/common/pmr.o \
+ services/server/common/power.o \
+ services/server/common/process_stats.o \
+ services/server/common/pvrsrv.o \
+ services/server/common/srvcore.o \
+ services/server/common/sync_server.o \
+ services/server/common/tlintern.o \
+ services/shared/common/tlclient.o \
+ services/server/common/tlserver.o \
+ services/server/common/tlstream.o \
+ services/shared/common/uniq_key_splay_tree.o
+
+ifneq ($(PVR_LOADER),)
+pvrsrvkm-y += services/server/env/linux/$(PVR_LOADER).o
+else
+pvrsrvkm-y += services/server/env/linux/module.o
+endif
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+pvrsrvkm-y += \
+ services/server/common/dc_server.o \
+ services/server/common/scp.o
+endif
+
+ifeq ($(PVR_RI_DEBUG),1)
+pvrsrvkm-y += services/server/common/ri_server.o
+endif
+
+ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1)
+pvrsrvkm-y += services/server/common/devicemem_history_server.o
+endif
+
+ifeq ($(PVR_HANDLE_BACKEND),generic)
+pvrsrvkm-y += services/server/common/handle_generic.o
+else
+ifeq ($(PVR_HANDLE_BACKEND),idr)
+pvrsrvkm-y += services/server/env/linux/handle_idr.o
+endif
+endif
+
+ifeq ($(SUPPORT_GPUTRACE_EVENTS),1)
+pvrsrvkm-y += services/server/env/linux/pvr_gputrace.o
+endif
+
+ifeq ($(PVR_TESTING_UTILS),1)
+pvrsrvkm-y += services/server/common/tutils.o
+endif
+
+ifeq ($(PVR_DVFS),1)
+pvrsrvkm-y += \
+ services/server/env/linux/pvr_dvfs_governor.o \
+ services/server/env/linux/pvr_dvfs_device.o
+endif
+
+pvrsrvkm-$(CONFIG_X86) += services/server/env/linux/osfunc_x86.o
+pvrsrvkm-$(CONFIG_ARM) += services/server/env/linux/osfunc_arm.o
+pvrsrvkm-$(CONFIG_ARM64) += services/server/env/linux/osfunc_arm64.o
+pvrsrvkm-$(CONFIG_METAG) += services/server/env/linux/osfunc_metag.o
+pvrsrvkm-$(CONFIG_MIPS) += services/server/env/linux/osfunc_mips.o
+
+pvrsrvkm-$(CONFIG_EVENT_TRACING) += services/server/env/linux/trace_events.o
+
+ifneq ($(W),1)
+CFLAGS_mm.o := -Werror
+CFLAGS_mmap.o := -Werror
+CFLAGS_module_common.o := -Werror
+CFLAGS_mutils.o := -Werror
+CFLAGS_devicemem_mmap_stub.o := -Werror
+CFLAGS_osfunc.o := -Werror
+CFLAGS_osfunc_x86.o := -Werror
+CFLAGS_osconnection_server.o := -Werror
+CFLAGS_pdump.o := -Werror
+CFLAGS_pvr_debugfs.o := -Werror
+CFLAGS_pvr_bridge_k.o := -Werror
+CFLAGS_devicemem_heapcfg.o := -Werror
+CFLAGS_devicemem.o := -Werror
+CFLAGS_devicemem_utils.o = -Werror
+CFLAGS_devicemem_pdump.o = -Werror
+CFLAGS_hash.o := -Werror
+CFLAGS_ra.o := -Werror
+CFLAGS_sync.o := -Werror
+CFLAGS_devicemem_server.o := -Werror
+CFLAGS_handle.o := -Werror
+CFLAGS_lists.o := -Werror
+CFLAGS_mem_debug.o := -Werror
+CFLAGS_mmu_common.o := -Werror
+CFLAGS_connection_server.o := -Werror
+CFLAGS_physmem.o := -Werror
+CFLAGS_physmem_lma.o := -Werror
+CFLAGS_pmr.o := -Werror
+CFLAGS_power.o := -Werror
+CFLAGS_process_stats.o := -Werror
+CFLAGS_pvrsrv.o := -Werror
+CFLAGS_srvcore.o := -Werror
+CFLAGS_sync_server.o := -Werror
+CFLAGS_tlintern.o := -Werror
+CFLAGS_tlclient.o := -Werror
+CFLAGS_tlserver.o := -Werror
+CFLAGS_tlstream.o := -Werror
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+CFLAGS_dc_server.o := -Werror
+CFLAGS_scp.o := -Werror
+endif
+
+ifeq ($(PVR_RI_DEBUG),1)
+CFLAGS_ri_server.o := -Werror
+endif
+ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1)
+CFLAGS_devicememhistory_server.o := -Werror
+endif
+ifeq ($(SUPPORT_GPUTRACE_EVENTS),1)
+CFLAGS_pvr_gputrace.o := -Werror
+endif
+ifeq ($(SUPPORT_VALIDATION),1)
+CFLAGS_validation.o := -Werror
+endif
+ifeq ($(PVR_TESTING_UTILS),1)
+CFLAGS_tutils.o := -Werror
+endif
+endif
+
+# With certain build configurations, e.g., ARM, Werror, we get a build 
+# failure in the ftrace Linux kernel header.  So disable the relevant check.
+CFLAGS_trace_events.o := -Wno-missing-prototypes
+
+ifeq ($(PDUMP),1)
+pvrsrvkm-y += \
+ services/server/common/pdump_common.o \
+ services/server/common/pdump_mmu.o \
+ services/server/common/pdump_physmem.o \
+ services/shared/common/devicemem_pdump.o
+ifneq ($(W),1)
+CFLAGS_pdump_common.o := -Werror
+CFLAGS_pdump_mmu.o := -Werror
+CFLAGS_pdump_physmem.o := -Werror
+CFLAGS_devicemem_pdump.o := -Werror
+endif
+endif
+
+pvrsrvkm-y += \
+ services/server/devices/rgx/rgxinit.o \
+ services/server/devices/rgx/rgxdebug.o \
+ services/server/devices/rgx/rgxhwperf.o \
+ services/server/devices/rgx/rgxmem.o \
+ services/server/devices/rgx/rgxta3d.o \
+ services/server/devices/rgx/rgxcompute.o \
+ services/server/devices/rgx/rgxccb.o \
+ services/server/devices/rgx/rgxmmuinit.o \
+ services/server/devices/rgx/rgxpower.o \
+ services/server/devices/rgx/rgxtransfer.o \
+ services/server/devices/rgx/rgxutils.o \
+ services/server/devices/rgx/rgxfwutils.o \
+ services/server/devices/rgx/rgxbreakpoint.o \
+ services/server/devices/rgx/debugmisc_server.o \
+ services/shared/devices/rgx/rgx_compat_bvnc.o \
+ services/server/devices/rgx/rgxregconfig.o \
+ services/server/devices/rgx/rgxtimerquery.o \
+ services/server/devices/rgx/rgxsync.o \
+ services/server/devices/rgx/rgxtimecorr.o
+
+ifeq ($(SUPPORT_RAY_TRACING),1)
+pvrsrvkm-y += services/server/devices/rgx/rgxray.o
+endif
+
+
+ifneq ($(W),1)
+CFLAGS_rgxinit.o := -Werror
+CFLAGS_rgxdebug.o := -Werror
+CFLAGS_rgxhwperf.o := -Werror
+CFLAGS_rgxmem.o := -Werror
+CFLAGS_rgxta3d.o := -Werror
+CFLAGS_rgxcompute.o := -Werror
+CFLAGS_rgxccb.o := -Werror
+CFLAGS_rgxmmuinit.o := -Werror
+CFLAGS_rgxpower.o := -Werror
+CFLAGS_rgxsharedpb.o := -Werror
+CFLAGS_rgxtransfer.o := -Werror
+CFLAGS_rgxutils.o := -Werror
+CFLAGS_rgxfwutils.o := -Werror
+CFLAGS_rgxbreakpoint.o := -Werror
+CFLAGS_debugmisc_server.o := -Werror
+CFLAGS_rgxray.o := -Werror
+CFLAGS_rgxregconfig.o := -Werror
+CFLAGS_rgxsync.o := -Werror
+endif
+
+ifeq ($(PDUMP),1)
+pvrsrvkm-y += services/server/devices/rgx/rgxpdump.o
+ifneq ($(W),1)
+CFLAGS_rgxpdump.o := -Werror
+endif
+endif
+
+# Bridge headers and source files
+ccflags-y += \
+ -I$(bridge_base)/dmm_bridge \
+ -I$(bridge_base)/mm_bridge \
+ -I$(bridge_base)/cmm_bridge \
+ -I$(bridge_base)/pdumpmm_bridge \
+ -I$(bridge_base)/pdump_bridge \
+ -I$(bridge_base)/pdumpctrl_bridge \
+ -I$(bridge_base)/rgxtq_bridge \
+ -I$(bridge_base)/rgxinit_bridge \
+ -I$(bridge_base)/rgxta3d_bridge \
+ -I$(bridge_base)/rgxcmp_bridge \
+ -I$(bridge_base)/dsync_bridge \
+ -I$(bridge_base)/sync_bridge \
+ -I$(bridge_base)/breakpoint_bridge \
+ -I$(bridge_base)/debugmisc_bridge \
+ -I$(bridge_base)/rgxpdump_bridge \
+ -I$(bridge_base)/pvrtl_bridge \
+ -I$(bridge_base)/dpvrtl_bridge \
+ -I$(bridge_base)/rgxhwperf_bridge \
+ -I$(bridge_base)/regconfig_bridge \
+ -I$(bridge_base)/timerquery_bridge
+
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+ccflags-y += \
+ -I$(bridge_base)/dsrvcore_bridge \
+ -I$(bridge_base)/drgxinit_bridge \
+ -I$(bridge_base)/dpdumpctrl_bridge \
+ -I$(bridge_base)/dpdump_bridge \
+ -I$(bridge_base)/drgxpdump_bridge
+endif
+
+ccflags-y += \
+ -I$(bridge_base)/srvcore_bridge
+
+ifeq ($(PVR_RI_DEBUG),1)
+ccflags-y += \
+ -I$(bridge_base)/ri_bridge \
+ -I$(bridge_base)/dri_bridge
+endif
+
+ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1)
+ccflags-y += \
+ -I$(bridge_base)/devicememhistory_bridge \
+ -I$(bridge_base)/ddevicememhistory_bridge
+endif
+
+
+ifeq ($(SUPPORT_RAY_TRACING),1)
+ccflags-y += -I$(bridge_base)/rgxray_bridge
+endif
+
+# Compatibility BVNC
+ccflags-y += \
+ -I$(TOP)/services/shared/devices/rgx
+
+# Errata files
+ccflags-y += \
+ -I$(TOP)/hwdefs
+
+ccflags-y += -I$(TOP)/services/include/env/linux
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+ccflags-y += \
+ -I$(bridge_base)/dc_bridge
+endif
+
+ifeq ($(CACHEFLUSH_TYPE),CACHEFLUSH_GENERIC)
+ccflags-y += -I$(bridge_base)/cachegeneric_bridge
+endif
+
+ifeq ($(SUPPORT_SECURE_EXPORT),1)
+ccflags-y += \
+ -I$(bridge_base)/syncsexport_bridge \
+ -I$(bridge_base)/smm_bridge
+endif
+ifeq ($(SUPPORT_INSECURE_EXPORT),1)
+ccflags-y += \
+ -I$(bridge_base)/syncexport_bridge
+endif
+
+ifeq ($(SUPPORT_ION),1)
+ccflags-y += -I$(bridge_base)/dmabuf_bridge
+endif
+
+ifeq ($(SUPPORT_ANDROID_PLATFORM),1)
+ccflags-y += -I$(TOP)/kernel/drivers/staging/imgtec
+endif
+
+ifeq ($(SUPPORT_NATIVE_FENCE_SYNC),1)
+pvrsrvkm-y += kernel/drivers/staging/imgtec/pvr_sync.o
+endif
+
+ifeq ($(SUPPORT_VALIDATION),1)
+ccflags-y += -I$(bridge_base)/validation_bridge
+endif
+
+ifeq ($(PVR_TESTING_UTILS),1)
+ccflags-y += -I$(bridge_base)/tutils_bridge
+endif
+
+pvrsrvkm-y += \
+ generated/mm_bridge/server_mm_bridge.o \
+ generated/dmm_bridge/client_mm_bridge.o \
+ generated/pdumpmm_bridge/server_pdumpmm_bridge.o \
+ generated/dpdumpmm_bridge/client_pdumpmm_bridge.o \
+ generated/cmm_bridge/server_cmm_bridge.o \
+ generated/pdump_bridge/server_pdump_bridge.o \
+ generated/pdumpctrl_bridge/server_pdumpctrl_bridge.o \
+ generated/rgxtq_bridge/server_rgxtq_bridge.o \
+ generated/rgxinit_bridge/server_rgxinit_bridge.o \
+ generated/rgxta3d_bridge/server_rgxta3d_bridge.o \
+ generated/rgxcmp_bridge/server_rgxcmp_bridge.o \
+ generated/srvcore_bridge/server_srvcore_bridge.o \
+ generated/sync_bridge/server_sync_bridge.o \
+ generated/dsync_bridge/client_sync_bridge.o \
+ generated/breakpoint_bridge/server_breakpoint_bridge.o \
+ generated/debugmisc_bridge/server_debugmisc_bridge.o \
+ generated/rgxpdump_bridge/server_rgxpdump_bridge.o \
+ generated/pvrtl_bridge/server_pvrtl_bridge.o \
+ generated/dpvrtl_bridge/client_pvrtl_bridge.o \
+ generated/rgxhwperf_bridge/server_rgxhwperf_bridge.o \
+ generated/regconfig_bridge/server_regconfig_bridge.o \
+ generated/timerquery_bridge/server_timerquery_bridge.o
+
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+pvrsrvkm-y += \
+ generated/dsrvcore_bridge/client_srvcore_bridge.o \
+ generated/drgxinit_bridge/client_rgxinit_bridge.o \
+ generated/dpdumpctrl_bridge/client_pdumpctrl_bridge.o \
+ generated/dpdump_bridge/client_pdump_bridge.o \
+ generated/drgxpdump_bridge/client_rgxpdump_bridge.o
+endif
+
+ifeq ($(PVR_RI_DEBUG),1)
+pvrsrvkm-y += \
+ generated/ri_bridge/server_ri_bridge.o \
+ generated/dri_bridge/client_ri_bridge.o
+endif
+ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1)
+pvrsrvkm-y += \
+ generated/devicememhistory_bridge/server_devicememhistory_bridge.o \
+ generated/ddevicememhistory_bridge/client_devicememhistory_bridge.o
+endif
+
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+pvrsrvkm-y += \
+ generated/dc_bridge/server_dc_bridge.o
+endif
+
+ifeq ($(SUPPORT_RAY_TRACING),1)
+pvrsrvkm-y += generated/rgxray_bridge/server_rgxray_bridge.o
+endif
+
+ifeq ($(CACHEFLUSH_TYPE),CACHEFLUSH_GENERIC)
+pvrsrvkm-y += \
+ services/server/common/cache_generic.o \
+ generated/cachegeneric_bridge/server_cachegeneric_bridge.o
+endif
+
+ifeq ($(SUPPORT_SECURE_EXPORT),1)
+pvrsrvkm-y += \
+ services/server/env/linux/ossecure_export.o \
+ generated/smm_bridge/server_smm_bridge.o \
+ generated/syncsexport_bridge/server_syncsexport_bridge.o
+endif
+ifeq ($(SUPPORT_INSECURE_EXPORT),1)
+pvrsrvkm-y += \
+ generated/syncexport_bridge/server_syncexport_bridge.o
+endif
+
+ifeq ($(SUPPORT_ION),1)
+pvrsrvkm-y += generated/dmabuf_bridge/server_dmabuf_bridge.o
+pvrsrvkm-y += services/server/env/linux/physmem_dmabuf.o
+endif # SUPPORT_ION
+
+ifeq ($(SUPPORT_VALIDATION),1)
+pvrsrvkm-y += generated/validation_bridge/server_validation_bridge.o
+pvrsrvkm-y += services/server/common/validation.o
+endif # SUPPORT_VALIDATION
+
+ifeq ($(PVR_TESTING_UTILS),1)
+pvrsrvkm-y += generated/tutils_bridge/server_tutils_bridge.o
+endif
+
+ifneq ($(W),1)
+CFLAGS_server_mm_bridge.o := -Werror
+CFLAGS_server_cmm_bridge.o := -Werror
+CFLAGS_client_mm_bridge.o := -Werror
+CFLAGS_client_pdumpmm_bridge.o := -Werror
+CFLAGS_server_pdumpctrl_bridge.o := -Werror
+CFLAGS_server_sync_bridge.o := -Werror
+CFLAGS_server_rgxtq_bridge.o := -Werror
+CFLAGS_server_rgxinit_bridge.o := -Werror
+CFLAGS_server_rgxta3d_bridge.o := -Werror
+CFLAGS_server_rgxcmp_bridge.o := -Werror
+CFLAGS_server_srvcore_bridge.o := -Werror
+CFLAGS_server_breakpoint_bridge.o := -Werror
+CFLAGS_server_debugmisc_bridge.o := -Werror
+CFLAGS_server_rgxpdump_bridge.o := -Werror
+CFLAGS_server_pdumpmm_bridge.o := -Werror
+CFLAGS_client_pdumpmm_bridge.o := -Werror
+CFLAGS_server_pdump_bridge.o := -Werror
+CFLAGS_server_rgxray_bridge.o := -Werror
+CFLAGS_server_regconfig_bridge.o := -Werror
+CFLAGS_server_timerquery_bridge.o := -Werror
+
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+CFLAGS_client_srvcore_bridge.o := -Werror
+endif
+ifeq ($(SUPPORT_DISPLAY_CLASS),1)
+CFLAGS_server_dc_bridge.o := -Werror
+endif
+ifeq ($(CACHEFLUSH_TYPE),CACHEFLUSH_GENERIC)
+CFLAGS_cache_generic.o := -Werror
+CFLAGS_server_cachegeneric_bridge.o := -Werror
+endif
+ifeq ($(SUPPORT_SECURE_EXPORT),1)
+CFLAGS_ossecure_export.o := -Werror
+CFLAGS_server_smm_bridge.o := -Werror
+CFLAGS_server_syncsexport_bridge.o := -Werror
+endif
+ifeq ($(SUPPORT_INSECURE_EXPORT),1)
+CFLAGS_server_syncexport_bridge.o := -Werror
+endif
+CFLAGS_server_pvrtl_bridge.o := -Werror
+CFLAGS_client_pvrtl_bridge.o := -Werror
+CFLAGS_server_rgxhwperf_bridge.o := -Werror
+ifeq ($(PVR_RI_DEBUG),1)
+CFLAGS_server_ri_bridge.o := -Werror
+CFLAGS_client_ri_bridge.o := -Werror
+endif
+ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1)
+CFLAGS_server_devicememhistory_bridge.o := -Werror
+CFLAGS_client_devicememhistory_bridge.o := -Werror
+endif
+ifeq ($(SUPPORT_ION),1)
+CFLAGS_physmem_dmabuf.o := -Werror
+CFLAGS_server_dmabuf_bridge.o = -Werror
+endif
+ifeq ($(SUPPORT_VALIDATION),1)
+CFLAGS_server_validation_bridge.o := -Werror
+endif
+ifeq ($(PVR_TESTING_UTILS),1)
+CFLAGS_server_tutils_bridge.o := -Werror
+endif
+endif
+
+ifeq ($(SUPPORT_DRM),1)
+ifneq ($(SUPPORT_DRM_EXT),1)
+pvrsrvkm-y += \
+ services/server/env/linux/pvr_drm.o
+endif
+
+pvrsrvkm-y += \
+ services/server/env/linux/pvr_drm_gem.o \
+ services/server/env/linux/pvr_drm_prime.o \
+ services/server/env/linux/physmem_dmabuf.o
+
+CFLAGS_physmem_dmabuf.o := -Werror
+
+ifeq ($(SUPPORT_DRM_DC_MODULE),1)
+pvrsrvkm-y += \
+ services/server/env/linux/pvr_drm_display.o
+ifneq ($(SUPPORT_DISPLAY_CLASS),1)
+pvrsrvkm-y += \
+ services/server/common/scp.o
+CFLAGS_scp.o := -Werror
+endif
+endif
+
+ccflags-y += \
+ -Iinclude/drm \
+ -I$(TOP)/services/include/env/linux
+endif # SUPPORT_DRM
+
+ifeq ($(SUPPORT_KERNEL_SRVINIT),1)
+SRVINIT := srvinit
+include $(TOP)/services/srvinit/env/linux/srvinit_common.mk
+pvrsrvkm-y += $(patsubst $(TOP)/%.c,%.o,$($(SRVINIT)_src))
+ccflags-y += $(patsubst %,-I$(TOP)/%,$($(SRVINIT)_includes))
+
+pvrsrvkm-y += \
+ services/client/common/pvrsrv_devmem.o \
+ services/client/common/srvcore.o \
+ services/client/common/connection.o \
+ services/client/devices/rgx/rgxinit_client.o \
+ services/client/env/linux/km/osfunc_km.o \
+ services/client/env/linux/km/osfunc_mutex.o \
+ services/client/env/linux/km/pvr_bridge_client.o \
+ services/client/env/linux/km/pvrtl_client.o
+
+ifeq ($(PDUMP),1)
+pvrsrvkm-y += \
+ services/client/common/pvrsrv_devmem_pdump.o \
+ services/client/common/pvr_pdump_glue.o \
+ services/client/common/devicemem_pdumpc.o
+endif
+
+ifeq ($(SUPPORT_VALIDATION),1)
+pvrsrvkm-y += \
+ services/client/common/validation.o
+endif
+
+ccflags-y += \
+ -I$(TOP)/services/client/include \
+ -I$(TOP)/services/client/common \
+ -I$(TOP)/services/client/env/linux
+
+ccflags-y += \
+ -I$(OUT)/target_neutral/intermediates/firmware
+endif
+
+include $(TOP)/services/system/$(PVR_SYSTEM)/Kbuild.mk
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/Linux.mk b/drivers/gpu/rogue_m/services/server/env/linux/Linux.mk
new file mode 100644 (file)
index 0000000..7d15d88
--- /dev/null
@@ -0,0 +1,46 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := srvkm
+
+srvkm_type := kernel_module
+srvkm_target := pvrsrvkm.ko
+srvkm_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/allocmem.c b/drivers/gpu/rogue_m/services/server/env/linux/allocmem.c
new file mode 100644 (file)
index 0000000..e3e359d
--- /dev/null
@@ -0,0 +1,253 @@
+/*************************************************************************/ /*!
+@File
+@Title          Host memory management implementation for Linux
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include "img_defs.h"
+#include "allocmem.h"
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+
+IMG_INTERNAL IMG_PVOID OSAllocMem(IMG_UINT32 ui32Size)
+{
+       IMG_PVOID pvRet = IMG_NULL;
+
+       if (ui32Size > PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD)
+       {
+               pvRet = vmalloc(ui32Size);
+       }
+       if (pvRet == IMG_NULL)
+       {
+               pvRet = kmalloc(ui32Size, GFP_KERNEL);
+       }
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+
+       if (pvRet != IMG_NULL)
+       {
+
+               if (!is_vmalloc_addr(pvRet))
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvRet));
+#else
+                       {
+                               IMG_CPU_PHYADDR sCpuPAddr;
+                               sCpuPAddr.uiAddr = 0;
+
+                               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
+                                                            pvRet,
+                                                            sCpuPAddr,
+                                                            ksize(pvRet),
+                                                            IMG_NULL);
+                       }
+#endif
+               }
+               else
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                                                          ((ui32Size + PAGE_SIZE -1) & ~(PAGE_SIZE-1)),
+                                                                                          (IMG_UINT64)(IMG_UINTPTR_T) pvRet);
+#else
+                       {
+                               IMG_CPU_PHYADDR sCpuPAddr;
+                               sCpuPAddr.uiAddr = 0;
+
+                               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                                                        pvRet,
+                                                                                        sCpuPAddr,
+                                                                                        ((ui32Size + PAGE_SIZE -1) & ~(PAGE_SIZE-1)),
+                                                                                        IMG_NULL);
+                       }
+#endif
+               }
+
+       }
+#endif
+       return pvRet;
+}
+
+
+IMG_INTERNAL IMG_PVOID OSAllocMemstatMem(IMG_UINT32 ui32Size)
+{
+       IMG_PVOID pvRet = IMG_NULL;
+
+       if (ui32Size > PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD)
+       {
+               pvRet = vmalloc(ui32Size);
+       }
+       if (pvRet == IMG_NULL)
+       {
+               pvRet = kmalloc(ui32Size, GFP_KERNEL);
+       }
+
+       return pvRet;
+}
+
+IMG_INTERNAL IMG_PVOID OSAllocZMem(IMG_UINT32 ui32Size)
+{
+       IMG_PVOID pvRet = IMG_NULL;
+
+       if (ui32Size > PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD)
+       {
+               pvRet = vzalloc(ui32Size);
+       }
+       if (pvRet == IMG_NULL)
+       {
+               pvRet = kzalloc(ui32Size, GFP_KERNEL);
+       }
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+
+       if (pvRet != IMG_NULL)
+       {
+
+               if (!is_vmalloc_addr(pvRet))
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvRet));
+#else
+                       {
+                               IMG_CPU_PHYADDR sCpuPAddr;
+                               sCpuPAddr.uiAddr = 0;
+
+                               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
+                                                            pvRet,
+                                                            sCpuPAddr,
+                                                            ksize(pvRet),
+                                                            IMG_NULL);
+                       }
+#endif
+               }
+               else
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                                                          ((ui32Size + PAGE_SIZE -1) & ~(PAGE_SIZE-1)),
+                                                                                          (IMG_UINT64)(IMG_UINTPTR_T) pvRet);
+#else
+                       {
+                               IMG_CPU_PHYADDR sCpuPAddr;
+                               sCpuPAddr.uiAddr = 0;
+
+                               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                                                        pvRet,
+                                                                                        sCpuPAddr,
+                                                                                        ((ui32Size + PAGE_SIZE -1) & ~(PAGE_SIZE-1)),
+                                                                                        IMG_NULL);
+                       }
+#endif
+               }
+
+       }
+#endif
+       return pvRet;
+}
+
+IMG_INTERNAL IMG_PVOID OSAllocMemstatZMem(IMG_UINT32 ui32Size)
+{
+       IMG_PVOID pvRet = IMG_NULL;
+
+       if (ui32Size > PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD)
+       {
+               pvRet = vzalloc(ui32Size);
+       }
+       if (pvRet == IMG_NULL)
+       {
+               pvRet = kzalloc(ui32Size, GFP_KERNEL);
+       }
+
+       return pvRet;
+}
+
+IMG_INTERNAL void OSFreeMem(IMG_PVOID pvMem)
+{
+
+       if ( !is_vmalloc_addr(pvMem) )
+       {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+               if (pvMem != IMG_NULL)
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvMem));
+#else
+                       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
+                                                      (IMG_UINT64)(IMG_UINTPTR_T) pvMem);
+#endif
+               }
+#endif
+               kfree(pvMem);
+       }
+       else
+       {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+               if (pvMem != IMG_NULL)
+               {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                            (IMG_UINT64)(IMG_UINTPTR_T) pvMem);
+#else
+                       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+                                                      (IMG_UINT64)(IMG_UINTPTR_T) pvMem);
+#endif
+               }
+#endif
+               vfree(pvMem);
+       }
+}
+
+IMG_INTERNAL void OSFreeMemstatMem(IMG_PVOID pvMem)
+{
+       if ( !is_vmalloc_addr(pvMem) )
+       {
+               kfree(pvMem);
+       }
+       else
+       {
+               vfree(pvMem);
+       }
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/devicemem_mmap_stub.c b/drivers/gpu/rogue_m/services/server/env/linux/devicemem_mmap_stub.c
new file mode 100644 (file)
index 0000000..70cde15
--- /dev/null
@@ -0,0 +1,135 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS abstraction for the mmap2 interface for mapping PMRs into
+                User Mode memory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* our exported API */
+#include "devicemem_mmap.h"
+
+/* include/ */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+/* services/include/ */
+
+/* services/include/srvhelper/ */
+#include "ra.h"
+
+/* autogenerated bridge */
+#include <client_mm_bridge.h>
+
+#include "pmr.h"
+
+IMG_INTERNAL PVRSRV_ERROR
+OSMMapPMR(IMG_HANDLE hBridge,
+          IMG_HANDLE hPMR,
+          IMG_DEVMEM_SIZE_T uiPMRSize,
+          IMG_UINT32 uiFlags,
+          IMG_HANDLE *phOSMMapPrivDataOut,
+          void **ppvMappingAddressOut,
+          IMG_SIZE_T *puiMappingLengthOut)
+{
+    PVRSRV_ERROR eError;
+    PMR *psPMR;
+    void *pvKernelAddress;
+    IMG_SIZE_T uiLength;
+    IMG_HANDLE hPriv;
+
+    PVR_UNREFERENCED_PARAMETER(hBridge);
+    PVR_UNREFERENCED_PARAMETER(uiFlags);
+
+    /*
+      Normally this function would mmap a PMR into the memory space of
+      user process, but in this case we're taking a PMR and mapping it
+      into kernel virtual space.  We keep the same function name for
+      symmetry as this allows the higher layers of the software stack
+      to not care whether they are user mode or kernel
+    */
+
+    psPMR = hPMR;
+
+    eError = PMRAcquireKernelMappingData(psPMR,
+                                         0,
+                                         0,
+                                         &pvKernelAddress,
+                                         &uiLength,
+                                         &hPriv);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+    
+    *phOSMMapPrivDataOut = hPriv;
+    *ppvMappingAddressOut = pvKernelAddress;
+    *puiMappingLengthOut = uiLength;
+
+    PVR_ASSERT(*puiMappingLengthOut == uiPMRSize);
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL void
+OSMUnmapPMR(IMG_HANDLE hBridge,
+            IMG_HANDLE hPMR,
+            IMG_HANDLE hOSMMapPrivData,
+            void *pvMappingAddress,
+            IMG_SIZE_T uiMappingLength)
+{
+    PMR *psPMR;
+
+    PVR_UNREFERENCED_PARAMETER(hBridge);
+    PVR_UNREFERENCED_PARAMETER(pvMappingAddress);
+    PVR_UNREFERENCED_PARAMETER(uiMappingLength);
+
+    psPMR = hPMR;
+    PMRReleaseKernelMappingData(psPMR,
+                                hOSMMapPrivData);
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/driverlock.h b/drivers/gpu/rogue_m/services/server/env/linux/driverlock.h
new file mode 100644 (file)
index 0000000..bb44265
--- /dev/null
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@File           driverlock.h
+@Title          Main driver lock
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    The main driver lock, held in most places in
+                the driver.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __DRIVERLOCK_H__
+#define __DRIVERLOCK_H__
+
+/*
+ * Main driver lock, used to ensure driver code is single threaded.
+ * There are some places where this lock must not be taken, such as
+ * in the mmap related deriver entry points.
+ */
+extern struct mutex gPVRSRVLock;
+
+#endif /* __DRIVERLOCK_H__ */
+/*****************************************************************************
+ End of file (driverlock.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/env_connection.h b/drivers/gpu/rogue_m/services/server/env/linux/env_connection.h
new file mode 100644 (file)
index 0000000..2b8622e
--- /dev/null
@@ -0,0 +1,107 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server side connection management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Linux specific server side connection management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_ENV_CONNECTION_H_)
+#define _ENV_CONNECTION_H_
+
+#include <linux/list.h>
+
+#include "handle.h"
+#include "pvr_debug.h"
+
+#if defined(SUPPORT_ION)
+#include PVR_ANDROID_ION_HEADER
+#include "ion_sys.h"
+#include "allocmem.h"
+#endif
+
+#if defined(SUPPORT_ION)
+#define ION_CLIENT_NAME_SIZE   50
+
+typedef struct _ENV_ION_CONNECTION_DATA_
+{
+       IMG_CHAR azIonClientName[ION_CLIENT_NAME_SIZE];
+       struct ion_device *psIonDev;
+       struct ion_client *psIonClient;
+       IMG_UINT32 ui32IonClientRefCount;
+} ENV_ION_CONNECTION_DATA;
+#endif
+
+typedef struct _ENV_CONNECTION_DATA_
+{
+       struct file *psFile;
+
+#if defined(SUPPORT_ION)
+       ENV_ION_CONNECTION_DATA *psIonData;
+#endif
+#if defined(SUPPORT_DRM_EXT)
+       IMG_VOID *pPriv;
+#endif
+} ENV_CONNECTION_DATA;
+
+#if defined(SUPPORT_ION)
+static inline struct ion_client *EnvDataIonClientAcquire(ENV_CONNECTION_DATA *psEnvData)
+{
+       PVR_ASSERT(psEnvData->psIonData != IMG_NULL);
+       PVR_ASSERT(psEnvData->psIonData->psIonClient != IMG_NULL);
+       PVR_ASSERT(psEnvData->psIonData->ui32IonClientRefCount > 0);
+       psEnvData->psIonData->ui32IonClientRefCount++;
+       return psEnvData->psIonData->psIonClient;
+}
+
+static inline void EnvDataIonClientRelease(ENV_ION_CONNECTION_DATA *psIonData)
+{
+       PVR_ASSERT(psIonData != IMG_NULL);
+       PVR_ASSERT(psIonData->psIonClient != IMG_NULL);
+       PVR_ASSERT(psIonData->ui32IonClientRefCount > 0);
+       if (--psIonData->ui32IonClientRefCount == 0)
+       {
+               ion_client_destroy(psIonData->psIonClient);
+               IonDevRelease(psIonData->psIonDev);
+               OSFreeMem(psIonData);
+               psIonData = IMG_NULL;
+       }
+}
+#endif /* defined(SUPPORT_ION) */
+
+#endif /* !defined(_ENV_CONNECTION_H_) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/env_data.h b/drivers/gpu/rogue_m/services/server/env/linux/env_data.h
new file mode 100644 (file)
index 0000000..7e5eb03
--- /dev/null
@@ -0,0 +1,56 @@
+/*************************************************************************/ /*!
+@File
+@Title          Environmental Data header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Linux-specific part of system data.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _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
+
+#endif /* _ENV_DATA_ */
+/*****************************************************************************
+ End of file (env_data.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/event.c b/drivers/gpu/rogue_m/services/server/env/linux/event.c
new file mode 100644 (file)
index 0000000..c54ca21
--- /dev/null
@@ -0,0 +1,361 @@
+/*************************************************************************/ /*!
+@File
+@Title          Event Object
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) )
+#include <asm/system.h>
+#endif
+#include <linux/mm.h>
+#include <linux/slab.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 <linux/sched.h>
+#include <asm/uaccess.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "allocmem.h"
+#include "mm.h"
+#include "env_data.h"
+#include "driverlock.h"
+#include "event.h"
+#include "pvr_debug.h"
+#include "pvrsrv.h"
+
+#include "osfunc.h"
+
+/* Returns pointer to task_struct that belongs to thread which acquired
+ * bridge lock. */
+extern struct task_struct *OSGetBridgeLockOwner(void);
+
+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;
+       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList;
+} PVRSRV_LINUX_EVENT_OBJECT;
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectListCreate
+
+ @Description
+
+ Linux wait object list creation
+
+ @Output    hOSEventKM : Pointer to the event object list handle
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
+{
+       PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList;
+
+       psEvenObjectList = OSAllocMem(sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST));
+       if (psEvenObjectList == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       INIT_LIST_HEAD(&psEvenObjectList->sList);
+
+       rwlock_init(&psEvenObjectList->sLock);
+
+       *phEventObjectList = (IMG_HANDLE *) psEvenObjectList;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectListDestroy
+
+ @Description
+
+ Linux wait object list destruction
+
+ @Input    hOSEventKM : Event object list handle
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
+{
+
+       PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
+
+       if(psEvenObjectList)
+       {
+               if (!list_empty(&psEvenObjectList->sList))
+               {
+                        PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
+                        return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+               }
+               OSFreeMem(psEvenObjectList);
+               /*not nulling pointer, copy on stack*/
+       }
+       return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectDelete
+
+ @Description
+
+ Linux wait object removal
+
+ @Input    hOSEventObject : Event object handle
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject)
+{
+       if(hOSEventObject)
+       {
+               PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
+               PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+
+               write_lock_bh(&psLinuxEventObjectList->sLock);
+               list_del(&psLinuxEventObject->sList);
+               write_unlock_bh(&psLinuxEventObjectList->sLock);
+
+#if defined(DEBUG)
+//             PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDelete: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+
+               OSFreeMem(psLinuxEventObject);
+               /*not nulling pointer, copy on stack*/
+
+               return PVRSRV_OK;
+       }
+       return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+}
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectAdd
+
+ @Description
+
+ Linux wait object addition
+
+ @Input    hOSEventObjectList : Event object list handle
+ @Output   phOSEventObject : Pointer to the event object handle
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+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;
+
+       /* allocate completion variable */
+       psLinuxEventObject = OSAllocMem(sizeof(PVRSRV_LINUX_EVENT_OBJECT));
+       if (psLinuxEventObject == IMG_NULL)
+       {
+               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;
+
+       write_lock_bh(&psLinuxEventObjectList->sLock);
+       list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
+       write_unlock_bh(&psLinuxEventObjectList->sLock);
+
+       *phOSEventObject = psLinuxEventObject;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectSignal
+
+ @Description
+
+ Linux wait object signaling function
+
+ @Input    hOSEventObjectList : Event object list handle
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList)
+{
+       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
+       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
+       struct list_head *psListEntry, *psListEntryTemp, *psList;
+       psList = &psLinuxEventObjectList->sList;
+
+       read_lock_bh(&psLinuxEventObjectList->sLock);
+       list_for_each_safe(psListEntry, psListEntryTemp, 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_bh(&psLinuxEventObjectList->sLock);
+
+       return  PVRSRV_OK;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function     LinuxEventObjectWait
+
+ @Description
+
+ Linux wait object routine
+
+ @Input    hOSEventObject : Event object handle
+
+ @Input   ui32MSTimeout : Time out value in msec
+
+ @Return   PVRSRV_ERROR  :  Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout, IMG_BOOL bHoldBridgeLock)
+{
+       IMG_UINT32 ui32TimeStamp;
+       IMG_BOOL bReleasePVRLock;
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       DEFINE_WAIT(sWait);
+
+       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
+
+       IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
+
+       /* Check if the driver is good shape */
+       if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+       {
+               return PVRSRV_ERROR_TIMEOUT;
+       }
+
+       do
+       {
+               prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
+               ui32TimeStamp = (IMG_UINT32)atomic_read(&psLinuxEventObject->sTimeStamp);
+
+               if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp)
+               {
+                       break;
+               }
+
+               /* Check thread holds the current PVR/bridge lock before obeying the
+                * 'release before deschedule' behaviour. Some threads choose not to
+                * hold the bridge lock in their implementation.
+                */
+               bReleasePVRLock = (!bHoldBridgeLock && mutex_is_locked(&gPVRSRVLock) && current == OSGetBridgeLockOwner());
+               if (bReleasePVRLock == IMG_TRUE)
+               {
+                       OSReleaseBridgeLock();
+               }
+
+               ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
+
+               if (bReleasePVRLock == IMG_TRUE)
+               {
+                       OSAcquireBridgeLock();
+               }
+
+#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/gpu/rogue_m/services/server/env/linux/event.h b/drivers/gpu/rogue_m/services/server/env/linux/event.h
new file mode 100644 (file)
index 0000000..9063f88
--- /dev/null
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@File
+@Title          Event Object 
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+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 hOSEventObject);
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout, IMG_BOOL bHoldBridgeLock);
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/handle_idr.c b/drivers/gpu/rogue_m/services/server/env/linux/handle_idr.c
new file mode 100644 (file)
index 0000000..5b5ecf6
--- /dev/null
@@ -0,0 +1,445 @@
+/*************************************************************************/ /*!
+@File
+@Title         Resource Handle Manager - IDR Back-end
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Provide IDR based resource handle management back-end
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/idr.h>
+
+#include "handle_impl.h"
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+
+#define ID_VALUE_MIN   1
+#define ID_VALUE_MAX   INT_MAX
+
+#define        ID_TO_HANDLE(i) ((IMG_HANDLE)(IMG_UINTPTR_T)(i))
+#define        HANDLE_TO_ID(h) ((IMG_INT)(IMG_UINTPTR_T)(h))
+
+struct _HANDLE_IMPL_BASE_
+{
+       struct idr sIdr;
+
+       IMG_UINT32 ui32MaxHandleValue;
+
+       IMG_UINT32 ui32TotalHandCount;
+};
+
+typedef struct _HANDLE_ITER_DATA_WRAPPER_
+{
+       PFN_HANDLE_ITER pfnHandleIter;
+       void *pvHandleIterData;
+} HANDLE_ITER_DATA_WRAPPER;
+
+
+static int HandleIterFuncWrapper(int id, void *data, void *iter_data)
+{
+       HANDLE_ITER_DATA_WRAPPER *psIterData = (HANDLE_ITER_DATA_WRAPPER *)iter_data;
+
+       PVR_UNREFERENCED_PARAMETER(data);
+
+       return (int)psIterData->pfnHandleIter(ID_TO_HANDLE(id), psIterData->pvHandleIterData);
+}
+
+/*!
+******************************************************************************
+
+ @Function     AcquireHandle
+
+ @Description  Acquire a new handle
+
+ @Input                psBase - Pointer to handle base structure
+               phHandle - Points to a handle pointer
+               pvData - Pointer to resource to be associated with the handle
+
+ @Output       phHandle - Points to a handle pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR AcquireHandle(HANDLE_IMPL_BASE *psBase, 
+                                 IMG_HANDLE *phHandle, 
+                                 void *pvData)
+{
+       int id;
+       int result;
+
+       PVR_ASSERT(psBase != IMG_NULL);
+       PVR_ASSERT(phHandle != IMG_NULL);
+       PVR_ASSERT(pvData != IMG_NULL);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+       idr_preload(GFP_KERNEL);
+       id = idr_alloc(&psBase->sIdr, pvData, ID_VALUE_MIN, psBase->ui32MaxHandleValue + 1, 0);
+       idr_preload_end();
+
+       result = id;
+#else
+       do
+       {
+               if (idr_pre_get(&psBase->sIdr, GFP_KERNEL) == 0)
+               {
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+
+               result = idr_get_new_above(&psBase->sIdr, pvData, ID_VALUE_MIN, &id);
+       } while (result == -EAGAIN);
+
+       if ((IMG_UINT32)id > psBase->ui32MaxHandleValue)
+       {
+               idr_remove(&psBase->sIdr, id);
+               result = -ENOSPC;
+       }
+#endif
+
+       if (result < 0)
+       {
+               if (result == -ENOSPC)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Limit of %u handles reached", 
+                                __FUNCTION__, psBase->ui32MaxHandleValue));
+
+                       return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+               }
+
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psBase->ui32TotalHandCount++;
+
+       *phHandle = ID_TO_HANDLE(id);
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     ReleaseHandle
+
+ @Description  Release a handle that is no longer needed.
+
+ @Input                psBase - Pointer to handle base structure
+               hHandle - Handle to release
+               ppvData - Points to a void data pointer
+
+ @Output       ppvData - Points to a void data pointer
+
+ @Return       PVRSRV_OK or PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR ReleaseHandle(HANDLE_IMPL_BASE *psBase, 
+                                 IMG_HANDLE hHandle, 
+                                 void **ppvData)
+{
+       int id = HANDLE_TO_ID(hHandle);
+       void *pvData;
+
+       PVR_ASSERT(psBase);
+
+       /* Get the data associated with the handle. If we get back NULL then 
+          it's an invalid handle */
+
+       pvData = idr_find(&psBase->sIdr, id);
+       if (pvData)
+       {
+               idr_remove(&psBase->sIdr, id);
+               psBase->ui32TotalHandCount--;
+       }
+
+       if (pvData == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Handle out of range (%u > %u)", 
+                        __FUNCTION__, id, psBase->ui32TotalHandCount));
+               return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+       }
+
+       if (ppvData)
+       {
+               *ppvData = pvData;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     GetHandleData
+
+ @Description  Get the data associated with the given handle
+
+ @Input                psBase - Pointer to handle base structure
+               hHandle - Handle from which data should be retrieved
+                ppvData - Points to a void data pointer
+
+ @Output       ppvData - Points to a void data pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR GetHandleData(HANDLE_IMPL_BASE *psBase, 
+                                 IMG_HANDLE hHandle, 
+                                 void **ppvData)
+{
+       int id = HANDLE_TO_ID(hHandle);
+       void *pvData;
+
+       PVR_ASSERT(psBase);
+       PVR_ASSERT(ppvData);
+
+       pvData = idr_find(&psBase->sIdr, id);
+       if (pvData)
+       {
+               *ppvData = pvData;
+
+               return PVRSRV_OK;
+       }
+       else
+       {
+               return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+       }
+}
+
+/*!
+******************************************************************************
+
+ @Function     SetHandleData
+
+ @Description  Set the data associated with the given handle
+
+ @Input                psBase - Pointer to handle base structure
+               hHandle - Handle for which data should be changed
+               pvData - Pointer to new data to be associated with the handle
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR SetHandleData(HANDLE_IMPL_BASE *psBase, 
+                                 IMG_HANDLE hHandle, 
+                                 void *pvData)
+{
+       int id = HANDLE_TO_ID(hHandle);
+       void *pvOldData;
+
+       PVR_ASSERT(psBase);
+
+       pvOldData = idr_replace(&psBase->sIdr, pvData, id);
+       if (IS_ERR(pvOldData))
+       {
+               if (PTR_ERR(pvOldData) == -ENOENT)
+               {
+                       return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
+               }
+               else
+               {
+                       return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR IterateOverHandles(HANDLE_IMPL_BASE *psBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData)
+{
+       HANDLE_ITER_DATA_WRAPPER sIterData;
+
+       PVR_ASSERT(psBase);
+       PVR_ASSERT(pfnHandleIter);
+
+       sIterData.pfnHandleIter = pfnHandleIter;
+       sIterData.pvHandleIterData = pvHandleIterData;
+
+       return (PVRSRV_ERROR)idr_for_each(&psBase->sIdr, HandleIterFuncWrapper, &sIterData);
+}
+
+/*!
+******************************************************************************
+
+ @Function     EnableHandlePurging
+
+ @Description  Enable purging for a given handle base
+
+ @Input        psBase - pointer to handle base structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR EnableHandlePurging(HANDLE_IMPL_BASE *psBase)
+{
+       PVR_UNREFERENCED_PARAMETER(psBase);
+       PVR_ASSERT(psBase);
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     PurgeHandles
+
+ @Description  Purge handles for a given handle base
+
+ @Input        psBase - Pointer to handle base structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR PurgeHandles(HANDLE_IMPL_BASE *psBase)
+{
+       PVR_UNREFERENCED_PARAMETER(psBase);
+       PVR_ASSERT(psBase);
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     CreateHandleBase
+
+ @Description  Create a handle base structure
+
+ @Input        ppsBase - pointer to handle base structure pointer
+
+ @Output       ppsBase - points to handle base structure pointer
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR CreateHandleBase(HANDLE_IMPL_BASE **ppsBase)
+{
+       HANDLE_IMPL_BASE *psBase;
+
+       PVR_ASSERT(ppsBase);
+
+       psBase = OSAllocZMem(sizeof(*psBase));
+       if (psBase == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't allocate generic handle base", __FUNCTION__));
+
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       idr_init(&psBase->sIdr);
+
+       psBase->ui32MaxHandleValue = ID_VALUE_MAX;
+       psBase->ui32TotalHandCount = 0;
+
+       *ppsBase = psBase;
+
+       return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function     DestroyHandleBase
+
+ @Description  Destroy a handle base structure
+
+ @Input        psBase - pointer to handle base structure
+
+ @Return       Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR DestroyHandleBase(HANDLE_IMPL_BASE *psBase)
+{
+       PVR_ASSERT(psBase);
+
+       if (psBase->ui32TotalHandCount != 0)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "%s: Handles still exist (%u found)", 
+                        __FUNCTION__, psBase->ui32TotalHandCount));
+       }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
+       idr_remove_all(&psBase->sIdr);
+#endif
+
+       /* Finally destroy the idr */
+       idr_destroy(&psBase->sIdr);
+
+       OSFreeMem(psBase);
+
+       return PVRSRV_OK;
+}
+
+
+static const HANDLE_IMPL_FUNCTAB g_sHandleFuncTab = 
+{
+       .pfnAcquireHandle = AcquireHandle,
+       .pfnReleaseHandle = ReleaseHandle,
+       .pfnGetHandleData = GetHandleData,
+       .pfnSetHandleData = SetHandleData,
+       .pfnIterateOverHandles = IterateOverHandles,
+       .pfnEnableHandlePurging = EnableHandlePurging,
+       .pfnPurgeHandles = PurgeHandles,
+       .pfnCreateHandleBase = CreateHandleBase,
+       .pfnDestroyHandleBase = DestroyHandleBase
+};
+
+PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs)
+{
+       static IMG_BOOL bAcquired = IMG_FALSE;
+
+       if (bAcquired)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Function table already acquired", 
+                        __FUNCTION__));
+               return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+       }
+
+       if (ppsFuncs == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *ppsFuncs = &g_sHandleFuncTab;
+
+       bAcquired = IMG_TRUE;
+
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/linkage.h b/drivers/gpu/rogue_m/services/server/env/linux/linkage.h
new file mode 100644 (file)
index 0000000..ddbb255
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux specific Services code internal interfaces
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Interfaces between various parts of the Linux specific
+                Services code, that don't have any other obvious
+                header file to go into.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__LINKAGE_H__)
+#define __LINKAGE_H__
+
+/*
+ * FIXME: This is declared here to save creating a new header which should be
+ * removed soon anyway as bridge gen should be providing this interface.
+ */
+PVRSRV_ERROR LinuxBridgeInit(void);
+PVRSRV_ERROR LinuxBridgeDeInit(void);
+
+#if !defined(SUPPORT_DRM)
+long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
+
+#if defined(CONFIG_COMPAT)
+long PVRSRV_BridgeCompatDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
+#endif
+#endif
+
+PVRSRV_ERROR PVROSFuncInit(void);
+void PVROSFuncDeInit(void);
+
+int PVRDebugCreateDebugFSEntries(void);
+void PVRDebugRemoveDebugFSEntries(void);
+
+int MMapPMR(struct file *file, struct vm_area_struct *ps_vma);
+
+#endif /* !defined(__LINKAGE_H__) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/mm.c b/drivers/gpu/rogue_m/services/server/env/linux/mm.c
new file mode 100644 (file)
index 0000000..6bb2d29
--- /dev/null
@@ -0,0 +1,107 @@
+/*************************************************************************/ /*!
+@File
+@Title          Misc memory management utility functions for Linux
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <asm/io.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "mm.h"
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_server_utils.h"
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
+ #if defined(CONFIG_ARM)
+  #define ioremap_cache(x,y) ioremap_cached(x,y)
+ #endif
+#endif
+
+void *
+_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+               IMG_UINT32 ui32Bytes,
+               IMG_UINT32 ui32MappingFlags,
+               IMG_CHAR *pszFileName,
+               IMG_UINT32 ui32Line)
+{
+       void *pvIORemapCookie;
+       IMG_UINT32 ui32CPUCacheMode = DevmemCPUCacheMode(ui32MappingFlags);
+
+       switch (ui32CPUCacheMode)
+       {
+               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+                               pvIORemapCookie = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
+                               break;
+               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+                               pvIORemapCookie = (void *)ioremap_wc(BasePAddr.uiAddr, ui32Bytes);
+#else
+                               pvIORemapCookie = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
+#endif
+                               break;
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+                               pvIORemapCookie = (void *)ioremap_cache(BasePAddr.uiAddr, ui32Bytes);
+#else
+                               pvIORemapCookie = (void *)ioremap(BasePAddr.uiAddr, ui32Bytes);
+#endif
+                               break;
+               default:
+                               return IMG_NULL;
+                               break;
+       }
+
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+
+    return pvIORemapCookie;
+}
+
+
+void
+_IOUnmapWrapper(void *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+    PVR_UNREFERENCED_PARAMETER(pszFileName);
+    PVR_UNREFERENCED_PARAMETER(ui32Line);
+
+    iounmap(pvIORemapCookie);
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/mm.h b/drivers/gpu/rogue_m/services/server/env/linux/mm.h
new file mode 100644 (file)
index 0000000..e8a4447
--- /dev/null
@@ -0,0 +1,86 @@
+/*************************************************************************/ /*!
+@File
+@Title          Declares various memory management utility functions for Linux.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __IMG_LINUX_MM_H__
+#define __IMG_LINUX_MM_H__
+
+#include <asm/io.h>
+/*!
+ *******************************************************************************
+ * @brief Reserve physical IO memory and create a CPU virtual mapping for it
+ *
+ * @param BasePAddr 
+ * @param ui32Bytes  
+ * @param ui32MappingFlags  
+ *
+ * @return 
+ ******************************************************************************/
+#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
+void *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+                                         IMG_UINT32 ui32Bytes,
+                                         IMG_UINT32 ui32MappingFlags,
+                                         IMG_CHAR *pszFileName,
+                                         IMG_UINT32 ui32Line);
+
+/*!
+ ******************************************************************************
+ * @brief Unmaps an IO memory mapping created using IORemap
+ *
+ * @param pvIORemapCookie  
+ *
+ * @return 
+ ******************************************************************************/
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define IOUnmapWrapper(pvIORemapCookie) \
+       _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
+#else
+#define IOUnmapWrapper(pvIORemapCookie) \
+       _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
+#endif
+void _IOUnmapWrapper(void *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
+
+#endif /* __IMG_LINUX_MM_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/mmap.c b/drivers/gpu/rogue_m/services/server/env/linux/mmap.c
new file mode 100644 (file)
index 0000000..a522b40
--- /dev/null
@@ -0,0 +1,546 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux mmap interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <asm/io.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "linkage.h"
+#include "handle.h"
+#include "pvrsrv.h"
+#include "connection_server.h"
+#include "devicemem_server_utils.h"
+#include "allocmem.h"
+
+#include "private_data.h"
+#include "driverlock.h"
+
+#if defined(SUPPORT_DRM)
+#include "pvr_drm.h"
+#endif
+
+/* WARNING!
+ * The mmap code has its own mutex, to prevent a possible deadlock,
+ * when using gPVRSRVLock.
+ * The Linux kernel takes the mm->mmap_sem before calling the mmap
+ * entry points (PVRMMap, MMapVOpen, MMapVClose), but the ioctl
+ * entry point may take mm->mmap_sem during fault handling, or 
+ * before calling get_user_pages.  If gPVRSRVLock was used in the
+ * mmap entry points, a deadlock could result, due to the ioctl
+ * and mmap code taking the two locks in different orders.
+ * As a corollary to this, the mmap entry points must not call
+ * any driver code that relies on gPVRSRVLock is held.
+ */
+static DEFINE_MUTEX(g_sMMapMutex);
+
+#include "pmr.h"
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+
+/*
+ * x86_32:
+ * Use vm_insert_page because remap_pfn_range has issues when mapping HIGHMEM
+ * pages with default memory attributes; these HIGHMEM pages are skipped in
+ * set_pages_array_[uc,wc] during allocation; see reserve_pfn_range().
+ * Also vm_insert_page is faster.
+ *
+ * x86_64:
+ * Use vm_insert_page because it is faster.
+ *
+ * Other platforms:
+ * Use remap_pfn_range by default because it does not issue a cache flush.
+ * It is known that ARM32 benefits from this. When other platforms become
+ * available it has to be investigated if this asumption holds for them as well.
+ *
+ * Since vm_insert_page does more precise memory accounting we have the build
+ * flag PVR_MMAP_USE_VM_INSERT that forces its use. This is useful as a debug
+ * feature.
+ *
+ */
+#if defined(CONFIG_X86) || defined(PVR_MMAP_USE_VM_INSERT)
+#define MMAP_USE_VM_INSERT_PAGE 1
+#endif
+
+static void MMapPMROpen(struct vm_area_struct* ps_vma)
+{
+       PMR *psPMR = ps_vma->vm_private_data;
+
+       /* Our VM flags should ensure this function never gets called */
+       PVR_DPF((PVR_DBG_WARNING,
+                        "%s: Unexpected mmap open call, this is probably an application bug.",
+                        __func__));
+       PVR_DPF((PVR_DBG_WARNING,
+                        "%s: vma struct: 0x%p, vAddr: %#lX, length: %#lX, PMR pointer: 0x%p",
+                        __func__,
+                        ps_vma,
+                        ps_vma->vm_start,
+                        ps_vma->vm_end - ps_vma->vm_start,
+                        psPMR));
+
+       /* In case we get called anyway let's do things right by increasing the refcount and
+        * locking down the physical addresses. */
+       PMRRefPMR(psPMR);
+
+       if (PMRLockSysPhysAddresses(psPMR, PAGE_SHIFT) != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Could not lock down physical addresses, aborting.", __func__));
+               PMRUnrefPMR(psPMR);
+       }
+}
+
+static void MMapPMRClose(struct vm_area_struct *ps_vma)
+{
+    PMR *psPMR;
+    IMG_UINTPTR_T  vAddr = ps_vma->vm_start;
+    IMG_SIZE_T pageSize = OSGetPageSize();
+
+    psPMR = ps_vma->vm_private_data;
+
+    while (vAddr < ps_vma->vm_end)
+    {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+    /* USER MAPPING */
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+    PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, PAGE_SIZE);
+#else
+       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, (IMG_UINT64)vAddr);
+#endif
+#endif
+       vAddr += pageSize;
+    }
+
+    PMRUnlockSysPhysAddresses(psPMR);
+    PMRUnrefPMR(psPMR);
+}
+
+/*
+ * This vma operation is used to read data from mmap regions. It is called
+ * by access_process_vm, which is called to handle PTRACE_PEEKDATA ptrace
+ * requests and reads from /proc/<pid>/mem.
+ */
+static int MMapVAccess(struct vm_area_struct *ps_vma, unsigned long addr,
+                                          void *buf, int len, int write)
+{
+    PMR *psPMR;
+    unsigned long ulOffset;
+    IMG_SIZE_T uiBytesCopied;
+    PVRSRV_ERROR eError;
+    int iRetVal = -EINVAL;
+
+    psPMR = ps_vma->vm_private_data;
+
+    ulOffset = addr - ps_vma->vm_start;
+
+       if (write)
+       {
+               eError = PMR_WriteBytes(psPMR,
+                                                               (IMG_DEVMEM_OFFSET_T) ulOffset,
+                                                               buf,
+                                                               len,
+                                                               &uiBytesCopied);
+       }
+       else
+       {
+               eError = PMR_ReadBytes(psPMR,
+                                                          (IMG_DEVMEM_OFFSET_T) ulOffset,
+                                                          buf,
+                                                          len,
+                                                          &uiBytesCopied);
+       }
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Error from %s (%d)",
+                                __FUNCTION__,
+                                write?"PMR_WriteBytes":"PMR_ReadBytes",
+                                eError));
+       }
+       else
+       {
+               iRetVal = uiBytesCopied;
+       }
+
+       return iRetVal;
+}
+
+static struct vm_operations_struct gsMMapOps =
+{
+       .open=&MMapPMROpen,
+       .close=&MMapPMRClose,
+       .access=MMapVAccess,
+};
+
+int MMapPMR(struct file *pFile, struct vm_area_struct *ps_vma)
+{
+       PVRSRV_ERROR eError;
+       IMG_HANDLE hSecurePMRHandle;
+       IMG_SIZE_T uiLength;
+       IMG_DEVMEM_OFFSET_T uiOffset;
+       unsigned long uiPFN;
+       PMR *psPMR;
+       PMR_FLAGS_T ulPMRFlags;
+       IMG_UINT32 ui32CPUCacheFlags;
+       unsigned long ulNewFlags = 0;
+       pgprot_t sPageProt;
+       CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile);
+    IMG_CPU_PHYADDR asCpuPAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+    IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
+       IMG_UINT32 uiOffsetIdx, uiNumOfPFNs;
+       IMG_CPU_PHYADDR *psCpuPAddr;
+       IMG_BOOL *pbValid;
+#if defined(MMAP_USE_VM_INSERT_PAGE)
+       IMG_BOOL bMixedMap = IMG_FALSE;
+#endif
+
+       if(psConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Invalid connection data"));
+               goto em0;
+       }
+
+       /*
+        * The bridge lock used here to protect Both PVRSRVLookupHandle and ResManFindPrivateDataByPtr
+        * is replaced by a specific lock considering that the handle functions have now their own lock
+        * and ResManFindPrivateDataByPtr is going to be removed.
+        *  This change was necessary to solve the lockdep issues related with the MMapPMR
+        */
+       mutex_lock(&g_sMMapMutex);
+       PMRLock();
+
+#if defined(SUPPORT_DRM_DC_MODULE)
+       psPMR = PVRSRVGEMMMapLookupPMR(pFile, ps_vma);
+       if (!psPMR)
+#endif
+       {
+               hSecurePMRHandle = (IMG_HANDLE)((IMG_UINTPTR_T)ps_vma->vm_pgoff);
+
+               eError = PVRSRVLookupHandle(psConnection->psHandleBase,
+                                           (void **)&psPMR,
+                                           hSecurePMRHandle,
+                                           PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+               if (eError != PVRSRV_OK)
+               {
+                       goto e0;
+               }
+       }
+
+       /*
+        * Take a reference on the PMR, make's sure that it can't be freed
+        * while it's mapped into the user process
+        */
+       PMRRefPMR(psPMR);
+
+       PMRUnlock();
+
+       eError = PMRLockSysPhysAddresses(psPMR, PAGE_SHIFT);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
+           ((ps_vma->vm_flags & VM_SHARED) == 0))
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e1;
+       }
+
+       /*
+        * We ought to call PMR_Flags() here to check the permissions
+        * against the requested mode, and possibly to set up the cache
+        * control protflags
+        */
+       eError = PMR_Flags(psPMR, &ulPMRFlags);
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+       ulNewFlags = ps_vma->vm_flags;
+#if 0
+       /* Discard user read/write request, we will pull these flags from the PMR */
+       ulNewFlags &= ~(VM_READ | VM_WRITE);
+
+       if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_READABLE)
+       {
+               ulNewFlags |= VM_READ;
+       }
+       if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE)
+       {
+               ulNewFlags |= VM_WRITE;
+       }
+#endif
+
+       ps_vma->vm_flags = ulNewFlags;
+
+#if defined (CONFIG_ARM64)
+       sPageProt = __pgprot_modify(ps_vma->vm_page_prot, 0, vm_get_page_prot(ulNewFlags));
+#elif defined(CONFIG_ARM)
+       sPageProt = __pgprot_modify(ps_vma->vm_page_prot, L_PTE_MT_MASK, vm_get_page_prot(ulNewFlags));
+#elif defined(CONFIG_X86)
+       sPageProt = pgprot_modify(ps_vma->vm_page_prot, vm_get_page_prot(ulNewFlags));
+#elif defined(CONFIG_METAG) || defined(CONFIG_MIPS)
+       sPageProt = vm_get_page_prot(ulNewFlags);
+#else
+#error Please add pgprot_modify equivalent for your system
+#endif
+       ui32CPUCacheFlags = DevmemCPUCacheMode(ulPMRFlags);
+       switch (ui32CPUCacheFlags)
+       {
+               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+                               sPageProt = pgprot_noncached(sPageProt);
+                               break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+                               sPageProt = pgprot_writecombine(sPageProt);
+                               break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
+                               break;
+
+               default:
+                               eError = PVRSRV_ERROR_INVALID_PARAMS;
+                               goto e1;
+       }
+       ps_vma->vm_page_prot = sPageProt;
+
+    uiLength = ps_vma->vm_end - ps_vma->vm_start;
+
+    ps_vma->vm_flags |= VM_IO;
+
+/* Don't include the mapping in core dumps */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+    ps_vma->vm_flags |= VM_DONTDUMP;
+#else
+    ps_vma->vm_flags |= VM_RESERVED;
+#endif
+
+    /*
+     * Disable mremap because our nopage handler assumes all
+     * page requests have already been validated.
+     */
+    ps_vma->vm_flags |= VM_DONTEXPAND;
+    
+    /* Don't allow mapping to be inherited across a process fork */
+    ps_vma->vm_flags |= VM_DONTCOPY;
+
+    /* Can we use stack allocations */
+    uiNumOfPFNs = uiLength >> PAGE_SHIFT;
+    if (uiNumOfPFNs > PMR_MAX_TRANSLATION_STACK_ALLOC)
+    {
+       psCpuPAddr = OSAllocMem(uiNumOfPFNs * sizeof(IMG_CPU_PHYADDR));
+       if (psCpuPAddr == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e2;
+       }
+       
+       /* Should allocation fail, clean-up here before exiting */
+       pbValid = OSAllocMem(uiNumOfPFNs * sizeof(IMG_BOOL));
+       if (pbValid == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               OSFreeMem(psCpuPAddr);
+               goto e2;
+       }
+    }
+    else
+    {
+               psCpuPAddr = asCpuPAddr;
+               pbValid = abValid;
+    }
+    
+    /* Obtain map range pfns */
+       eError = PMR_CpuPhysAddr(psPMR,
+                                                        PAGE_SHIFT,
+                                                        uiNumOfPFNs,
+                                                        0,
+                                                        psCpuPAddr,
+                                                        pbValid);
+       if (eError)
+       {
+               goto e3;
+       }
+
+#if defined(MMAP_USE_VM_INSERT_PAGE)
+       /*
+        * Scan the map range for pfns without struct page* handling. If
+        * we find one, this is a mixed map, and we can't use
+        * vm_insert_page()
+        */
+       for (uiOffsetIdx = 0; uiOffsetIdx < uiNumOfPFNs; ++uiOffsetIdx)
+       {
+               if (pbValid[uiOffsetIdx])
+               {
+                       uiPFN = psCpuPAddr[uiOffsetIdx].uiAddr >> PAGE_SHIFT;
+                       PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == psCpuPAddr[uiOffsetIdx].uiAddr);
+
+                       if (!pfn_valid(uiPFN) || page_count(pfn_to_page(uiPFN)) == 0)
+                       {
+                               bMixedMap = IMG_TRUE;
+                               break;
+                       }
+               }
+       }
+
+       if (bMixedMap)
+       {
+               ps_vma->vm_flags |= VM_MIXEDMAP;
+       }
+#else
+       ps_vma->vm_flags |= VM_PFNMAP;
+#endif /* MMAP_USE_VM_INSERT_PAGE */
+
+    for (uiOffset = 0; uiOffset < uiLength; uiOffset += 1ULL<<PAGE_SHIFT)
+    {
+        IMG_SIZE_T uiNumContiguousBytes;
+        IMG_INT32 iStatus;
+
+        uiNumContiguousBytes = 1ULL<<PAGE_SHIFT;
+        uiOffsetIdx = uiOffset >> PAGE_SHIFT;
+
+               /*
+                       Only map in pages that are valid, any that aren't will be picked up
+                       by the nopage handler which will return a zeroed page for us
+               */
+               if (pbValid[uiOffsetIdx])
+               {
+               uiPFN = psCpuPAddr[uiOffsetIdx].uiAddr >> PAGE_SHIFT;
+               PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == psCpuPAddr[uiOffsetIdx].uiAddr);
+
+#if defined(MMAP_USE_VM_INSERT_PAGE)
+                       if (bMixedMap)
+                       {
+                               /*
+                                * This path is just for debugging. It should be
+                                * equivalent to the remap_pfn_range() path.
+                                */
+                               iStatus = vm_insert_mixed(ps_vma,
+                                                         ps_vma->vm_start + uiOffset,
+                                                         uiPFN);
+                       }
+                       else
+                       {
+                               /* Since kernel 3.7 this sets VM_MIXEDMAP internally */
+                               iStatus = vm_insert_page(ps_vma,
+                                                        ps_vma->vm_start + uiOffset,
+                                                        pfn_to_page(uiPFN));
+                       }
+#else
+                       iStatus = remap_pfn_range(ps_vma,
+                                                 ps_vma->vm_start + uiOffset,
+                                                 uiPFN,
+                                                 uiNumContiguousBytes,
+                                                 ps_vma->vm_page_prot);
+#endif  /* MMAP_USE_VM_INSERT_PAGE */
+
+               PVR_ASSERT(iStatus == 0);
+               if(iStatus)
+               {
+                   // N.B. not the right error code, but, it doesn't get propagated anyway... :(
+                   eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+       
+                   goto e3;
+               }
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+    /* USER MAPPING*/
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+           PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, PAGE_SIZE);
+#else
+       PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES,
+                                                        (IMG_VOID*)(IMG_UINTPTR_T)(ps_vma->vm_start + uiOffset),
+                                                        psCpuPAddr[uiOffsetIdx],
+                                                                PAGE_SIZE,
+                                                                IMG_NULL);
+#endif
+#endif
+
+               }
+        (void)pFile;
+    }
+    
+    if (psCpuPAddr != asCpuPAddr)
+    {
+       OSFreeMem(psCpuPAddr);
+       OSFreeMem(pbValid);
+    }
+
+    /* let us see the PMR so we can unlock it later */
+    ps_vma->vm_private_data = psPMR;
+
+    /* Install open and close handlers for ref-counting */
+    ps_vma->vm_ops = &gsMMapOps;
+
+       mutex_unlock(&g_sMMapMutex);
+
+    return 0;
+
+    /*
+      error exit paths follow
+    */
+ e3:
+       if (psCpuPAddr != asCpuPAddr)
+       {
+               OSFreeMem(psCpuPAddr);
+               OSFreeMem(pbValid);
+       }
+ e2:
+    PVR_DPF((PVR_DBG_ERROR, "don't know how to handle this error.  Abort!"));
+    PMRUnlockSysPhysAddresses(psPMR);
+ e1:
+       PMRUnrefPMR(psPMR);
+       goto em1;
+ e0:
+    PVR_DPF((PVR_DBG_ERROR, "Error in MMapPMR critical section"));
+       PMRUnlock();
+ em1:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    PVR_DPF((PVR_DBG_ERROR, "unable to translate error %d", eError));
+       mutex_unlock(&g_sMMapMutex);
+ em0:
+    return -ENOENT; // -EAGAIN // or what?
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/module.c b/drivers/gpu/rogue_m/services/server/env/linux/module.c
new file mode 100644 (file)
index 0000000..62c8f2e
--- /dev/null
@@ -0,0 +1,635 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux module setup
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
+#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
+#endif
+
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include <linux/fs.h>
+
+#if defined(LDM_PLATFORM)
+#include <linux/dma-mapping.h>
+#endif
+
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "pvrmodule.h"
+#include "linkage.h"
+#include "sysinfo.h"
+#include "module_common.h"
+
+#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+#include "syscommon.h"
+#endif
+
+#if defined(SUPPORT_SHARED_SLC)
+#include "rgxapi_km.h"
+#endif
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+#include "kerneldisplay.h"
+#endif
+
+/*
+ * DRVNAME is the name we use to register our driver.
+ * DEVNAME is the name we use to register actual device nodes.
+ */
+#define        DRVNAME         PVR_LDM_DRIVER_REGISTRATION_NAME
+#define DEVNAME                PVRSRV_MODNAME
+
+/*
+ * This is all module configuration stuff required by the linux kernel.
+ */
+MODULE_SUPPORTED_DEVICE(DEVNAME);
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+/* Display class interface */
+#include "kerneldisplay.h"
+EXPORT_SYMBOL(DCRegisterDevice);
+EXPORT_SYMBOL(DCUnregisterDevice);
+EXPORT_SYMBOL(DCDisplayConfigurationRetired);
+EXPORT_SYMBOL(DCDisplayHasPendingCommand);
+EXPORT_SYMBOL(DCImportBufferAcquire);
+EXPORT_SYMBOL(DCImportBufferRelease);
+
+/* Physmem interface (required by LMA DC drivers) */
+#include "physheap.h"
+EXPORT_SYMBOL(PhysHeapAcquire);
+EXPORT_SYMBOL(PhysHeapRelease);
+EXPORT_SYMBOL(PhysHeapGetType);
+EXPORT_SYMBOL(PhysHeapGetAddress);
+EXPORT_SYMBOL(PhysHeapGetSize);
+EXPORT_SYMBOL(PhysHeapCpuPAddrToDevPAddr);
+#endif
+
+/* System interface (required by DC drivers) */
+#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+EXPORT_SYMBOL(SysInstallDeviceLISR);
+EXPORT_SYMBOL(SysUninstallDeviceLISR);
+#endif
+
+#if defined(SUPPORT_SHARED_SLC)
+EXPORT_SYMBOL(RGXInitSLC);
+#endif
+#include "pvrversion.h"  //add by zxl
+
+#if defined(CONFIG_OF)
+#include <linux/of.h>
+#include <linux/of_device.h>
+#endif
+
+struct device *psDev;
+
+/*
+ * Device class used for /sys entries (and udev device node creation)
+ */
+static struct class *psPvrClass;
+
+/*
+ * This is the major number we use for all nodes in /dev.
+ */
+static int AssignedMajorNumber;
+
+static const struct of_device_id rockchip_gpu_dt_ids[] = {
+    { .compatible = "arm,rogue-G6110", },
+       { .compatible = "arm,rk3368-gpu", },
+       {},
+};
+
+/*
+ * These are the operations that will be associated with the device node
+ * we create.
+ *
+ * With gcc -W, specifying only the non-null members produces "missing
+ * initializer" warnings.
+*/
+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,
+#if defined(CONFIG_COMPAT)
+       .compat_ioctl   = PVRSRV_BridgeCompatDispatchKM,
+#endif
+       .open           = PVRSRVOpen,
+       .release        = PVRSRVRelease,
+       .mmap           = MMapPMR,
+};
+
+#if defined(LDM_PLATFORM)
+#define        LDM_DRV struct platform_driver
+#endif /*LDM_PLATFORM */
+
+#if defined(LDM_PCI)
+#define        LDM_DRV struct pci_driver
+#endif /* LDM_PCI */
+
+#if defined(LDM_PLATFORM)
+static int PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device);
+#endif
+
+#if defined(LDM_PCI)
+static void PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
+#endif
+
+#if defined(LDM_PCI)
+/* This structure is used by the Linux module code */
+struct pci_device_id powervr_id_table[] __devinitdata = {
+       {PCI_DEVICE(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV_DEVICE_ID)},
+#if defined (SYS_RGX_DEV1_DEVICE_ID)
+       {PCI_DEVICE(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV1_DEVICE_ID)},
+#endif
+       {0}
+};
+MODULE_DEVICE_TABLE(pci, powervr_id_table);
+#endif /*defined(LDM_PCI) */
+
+#if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static struct platform_device_id powervr_id_table[] __devinitdata = {
+       {SYS_RGX_DEV_NAME, 0},
+       {}
+};
+#endif
+
+static struct dev_pm_ops powervr_dev_pm_ops = {
+       .suspend        = PVRSRVDriverSuspend,
+       .resume         = PVRSRVDriverResume,
+};
+
+static LDM_DRV powervr_driver = {
+#if defined(LDM_PLATFORM)
+       .driver = {
+               .name   = DRVNAME,
+               .pm     = &powervr_dev_pm_ops,
+               .of_match_table = of_match_ptr(rockchip_gpu_dt_ids),
+       },
+#endif
+#if defined(LDM_PCI)
+       .name           = DRVNAME,
+       .driver.pm      = &powervr_dev_pm_ops,
+#endif
+#if defined(LDM_PCI) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+       .id_table       = powervr_id_table,
+#endif
+       .probe          = PVRSRVDriverProbe,
+#if defined(LDM_PLATFORM)
+       .remove         = PVRSRVDriverRemove,
+#endif
+#if defined(LDM_PCI)
+       .remove         = __devexit_p(PVRSRVDriverRemove),
+#endif
+       .shutdown       = PVRSRVDriverShutdown,
+};
+
+#if defined(LDM_PLATFORM)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+/*static void PVRSRVDeviceRelease(struct device unref__ *pDevice)
+{
+}
+
+static struct platform_device powervr_device =
+{
+       .name                   = DEVNAME,
+       .id                     = -1,
+       .dev                    = {
+               .release        = PVRSRVDeviceRelease
+       }
+};*/
+//time:2012-09-08
+//move platform_device_register from devices.c to sgx
+static struct resource resources_sgx[] = {
+    [0] = {
+        .name  = "gpu_irq",
+        .start     = IRQ_GPU,
+        .end    = IRQ_GPU,
+        .flags  = IORESOURCE_IRQ,
+    },
+    [1] = {
+        .name   = "gpu_base",
+        .start  = RK30_GPU_PHYS ,
+        .end    = RK30_GPU_PHYS  + RK30_GPU_SIZE - 1,
+        .flags  = IORESOURCE_MEM,
+    },
+};
+static struct platform_device powervr_device = {
+    .name             = DEVNAME,
+    .id               = 0,
+    .num_resources    = ARRAY_SIZE(resources_sgx),
+    .resource         = resources_sgx,
+};
+#else
+static struct platform_device_info powervr_device_info =
+{
+       .name                   = DEVNAME,
+       .id                     = -1,
+       .dma_mask               = DMA_BIT_MASK(32),
+};
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) */
+#endif /* defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) */
+#endif /* defined(LDM_PLATFORM) */
+
+static IMG_BOOL bCalledSysInit = IMG_FALSE;
+static IMG_BOOL        bDriverProbeSucceeded = IMG_FALSE;
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVSystemInit
+
+ @Description
+
+ Wrapper for PVRSRVInit.
+
+ @input pDevice - the device for which a probe is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+static int PVRSRVSystemInit(LDM_DEV *pDevice)
+{
+       PVR_TRACE(("PVRSRVSystemInit (pDevice=%p)", pDevice));
+
+       gpsPVRLDMDev = pDevice;
+       bCalledSysInit = IMG_TRUE;
+
+       if (PVRSRVInit(pDevice) != PVRSRV_OK)
+       {
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVSystemDeInit
+
+ @Description
+
+ Wrapper for PVRSRVDeInit.
+
+ @input pDevice - the device for which a probe is requested
+ @Return nothing.
+
+*****************************************************************************/
+static void PVRSRVSystemDeInit(LDM_DEV *pDevice)
+{
+       PVR_TRACE(("PVRSRVSystemDeInit"));
+
+       PVRSRVDeInit(pDevice);
+
+#if !defined(LDM_PLATFORM) || (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+       gpsPVRLDMDev = IMG_NULL;
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVDriverProbe
+
+ @Description
+
+ See whether a given device is really one we can drive.
+
+ @input pDevice - the device for which a probe is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(LDM_PLATFORM)
+static int PVRSRVDriverProbe(LDM_DEV *pDevice)
+#endif
+#if defined(LDM_PCI)
+static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *pID)
+#endif
+{
+       int result = 0;
+
+       PVR_TRACE(("PVRSRVDriverProbe (pDevice=%p)", pDevice));
+
+    //zxl:print gpu version on boot time
+    printk("PVR_K: sys.gpvr.version=%s\n",RKVERSION);
+
+       result = PVRSRVSystemInit(pDevice);
+       bDriverProbeSucceeded = (result == 0);
+       return result;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVDriverRemove
+
+ @Description
+
+ This call is the opposite of the probe call; it is called when the device is
+ being removed from the driver's control.
+
+ @input pDevice - the device for which driver detachment is happening
+
+ @Return 0, or no return value at all, depending on the device type.
+
+*****************************************************************************/
+#if defined (LDM_PLATFORM)
+static int PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+#if defined(LDM_PCI)
+static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+{
+       PVR_TRACE(("PVRSRVDriverRemove (pDevice=%p)", pDevice));
+
+       PVRSRVSystemDeInit(pDevice);
+
+#if defined(LDM_PLATFORM)
+       return 0;
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVOpen
+
+ @Description
+
+ Open the PVR services node.
+
+ @input pInode - the inode for the file being openeded.
+ @input dev    - the DRM device corresponding to this driver.
+
+ @input pFile - the file handle data for the actual file being opened
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+static int PVRSRVOpen(struct inode unref__ *pInode, struct file *pFile)
+{
+       int err;
+
+       if (!try_module_get(THIS_MODULE))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to get module"));
+               return -ENOENT;
+       }
+
+       if ((err = PVRSRVCommonOpen(pFile)) != 0)
+       {
+               module_put(THIS_MODULE);
+       }
+
+       return err;
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVRelease
+
+ @Description
+
+ Release access the PVR services node - called when a file is closed, whether
+ at exit or using close(2) system call.
+
+ @input pInode - the inode for the file being released
+ @input pvPrivData - driver private data
+
+ @input pFile - the file handle data for the actual file being released
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+static int PVRSRVRelease(struct inode unref__ *pInode, struct file *pFile)
+{
+       PVRSRVCommonRelease(pFile);
+
+       module_put(THIS_MODULE);
+
+       return 0;
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRCore_Init
+
+ @Description
+
+ Insert the driver into the kernel.
+
+ Readable and/or writable debugfs entries under /sys/kernel/debug/pvr are
+ created with PVRDebugFSCreateEntry().  These can be read at runtime to get
+ information about the device (eg. 'cat /sys/kernel/debug/pvr/nodes')
+
+ __init places the function in a special memory section that the kernel frees
+ once the function has been run.  Refer also to module_init() macro call below.
+
+ @input none
+
+ @Return none
+
+*****************************************************************************/
+static int __init PVRCore_Init(void)
+{
+       int error = 0;
+
+       PVR_TRACE(("PVRCore_Init"));
+
+       if ((error = PVRSRVDriverInit()) != 0)
+       {
+               return error;
+       }
+
+       AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
+       if (AssignedMajorNumber <= 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
+               return -EBUSY;
+       }
+
+       PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
+
+       /*
+        * This code facilitates automatic device node creation on platforms
+        * with udev (or similar).
+        */
+       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)));
+               return -EBUSY;
+       }
+
+       psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
+                                 NULL, DEVNAME);
+       if (IS_ERR(psDev))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
+               return -EBUSY;
+       }
+
+#if defined(LDM_PLATFORM)
+       error = platform_driver_register(&powervr_driver);
+       if (error != 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
+               return error;
+       }
+
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+       error = platform_device_register(&powervr_device);
+#else
+       gpsPVRLDMDev = platform_device_register_full(&powervr_device_info);
+       error = IS_ERR(gpsPVRLDMDev) ? PTR_ERR(gpsPVRLDMDev) : 0;
+#endif
+       if (error != 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
+               return error;
+       }
+#endif /* defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) */
+#endif /* defined(LDM_PLATFORM) */ 
+
+#if defined(LDM_PCI)
+       error = pci_register_driver(&powervr_driver);
+       if (error != 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
+               return error;
+       }
+#endif /* defined(LDM_PCI) */
+
+       /* Check that the driver probe function was called */
+       if (!bDriverProbeSucceeded)
+       {
+               PVR_TRACE(("PVRCore_Init: PVRSRVDriverProbe has not been called or did not succeed - check that hardware is detected"));
+               return error;
+       }
+
+       return PVRSRVDeviceInit();
+}
+
+
+/*!
+*****************************************************************************
+
+ @Function             PVRCore_Cleanup
+
+ @Description  
+
+ Remove the driver from the kernel.
+
+ There's no way we can get out of being unloaded other than panicking; we
+ just do everything and plough on regardless of error.
+
+ __exit places the function in a special memory section that the kernel frees
+ once the function has been run.  Refer also to module_exit() macro call below.
+
+ @input none
+
+ @Return none
+
+*****************************************************************************/
+static void __exit PVRCore_Cleanup(void)
+{
+       PVR_TRACE(("PVRCore_Cleanup"));
+
+       PVRSRVDeviceDeinit();
+
+       if (psDev)
+       {
+               device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
+       }
+
+       if (psPvrClass)
+       {
+               class_destroy(psPvrClass);
+       }
+
+       if (AssignedMajorNumber > 0)
+       {
+               unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME);
+       }
+
+#if defined(LDM_PCI)
+       pci_unregister_driver(&powervr_driver);
+#endif /* defined(LDM_PCI) */
+
+#if defined (LDM_PLATFORM)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
+       platform_device_unregister(&powervr_device);
+#else
+       PVR_ASSERT(gpsPVRLDMDev != NULL);
+       platform_device_unregister(gpsPVRLDMDev);
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) */
+#endif /* defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) */
+       platform_driver_unregister(&powervr_driver);
+#endif /* defined (LDM_PLATFORM) */
+
+       PVRSRVDriverDeinit();
+
+       PVR_TRACE(("PVRCore_Cleanup: unloading"));
+}
+
+/*
+ * These macro calls define the initialisation and removal functions of the
+ * driver.  Although they are prefixed `module_', they apply when compiling
+ * statically as well; in both cases they define the function the kernel will
+ * run to start/stop the driver.
+*/
+module_init(PVRCore_Init);
+module_exit(PVRCore_Cleanup);
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/module_common.c b/drivers/gpu/rogue_m/services/server/env/linux/module_common.c
new file mode 100644 (file)
index 0000000..d14c908
--- /dev/null
@@ -0,0 +1,495 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common linux module setup
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (!defined(LDM_PLATFORM) && !defined(LDM_PCI)) || \
+       (defined(LDM_PLATFORM) && defined(LDM_PCI))
+       #error "LDM_PLATFORM or LDM_PCI must be defined"
+#endif
+
+#include <linux/module.h>
+
+#include "pvr_debugfs.h"
+#include "private_data.h"
+#include "linkage.h"
+#include "power.h"
+#include "env_connection.h"
+#include "process_stats.h"
+#include "module_common.h"
+#include "pvrsrv.h"
+
+#if defined(SUPPORT_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if defined(SUPPORT_AUTH)
+#include "osauth.h"
+#endif
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+#include "pvr_sync.h"
+#endif
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+#include "pvr_gputrace.h"
+#endif
+
+#if defined(SUPPORT_KERNEL_HWPERF) || defined(SUPPORT_SHARED_SLC)
+#include "rgxapi_km.h"
+#endif
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+#include "srvinit.h"
+#endif
+
+#if defined(PVRSRV_NEED_PVR_DPF) || defined(DEBUG)
+#include <linux/moduleparam.h>
+#endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(DEBUG) */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+extern IMG_UINT32 gPVRDebugLevel;
+module_param(gPVRDebugLevel, uint, 0644);
+MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+#if defined(DEBUG)
+extern IMG_UINT32 gPMRAllocFail;
+module_param(gPMRAllocFail, uint, 0644);
+MODULE_PARM_DESC(gPMRAllocFail, "When number of PMR allocs reaches"
+        " this value, it will fail (default value is 0 which"
+        "means that alloc function will behave normally).");
+#endif /* defined(DEBUG) */
+
+/* Export some symbols that may be needed by other drivers */
+EXPORT_SYMBOL(PVRSRVCheckStatus);
+EXPORT_SYMBOL(PVRSRVGetErrorStringKM);
+
+#if defined(SUPPORT_KERNEL_HWPERF)
+#include "rgxapi_km.h"
+EXPORT_SYMBOL(RGXHWPerfConnect);
+EXPORT_SYMBOL(RGXHWPerfDisconnect);
+EXPORT_SYMBOL(RGXHWPerfControl);
+EXPORT_SYMBOL(RGXHWPerfConfigureAndEnableCounters);
+EXPORT_SYMBOL(RGXHWPerfDisableCounters);
+EXPORT_SYMBOL(RGXHWPerfAcquireData);
+EXPORT_SYMBOL(RGXHWPerfReleaseData);
+#endif
+
+DEFINE_MUTEX(gPVRSRVLock);
+
+static DEFINE_MUTEX(gsPMMutex);
+static IMG_BOOL bDriverIsSuspended;
+static IMG_BOOL bDriverIsShutdown;
+
+#if !defined(SUPPORT_DRM_EXT)
+LDM_DEV *gpsPVRLDMDev;
+#endif
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVDriverShutdown
+
+ @Description
+
+ Suspend device operation for system shutdown.  This is called as part of the
+ system halt/reboot process.  The driver is put into a quiescent state by
+ setting the power state to D3.
+
+ @input pDevice - the device for which shutdown is requested
+
+ @Return nothing
+
+*****************************************************************************/
+void PVRSRVDriverShutdown(LDM_DEV *pDevice)
+{
+       PVR_TRACE(("PVRSRVDriverShutdown (pDevice=%p)", pDevice));
+
+       mutex_lock(&gsPMMutex);
+
+       if (!bDriverIsShutdown && !bDriverIsSuspended)
+       {
+               /*
+                * Take the bridge mutex, and never release it, to stop
+                * processes trying to use the driver after it has been
+                * shutdown.
+                */
+               OSAcquireBridgeLock();
+
+               (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_OFF, IMG_TRUE);
+       }
+
+       bDriverIsShutdown = IMG_TRUE;
+
+       /* The bridge mutex is held on exit */
+       mutex_unlock(&gsPMMutex);
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVDriverSuspend
+
+ @Description
+
+ Suspend device operation.
+
+ @input pDevice - the device for which resume is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+int PVRSRVDriverSuspend(struct device *pDevice)
+{
+       int res = 0;
+
+       PVR_TRACE(( "PVRSRVDriverSuspend (pDevice=%p)", pDevice));
+
+       mutex_lock(&gsPMMutex);
+
+       if (!bDriverIsSuspended && !bDriverIsShutdown)
+       {
+               OSAcquireBridgeLock();
+
+               if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_OFF, IMG_TRUE) == PVRSRV_OK)
+               {
+                       bDriverIsSuspended = IMG_TRUE;
+                       OSSetDriverSuspended();
+               }
+               else
+               {
+                       res = -EINVAL;
+               }
+               OSReleaseBridgeLock();
+       }
+
+       mutex_unlock(&gsPMMutex);
+
+       return res;
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVDriverResume
+
+ @Description
+
+ Resume device operation.
+
+ @input pDevice - the device for which resume is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+int PVRSRVDriverResume(struct device *pDevice)
+{
+       int res = 0;
+
+       PVR_TRACE(("PVRSRVDriverResume (pDevice=%p)", pDevice));
+
+       mutex_lock(&gsPMMutex);
+
+       if (bDriverIsSuspended && !bDriverIsShutdown)
+       {
+               OSAcquireBridgeLock();
+
+               if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_ON, IMG_TRUE) == PVRSRV_OK)
+               {
+                       bDriverIsSuspended = IMG_FALSE;
+                       OSClearDriverSuspended();
+               }
+               else
+               {
+                       res = -EINVAL;
+               }
+               OSReleaseBridgeLock();
+       }
+
+       mutex_unlock(&gsPMMutex);
+
+       return res;
+}
+
+#if defined(SUPPORT_DRM)
+#define PRIVATE_DATA(pFile) (PVR_DRM_FILE_FROM_FILE(pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVCommonOpen
+
+ @Description
+
+ Open the PVR services node.
+
+ @input pFile - the file handle data for the actual file being opened
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+int PVRSRVCommonOpen(struct file *pFile)
+{
+       void *pvConnectionData;
+       PVRSRV_ERROR eError;
+
+       OSAcquireBridgeLock();
+
+       /*
+        * Here we pass the file pointer which will passed through to our
+        * OSConnectionPrivateDataInit function where we can save it so
+        * we can back reference the file structure from it's connection
+        */
+       eError = PVRSRVConnectionConnect(&pvConnectionData, (IMG_PVOID) pFile);
+       if (eError != PVRSRV_OK)
+       {
+               OSReleaseBridgeLock();
+               return -ENOMEM;
+       }
+
+       PRIVATE_DATA(pFile) = pvConnectionData;
+       OSReleaseBridgeLock();
+
+       return 0;
+}
+
+/*!
+******************************************************************************
+
+ @Function             PVRSRVCommonRelease
+
+ @Description
+
+ Release access the PVR services node - called when a file is closed, whether
+ at exit or using close(2) system call.
+
+ @input pFile - the file handle data for the actual file being released
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+void PVRSRVCommonRelease(struct file *pFile)
+{
+       void *pvConnectionData;
+
+       OSAcquireBridgeLock();
+
+       pvConnectionData = PRIVATE_DATA(pFile);
+       if (pvConnectionData)
+       {
+               PVRSRVConnectionDisconnect(pvConnectionData);
+               PRIVATE_DATA(pFile) = NULL;
+       }
+
+       OSReleaseBridgeLock();
+}
+
+
+CONNECTION_DATA *LinuxConnectionFromFile(struct file *pFile)
+{
+       return (pFile)? PRIVATE_DATA(pFile): IMG_NULL;
+}
+
+struct file *LinuxFileFromConnection(CONNECTION_DATA *psConnection)
+{
+       ENV_CONNECTION_DATA *psEnvConnection;
+
+       psEnvConnection = PVRSRVConnectionPrivateData(psConnection);
+       PVR_ASSERT(psEnvConnection != NULL);
+
+       return psEnvConnection->psFile;
+}
+
+#if defined(SUPPORT_AUTH)
+PVRSRV_ERROR OSCheckAuthentication(CONNECTION_DATA *psConnection, IMG_UINT32 ui32Level)
+{
+       if (ui32Level != 0)
+       {
+               ENV_CONNECTION_DATA *psEnvConnection;
+
+               psEnvConnection = PVRSRVConnectionPrivateData(psConnection);
+               if (psEnvConnection == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+               }
+
+               if (!PVR_DRM_FILE_FROM_FILE(psEnvConnection->psFile)->authenticated)
+               {
+                       PVR_DPF((PVR_DBG_WARNING, "%s: PVR Services Connection not authenticated", __FUNCTION__));
+                       return PVRSRV_ERROR_NOT_AUTHENTICATED;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+#endif /* defined(SUPPORT_AUTH) */
+
+/*!
+*****************************************************************************
+
+ @Function             PVRSRVDriverInit
+
+ @Description  Do the driver-specific initialisation (as opposed to
+              the device-specific initialisation.)
+
+*****************************************************************************/
+int PVRSRVDriverInit(void)
+{
+       int error = 0;
+
+       error = PVRDebugFSInit();
+       if (error != 0)
+       {
+               return error;
+       }
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       if (PVRSRVStatsInitialise() != PVRSRV_OK)
+       {
+               return -ENOMEM;
+       }
+#endif
+
+       if (PVROSFuncInit() != PVRSRV_OK)
+       {
+               return -ENOMEM;
+       }
+
+       LinuxBridgeInit();
+
+       return 0;
+}
+
+/*!
+*****************************************************************************
+
+ @Function             PVRSRVDriverDeinit
+
+ @Description  Unwind PVRSRVDriverInit
+
+*****************************************************************************/
+void PVRSRVDriverDeinit(void)
+{
+       LinuxBridgeDeInit();
+
+       PVROSFuncDeInit();
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       PVRSRVStatsDestroy();
+#endif
+       PVRDebugFSDeInit();
+}
+
+/*!
+*****************************************************************************
+
+ @Function             PVRSRVDeviceInit
+
+ @Description  Do the initialisation we have to do after registering the device
+
+*****************************************************************************/
+int PVRSRVDeviceInit(void)
+{
+       int error = 0;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       {
+               PVRSRV_ERROR eError = pvr_sync_init();
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create sync (%d)", eError));
+                       return -EBUSY;
+               }
+       }
+#endif
+
+       error = PVRDebugCreateDebugFSEntries();
+       if (error != 0)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "PVRCore_Init: failed to create default debugfs entries (%d)", error));
+       }
+
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+       error = PVRGpuTraceInit();
+       if (error != 0)
+       {
+               PVR_DPF((PVR_DBG_WARNING, "PVRCore_Init: failed to initialise PVR GPU Tracing (%d)", error));
+       }
+#endif
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+       {
+               PVRSRV_ERROR eError = SrvInit();
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: SrvInit failed (%d)", eError));
+                       return -ENODEV;
+               }
+       }
+#endif
+       return 0;
+}
+
+/*!
+*****************************************************************************
+
+ @Function             PVRSRVDeviceDeinit
+
+ @Description  Unwind PVRSRVDeviceInit
+
+*****************************************************************************/
+void PVRSRVDeviceDeinit(void)
+{
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+       PVRGpuTraceDeInit();
+#endif
+
+       PVRDebugRemoveDebugFSEntries();
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+       pvr_sync_deinit();
+#endif
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/module_common.h b/drivers/gpu/rogue_m/services/server/env/linux/module_common.h
new file mode 100644 (file)
index 0000000..de7fe06
--- /dev/null
@@ -0,0 +1,88 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common linux module setup header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _MODULE_COMMON_H_
+#define _MODULE_COMMON_H_
+
+#if defined(LDM_PLATFORM)
+#include <linux/platform_device.h>
+#define        LDM_DEV struct platform_device
+#endif /*LDM_PLATFORM */
+
+#if defined(LDM_PCI)
+#include <linux/pci.h>
+#define        LDM_DEV struct pci_dev
+#endif /* LDM_PCI */
+
+extern LDM_DEV *gpsPVRLDMDev;
+
+/*
+ * Linux 3.8 and newer kernels no longer support __devinitdata, __devinit, __devexit, or
+ * __devexit_p.
+ */
+#if !defined(__devinitdata)
+#define __devinitdata
+#endif
+#if !defined(__devinit)
+#define __devinit
+#endif
+#if !defined(__devexit)
+#define __devexit
+#endif
+#if !defined(__devexit_p)
+#define __devexit_p(x) (&(x))
+#endif
+
+void PVRSRVDriverShutdown(LDM_DEV *device);
+int PVRSRVDriverSuspend(struct device *device);
+int PVRSRVDriverResume(struct device *device);
+
+int PVRSRVCommonOpen(struct file *pFile);
+void PVRSRVCommonRelease(struct file *pFile);
+
+int PVRSRVDriverInit(void);
+void PVRSRVDriverDeinit(void);
+
+int PVRSRVDeviceInit(void);
+void PVRSRVDeviceDeinit(void);
+
+#endif /* _MODULE_COMMON_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/osconnection_server.c b/drivers/gpu/rogue_m/services/server/env/linux/osconnection_server.c
new file mode 100644 (file)
index 0000000..0842735
--- /dev/null
@@ -0,0 +1,132 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux specific per process data functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "connection_server.h"
+#include "osconnection_server.h"
+
+#include "env_connection.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+
+#if defined (SUPPORT_ION)
+#include <linux/err.h>
+#include PVR_ANDROID_ION_HEADER
+
+/*
+       The ion device (the base object for all requests)
+       gets created by the system and we acquire it via
+       linux specific functions provided by the system layer
+*/
+#include "ion_sys.h"
+#endif
+
+PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, IMG_PVOID pvOSData)
+{
+       ENV_CONNECTION_DATA *psEnvConnection;
+#if defined(SUPPORT_ION)
+       ENV_ION_CONNECTION_DATA *psIonConnection;
+#endif
+
+       *phOsPrivateData = OSAllocMem(sizeof(ENV_CONNECTION_DATA));
+
+       if (*phOsPrivateData == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __FUNCTION__));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psEnvConnection = (ENV_CONNECTION_DATA *)*phOsPrivateData;
+       OSMemSet(psEnvConnection, 0, sizeof(*psEnvConnection));
+
+       /* Save the pointer to our struct file */
+       psEnvConnection->psFile = pvOSData;
+
+#if defined(SUPPORT_ION)
+       psIonConnection = (ENV_ION_CONNECTION_DATA *)OSAllocMem(sizeof(ENV_ION_CONNECTION_DATA));
+       if (psIonConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __FUNCTION__));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       OSMemSet(psIonConnection, 0, sizeof(*psIonConnection));
+       psEnvConnection->psIonData = psIonConnection;
+       /*
+               We can have more then one connection per process so we need more then
+               the PID to have a unique name
+       */
+       psEnvConnection->psIonData->psIonDev = IonDevAcquire();
+       OSSNPrintf(psEnvConnection->psIonData->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%p-%d", *phOsPrivateData, OSGetCurrentProcessID());
+       psEnvConnection->psIonData->psIonClient =
+               ion_client_create(psEnvConnection->psIonData->psIonDev,
+                                                 psEnvConnection->psIonData->azIonClientName);
+       if (IS_ERR_OR_NULL(psEnvConnection->psIonData->psIonClient))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSConnectionPrivateDataInit: Couldn't create "
+                                                               "ion client for per connection data"));
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       psEnvConnection->psIonData->ui32IonClientRefCount = 1;
+#endif /* SUPPORT_ION */
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+       ENV_CONNECTION_DATA *psEnvConnection; 
+
+       if (hOsPrivateData == IMG_NULL)
+       {
+               return PVRSRV_OK;
+       }
+
+       psEnvConnection = hOsPrivateData;
+
+#if defined(SUPPORT_ION)
+       EnvDataIonClientRelease(psEnvConnection->psIonData);
+#endif
+
+       OSFreeMem(hOsPrivateData);
+       /*not nulling pointer, copy on stack*/
+
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/osfunc.c b/drivers/gpu/rogue_m/services/server/env/linux/osfunc.c
new file mode 100644 (file)
index 0000000..5ae4d0d
--- /dev/null
@@ -0,0 +1,2097 @@
+/*************************************************************************/ /*!
+@File
+@Title          Environment related functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/div64.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/genalloc.h>
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <asm/tlbflush.h>
+#include <asm/page.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 <linux/kthread.h>
+#include <asm/atomic.h>
+
+#include "osfunc.h"
+#include "img_types.h"
+#include "mm.h"
+#include "allocmem.h"
+#include "env_data.h"
+#include "pvr_debugfs.h"
+#include "event.h"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+#include "pvr_debug.h"
+#include "driverlock.h"
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+#include "syscommon.h"
+#endif
+#include "physmem_osmem_linux.h"
+
+#if defined(VIRTUAL_PLATFORM)
+#define EVENT_OBJECT_TIMEOUT_MS         (120000)
+#else
+#if defined(EMULATOR)
+#define EVENT_OBJECT_TIMEOUT_MS         (2000)
+#else
+#define EVENT_OBJECT_TIMEOUT_MS         (100)
+#endif /* EMULATOR */
+#endif
+
+/* Use a pool for PhysContigPages on x86 32bit so we avoid virtual address space fragmentation by vm_map_ram.
+ * ARM does not have the function to invalidate TLB entries so they have to use the kernel functions directly. */
+#if defined(CONFIG_GENERIC_ALLOCATOR) \
+        && defined(CONFIG_X86) \
+        && !defined(CONFIG_64BIT) \
+        && (LINUX_VERSION_CODE > KERNEL_VERSION(3,0,0))
+#define OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL 1
+#endif
+
+static void *g_pvBridgeBuffers = IMG_NULL;
+static atomic_t g_DriverSuspended;
+
+struct task_struct *OSGetBridgeLockOwner(void);
+
+/*
+       Create a 4MB pool which should be more then enough in most cases,
+       if it becomes full then the calling code will fall back to
+       vm_map_ram.
+*/
+
+#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL)
+#define POOL_SIZE      (4*1024*1024)
+static struct gen_pool *pvrsrv_pool_writecombine = NULL;
+static char *pool_start;
+
+static void deinit_pvr_pool(void)
+{
+       gen_pool_destroy(pvrsrv_pool_writecombine);
+       pvrsrv_pool_writecombine = NULL;
+       vfree(pool_start);
+       pool_start = NULL;
+}
+
+static void init_pvr_pool(void)
+{
+       struct vm_struct *tmp_area;
+       int ret = -1;
+
+       /* Create the pool to allocate vm space from */
+       pvrsrv_pool_writecombine = gen_pool_create(PAGE_SHIFT, -1);
+       if (!pvrsrv_pool_writecombine) {
+               printk(KERN_ERR "%s: create pvrsrv_pool failed\n", __func__);
+               return;
+       }
+
+       /* Reserve space in the vmalloc vm range */
+       tmp_area = __get_vm_area(POOL_SIZE, VM_ALLOC,
+                       VMALLOC_START, VMALLOC_END);
+       if (!tmp_area) {
+               printk(KERN_ERR "%s: __get_vm_area failed\n", __func__);
+               gen_pool_destroy(pvrsrv_pool_writecombine);
+               pvrsrv_pool_writecombine = NULL;
+               return;
+       }
+
+       pool_start = tmp_area->addr;
+
+       if (!pool_start) {
+               printk(KERN_ERR "%s:No vm space to create POOL\n",
+                               __func__);
+               gen_pool_destroy(pvrsrv_pool_writecombine);
+               pvrsrv_pool_writecombine = NULL;
+               return;
+       } else {
+               /* Add our reserved space into the pool */
+               ret = gen_pool_add(pvrsrv_pool_writecombine,
+                       (unsigned long) pool_start, POOL_SIZE, -1);
+               if (ret) {
+                       printk(KERN_ERR "%s:could not remainder pool\n",
+                                       __func__);
+                       deinit_pvr_pool();
+                       return;
+               }
+       }
+       return;
+}
+
+static inline IMG_BOOL vmap_from_pool(void *pvCPUVAddr)
+{
+       IMG_CHAR *pcTmp = pvCPUVAddr;
+       if ((pcTmp >= pool_start) && (pcTmp <= (pool_start + POOL_SIZE)))
+       {
+               return IMG_TRUE;
+       }
+       return IMG_FALSE;
+}
+#endif /* #if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL) */
+
+PVRSRV_ERROR OSMMUPxAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize,
+                                                       Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr)
+{
+       IMG_CPU_PHYADDR sCpuPAddr;
+       struct page *psPage;
+
+       /*
+               Check that we're not doing multiple pages worth of
+               import as it's not supported a.t.m.
+       */
+       PVR_ASSERT(uiSize == PAGE_SIZE);
+
+       psPage = alloc_page(GFP_KERNEL);
+       if (psPage == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+#if defined (CONFIG_X86)
+       {
+               IMG_PVOID pvPageVAddr = page_address(psPage);
+               int ret;
+               ret = set_memory_wc((unsigned long)pvPageVAddr, 1);
+
+               if (ret)
+               {
+                       __free_page(psPage);
+                       return PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE;
+               }
+       }
+#endif
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined (CONFIG_METAG)
+       {
+               IMG_CPU_PHYADDR sCPUPhysAddrStart, sCPUPhysAddrEnd;
+               IMG_PVOID pvPageVAddr = kmap(psPage);
+
+               sCPUPhysAddrStart.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(page_to_phys(psPage));
+               sCPUPhysAddrEnd.uiAddr = sCPUPhysAddrStart.uiAddr + PAGE_SIZE;
+
+               OSInvalidateCPUCacheRangeKM(pvPageVAddr,
+                                                                       pvPageVAddr + PAGE_SIZE,
+                                                                       sCPUPhysAddrStart,
+                                                                       sCPUPhysAddrEnd);
+       }
+#endif
+
+       psMemHandle->u.pvHandle = psPage;
+       sCpuPAddr.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(page_to_phys(psPage));
+
+       PhysHeapCpuPAddrToDevPAddr(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL], 1, psDevPAddr, &sCpuPAddr);
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+           PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, PAGE_SIZE);
+#else
+       PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA,
+                                                                psPage,
+                                                                sCpuPAddr,
+                                                                PAGE_SIZE,
+                                                                IMG_NULL);
+#endif
+#endif
+
+       return PVRSRV_OK;
+}
+
+void OSMMUPxFree(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle)
+{
+       struct page *psPage = (struct page*) psMemHandle->u.pvHandle;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+           PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, PAGE_SIZE);
+#else
+       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT64)(IMG_UINTPTR_T)psPage);
+#endif
+#endif
+
+#if defined (CONFIG_X86)
+       {
+               IMG_PVOID pvPageVAddr;
+               int ret;
+
+               pvPageVAddr = page_address(psPage);
+               ret = set_memory_wb((unsigned long) pvPageVAddr, 1);
+               if (ret)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attribute", __FUNCTION__));
+               }
+       }
+#endif
+       __free_page(psPage);
+}
+
+PVRSRV_ERROR OSMMUPxMap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                               IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+                                               void **pvPtr)
+{
+       struct page **ppsPage = (struct page **) &psMemHandle->u.pvHandle;
+       IMG_UINTPTR_T uiCPUVAddr;
+       pgprot_t prot = PAGE_KERNEL;
+       PVR_UNREFERENCED_PARAMETER(psDevNode);
+
+       prot = pgprot_writecombine(prot);
+
+#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL)
+       uiCPUVAddr = gen_pool_alloc(pvrsrv_pool_writecombine, PAGE_SIZE);
+
+       if (uiCPUVAddr) {
+               int ret = 0;
+               struct vm_struct tmp_area;
+
+               /* vmalloc and friends expect a guard page so we need to take that into account */
+               tmp_area.addr = (void *)uiCPUVAddr;
+               tmp_area.size =  2 * PAGE_SIZE;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,17,0))
+               ret = map_vm_area(&tmp_area, prot, ppsPage);
+#else
+               ret = map_vm_area(&tmp_area, prot, & ppsPage);
+#endif
+               if (ret) {
+                       gen_pool_free(pvrsrv_pool_writecombine, uiCPUVAddr, PAGE_SIZE);
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "%s: Cannot map page to pool",
+                                        __func__));
+                       /* Failed the pool alloc so fall back to the vm_map path */
+                       uiCPUVAddr = 0;
+               }
+       }
+
+       /* Not else as if the poll alloc fails it resets uiCPUVAddr to 0 */
+       if (uiCPUVAddr == 0)
+#endif /* #if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL) */
+       {
+#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS)
+               uiCPUVAddr = (IMG_UINTPTR_T) vmap(ppsPage, 1, VM_READ | VM_WRITE, prot);
+#else
+               uiCPUVAddr = (IMG_UINTPTR_T) vm_map_ram(ppsPage,
+                                                                                               1,
+                                                                                               -1,
+                                                                                               prot);
+#endif
+       }
+
+       /* Check that one of the above methods got us an address */
+       if (((void *)uiCPUVAddr) == IMG_NULL)
+       {
+               return PVRSRV_ERROR_FAILED_TO_MAP_KERNELVIRTUAL;
+       }
+
+       *pvPtr = (void *) ((uiCPUVAddr & (~OSGetPageMask())) |
+                                                       ((IMG_UINTPTR_T) (psDevPAddr->uiAddr & OSGetPageMask())));
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+       /* Mapping is done a page at a time */
+       PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, PAGE_SIZE);
+#else
+       {
+               IMG_CPU_PHYADDR sCpuPAddr;
+               sCpuPAddr.uiAddr = 0;
+
+               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA,
+                                                                        (void *)uiCPUVAddr,
+                                                                        sCpuPAddr,
+                                                                        uiSize,
+                                                                        IMG_NULL);
+       }
+#endif
+#endif
+
+       return PVRSRV_OK;
+}
+
+void OSMMUPxUnmap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle, void *pvPtr)
+{
+       PVR_UNREFERENCED_PARAMETER(psDevNode);
+       PVR_UNREFERENCED_PARAMETER(psMemHandle);
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+       /* Mapping is done a page at a time */
+       PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, PAGE_SIZE);
+#else
+       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, (IMG_UINT64)(IMG_UINTPTR_T)pvPtr);
+#endif
+#endif
+
+#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL)
+       if (vmap_from_pool(pvPtr))
+       {
+               unsigned long addr = (unsigned long)pvPtr;
+
+               /* Flush the data cache */
+               flush_cache_vunmap(addr, addr + PAGE_SIZE);
+               /* Unmap the page */
+               unmap_kernel_range_noflush(addr, PAGE_SIZE);
+               /* Flush the TLB */
+               __flush_tlb_single(addr);
+               /* Free the page back to the pool */
+               gen_pool_free(pvrsrv_pool_writecombine, addr, PAGE_SIZE);
+       }
+       else
+#endif /*#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL) */
+       {
+#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS)
+               vunmap(pvPtr);
+#else
+               vm_unmap_ram(pvPtr, 1);
+#endif
+       }
+}
+
+IMG_INT OSMemCmp(void *pvBufA, void *pvBufB, IMG_SIZE_T uiLen)
+{
+       return (IMG_INT) memcmp(pvBufA, pvBufB, uiLen);
+}
+
+/*************************************************************************/ /*!
+@Function       OSStringNCopy
+@Description    strcpy
+*/ /**************************************************************************/
+IMG_CHAR *OSStringNCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, IMG_SIZE_T uSize)
+{
+       return strncpy(pszDest, pszSrc, uSize);
+}
+
+/*************************************************************************/ /*!
+@Function       OSSNPrintf
+@Description    snprintf
+@Return         the chars written or -1 on error
+*/ /**************************************************************************/
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T 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_SIZE_T OSStringLength(const IMG_CHAR *pStr)
+{
+       return strlen(pStr);
+}
+
+IMG_SIZE_T OSStringNLength(const IMG_CHAR *pStr, IMG_SIZE_T uiCount)
+{
+       return strnlen(pStr, uiCount);
+}
+
+IMG_INT32 OSStringCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2)
+{
+       return strcmp(pStr1, pStr2);
+}
+
+/*************************************************************************/ /*!
+@Function       OSInitEnvData
+@Description    Allocates space for env specific data
+@Input          ppvEnvSpecificData   Pointer to pointer in which to return
+                                     allocated data.
+@Input          ui32MMUMode          MMU mode.
+@Return         PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR OSInitEnvData(void)
+{
+       /* allocate memory for the bridge buffers to be used during an ioctl */
+       g_pvBridgeBuffers = OSAllocMem(PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE);
+       if (g_pvBridgeBuffers == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       atomic_set(&g_DriverSuspended, 0);
+
+#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL)
+       /*
+               vm_ram_ram works with 2MB blocks to avoid excessive
+               TLB flushing but our allocations are always small and have
+               a long lifetime which then leads to fragmentation of vmalloc space.
+               To workaround this we create a virtual address pool in the vmap range
+               for mapping our page tables into so we don't fragment vmalloc space.
+       */
+       if (!pvrsrv_pool_writecombine)
+       {
+               init_pvr_pool();
+       }
+#endif /* #if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL) */
+
+       LinuxInitPagePool();
+
+       return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSDeInitEnvData
+@Description    frees env specific data memory
+@Input          pvEnvSpecificData   Pointer to private structure
+@Return         PVRSRV_OK on success else PVRSRV_ERROR_OUT_OF_MEMORY
+*/ /**************************************************************************/
+void OSDeInitEnvData(void)
+{
+
+       LinuxDeinitPagePool();
+
+#if defined(OSFUNC_USE_PHYS_CONTIG_PAGES_MAP_POOL)
+       if (pvrsrv_pool_writecombine)
+       {
+               deinit_pvr_pool();
+       }
+#endif
+       if (g_pvBridgeBuffers)
+       {
+               /* free-up the memory allocated for bridge buffers */
+               OSFreeMem(g_pvBridgeBuffers);
+               g_pvBridgeBuffers = IMG_NULL;
+       }
+}
+
+PVRSRV_ERROR OSGetGlobalBridgeBuffers(IMG_VOID **ppvBridgeInBuffer,
+                                                       IMG_UINT32 *pui32BridgeInBufferSize,
+                                                       IMG_VOID **ppvBridgeOutBuffer,
+                                                       IMG_UINT32 *pui32BridgeOutBufferSize)
+{
+       PVR_ASSERT (ppvBridgeInBuffer && ppvBridgeOutBuffer);
+       PVR_ASSERT (pui32BridgeInBufferSize && pui32BridgeOutBufferSize);
+
+       *ppvBridgeInBuffer = g_pvBridgeBuffers;
+       *pui32BridgeInBufferSize = PVRSRV_MAX_BRIDGE_IN_SIZE;
+
+       *ppvBridgeOutBuffer = *ppvBridgeInBuffer + *pui32BridgeInBufferSize;
+       *pui32BridgeOutBufferSize = PVRSRV_MAX_BRIDGE_OUT_SIZE;
+
+       return PVRSRV_OK;
+}
+
+IMG_BOOL OSSetDriverSuspended(void)
+{
+       int suspend_level = atomic_inc_return(&g_DriverSuspended);
+       return (1 != suspend_level)? IMG_FALSE: IMG_TRUE;
+}
+
+IMG_BOOL OSClearDriverSuspended(void)
+{
+       int suspend_level = atomic_dec_return(&g_DriverSuspended);
+       return (0 != suspend_level)? IMG_FALSE: IMG_TRUE;
+}
+
+IMG_BOOL OSGetDriverSuspended(void)
+{
+       return (0 < atomic_read(&g_DriverSuspended))? IMG_TRUE: IMG_FALSE;
+}
+
+/*************************************************************************/ /*!
+@Function       OSReleaseThreadQuanta
+@Description    Releases thread quanta
+*/ /**************************************************************************/ 
+void OSReleaseThreadQuanta(void)
+{
+       schedule();
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+static inline IMG_UINT32 Clockus(void)
+{
+       return (jiffies * (1000000 / HZ));
+}
+#else
+/* Not matching/aligning this API to the Clockus() API above to avoid necessary
+ * multiplication/division operations in calling code.
+ */
+static inline IMG_UINT64 Clockns64(void)
+{
+       IMG_UINT64 timenow;
+
+       /* Kernel thread preempt protection. Some architecture implementations 
+        * (ARM) of sched_clock are not preempt safe when the kernel is configured 
+        * as such e.g. CONFIG_PREEMPT and others.
+        */
+       preempt_disable();
+
+       /* Using sched_clock instead of ktime_get since we need a time stamp that
+        * correlates with that shown in kernel logs and trace data not one that
+        * is a bit behind. */
+       timenow = sched_clock();
+
+       preempt_enable();
+
+       return timenow;
+}
+#endif
+
+/*************************************************************************/ /*!
+ @Function OSClockns64
+ @Description
+        This function returns the clock in nanoseconds. Unlike OSClockus,
+        OSClockus64 has a near 64-bit range
+*/ /**************************************************************************/
+IMG_UINT64 OSClockns64(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       return Clockns64();     
+#else
+       return ((IMG_UINT64)Clockus()) * 1000ULL;
+#endif
+}
+
+/*************************************************************************/ /*!
+ @Function OSClockus64
+ @Description
+        This function returns the clock in microseconds. Unlike OSClockus,
+        OSClockus64 has a near 64-bit range
+*/ /**************************************************************************/
+IMG_UINT64 OSClockus64(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       IMG_UINT64 timenow = Clockns64();
+       IMG_UINT32 remainder;
+       return OSDivide64r64(timenow, 1000, &remainder);
+#else
+       return ((IMG_UINT64)Clockus());
+#endif
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSClockus
+@Description    This function returns the clock in microseconds
+@Return         clock (us)
+*/ /**************************************************************************/ 
+IMG_UINT32 OSClockus(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       return (IMG_UINT32) OSClockus64();
+#else
+       return Clockus();
+#endif
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSClockms
+@Description    This function returns the clock in milliseconds
+@Return         clock (ms)
+*/ /**************************************************************************/ 
+IMG_UINT32 OSClockms(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       IMG_UINT64 timenow = Clockns64();
+       IMG_UINT32 remainder;
+
+       return OSDivide64(timenow, 1000000, &remainder);
+#else
+       IMG_UINT64 time, j = (IMG_UINT32)jiffies;
+
+       time = j * (((1 << 16) * 1000) / HZ);
+       time >>= 16;
+
+       return (IMG_UINT32)time;
+#endif
+}
+
+
+/*
+       OSWaitus
+*/
+void OSWaitus(IMG_UINT32 ui32Timeus)
+{
+       udelay(ui32Timeus);
+}
+
+
+/*
+       OSSleepms
+*/
+void OSSleepms(IMG_UINT32 ui32Timems)
+{
+       msleep(ui32Timems);
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentProcessID
+@Description    Returns ID of current process (thread group)
+@Return         ID of current process
+*****************************************************************************/
+IMG_PID OSGetCurrentProcessID(void)
+{
+       if (in_interrupt())
+       {
+               return KERNEL_ID;
+       }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+       return (IMG_PID)current->pgrp;
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
+       return (IMG_PID)task_tgid_nr(current);
+#else
+       return (IMG_PID)current->tgid;
+#endif
+#endif
+}
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentProcessName
+@Description    gets name of current process
+@Return         process name
+*****************************************************************************/
+IMG_CHAR *OSGetCurrentProcessName(void)
+{
+       return current->comm;
+}
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentThreadID
+@Description    Returns ID for current thread
+@Return         ID of current thread
+*****************************************************************************/
+IMG_UINTPTR_T OSGetCurrentThreadID(void)
+{
+       if (in_interrupt())
+       {
+               return KERNEL_ID;
+       }
+
+       return current->pid;
+}
+
+/*************************************************************************/ /*!
+@Function       OSGetPageSize
+@Description    gets page size
+@Return         page size
+*/ /**************************************************************************/
+IMG_SIZE_T OSGetPageSize(void)
+{
+       return PAGE_SIZE;
+}
+
+/*************************************************************************/ /*!
+@Function       OSGetPageShift
+@Description    gets page size
+@Return         page size
+*/ /**************************************************************************/
+IMG_SIZE_T OSGetPageShift(void)
+{
+       return PAGE_SHIFT;
+}
+
+/*************************************************************************/ /*!
+@Function       OSGetPageMask
+@Description    gets page mask
+@Return         page size
+*/ /**************************************************************************/
+IMG_SIZE_T OSGetPageMask(void)
+{
+       return (OSGetPageSize()-1);
+}
+
+#if !defined (SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+typedef struct _LISR_DATA_ {
+       PFN_LISR pfnLISR;
+       void *pvData;
+       IMG_UINT32 ui32IRQ;
+} LISR_DATA;
+
+/*
+       DeviceISRWrapper
+*/
+static irqreturn_t DeviceISRWrapper(int irq, void *dev_id)
+{
+       LISR_DATA *psLISRData = (LISR_DATA *) dev_id;
+       IMG_BOOL bStatus = IMG_FALSE;
+
+       PVR_UNREFERENCED_PARAMETER(irq);
+
+       bStatus = psLISRData->pfnLISR(psLISRData->pvData);
+
+       return bStatus ? IRQ_HANDLED : IRQ_NONE;
+}
+#endif
+
+/*
+       OSInstallDeviceLISR
+*/
+PVRSRV_ERROR OSInstallDeviceLISR(PVRSRV_DEVICE_CONFIG *psDevConfig,
+                                IMG_HANDLE *hLISRData, 
+                                PFN_LISR pfnLISR,
+                                void *pvData)
+{
+#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+       return SysInstallDeviceLISR(psDevConfig->ui32IRQ,
+                                       psDevConfig->pszName,
+                                       pfnLISR,
+                                       pvData,
+                                       hLISRData);
+#else
+       LISR_DATA *psLISRData;
+       unsigned long flags = 0;
+
+       psLISRData = OSAllocMem(sizeof(LISR_DATA));
+
+       psLISRData->pfnLISR = pfnLISR;
+       psLISRData->pvData = pvData;
+       psLISRData->ui32IRQ = psDevConfig->ui32IRQ;
+
+       if (psDevConfig->bIRQIsShared)
+       {
+               flags |= IRQF_SHARED;
+       }
+
+       if (psDevConfig->eIRQActiveLevel == PVRSRV_DEVICE_IRQ_ACTIVE_HIGH)
+       {
+               flags |= IRQF_TRIGGER_HIGH;
+       }
+       else if (psDevConfig->eIRQActiveLevel == PVRSRV_DEVICE_IRQ_ACTIVE_LOW)
+       {
+               flags |= IRQF_TRIGGER_LOW;
+       }
+
+       PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", psDevConfig->pszName, psDevConfig->ui32IRQ, pvData));
+
+       if(request_irq(psDevConfig->ui32IRQ, DeviceISRWrapper,
+               flags, psDevConfig->pszName, psLISRData))
+       {
+               PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", psDevConfig->ui32IRQ));
+
+               return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+       }
+
+       *hLISRData = (IMG_HANDLE) psLISRData;
+
+       return PVRSRV_OK;
+#endif
+}
+
+/*
+       OSUninstallDeviceLISR
+*/
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_HANDLE hLISRData)
+{
+#if defined (SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+       return SysUninstallDeviceLISR(hLISRData);
+#else
+       LISR_DATA *psLISRData = (LISR_DATA *) hLISRData;
+
+       PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psLISRData->ui32IRQ,  psLISRData->pvData));
+
+       free_irq(psLISRData->ui32IRQ, psLISRData);
+       OSFreeMem(psLISRData);
+
+       return PVRSRV_OK;
+#endif
+}
+
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+typedef struct  _MISR_DATA_ {
+       struct workqueue_struct *psWorkQueue;
+       struct work_struct sMISRWork;
+       PFN_MISR pfnMISR;
+       void *hData;
+} MISR_DATA;
+
+/*
+       MISRWrapper
+*/
+static void MISRWrapper(struct work_struct *data)
+{
+       MISR_DATA *psMISRData = container_of(data, MISR_DATA, sMISRWork);
+
+       psMISRData->pfnMISR(psMISRData->hData);
+}
+
+/*
+       OSInstallMISR
+*/
+PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR,
+                                                       void *hData)
+{
+       MISR_DATA *psMISRData;
+
+       psMISRData = OSAllocMem(sizeof(MISR_DATA));
+       if (psMISRData == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psMISRData->hData = hData;
+       psMISRData->pfnMISR = pfnMISR;
+
+       PVR_TRACE(("Installing MISR with cookie %p", psMISRData));
+
+       psMISRData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
+
+       if (psMISRData->psWorkQueue == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
+               OSFreeMem(psMISRData);
+               return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+       }
+
+       INIT_WORK(&psMISRData->sMISRWork, MISRWrapper);
+
+       *hMISRData = (IMG_HANDLE) psMISRData;
+
+       return PVRSRV_OK;
+}
+
+/*
+       OSUninstallMISR
+*/
+PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData)
+{
+       MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
+
+       PVR_TRACE(("Uninstalling MISR"));
+
+       destroy_workqueue(psMISRData->psWorkQueue);
+       OSFreeMem(psMISRData);
+
+       return PVRSRV_OK;
+}
+
+/*
+       OSScheduleMISR
+*/
+PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData)
+{
+       MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
+
+       /*
+               Note:
+
+               In the case of NO_HARDWARE we want the driver to be synchronous so
+               that we don't have to worry about waiting for previous operations
+               to complete
+       */
+#if defined(NO_HARDWARE)
+       psMISRData->pfnMISR(psMISRData->hData);
+#else
+       queue_work(psMISRData->psWorkQueue, &psMISRData->sMISRWork);
+#endif
+       return PVRSRV_OK;
+}
+#else  /* defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
+typedef struct  _MISR_DATA_ {
+       struct work_struct sMISRWork;
+       PFN_MISR pfnMISR;
+       void *hData;
+} MISR_DATA;
+
+/*
+       MISRWrapper
+*/
+static void MISRWrapper(struct work_struct *data)
+{
+       MISR_DATA *psMISRData = container_of(data, MISR_DATA, sMISRWork);
+
+       psMISRData->pfnMISR(psMISRData->hData);
+}
+
+/*
+       OSInstallMISR
+*/
+PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR, void *hData)
+{
+       MISR_DATA *psMISRData;
+
+       psMISRData = OSAllocMem(sizeof(MISR_DATA));
+       if (psMISRData == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psMISRData->hData = hData;
+       psMISRData->pfnMISR = pfnMISR;
+
+       PVR_TRACE(("Installing MISR with cookie %p", psMISRData));
+
+       INIT_WORK(&psMISRData->sMISRWork, MISRWrapper);
+
+       *hMISRData = (IMG_HANDLE) psMISRData;
+
+       return PVRSRV_OK;
+}
+
+
+/*
+       OSUninstallMISR
+*/
+PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData)
+{
+       PVR_TRACE(("Uninstalling MISR"));
+
+       flush_scheduled_work();
+
+       OSFreeMem(hMISRData);
+
+       return PVRSRV_OK;
+}
+
+/*
+       OSScheduleMISR
+*/
+PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData)
+{
+       MISR_DATA *psMISRData = hMISRData;
+#if defined(NO_HARDWARE)
+       psMISRData->pfnMISR(psMISRData->hData);
+#else
+       schedule_work(&psMISRData->sMISRWork);
+#endif
+       return PVRSRV_OK;
+}
+
+#else  /* #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) */
+typedef struct _MISR_DATA_ {
+       struct tasklet_struct sMISRTasklet;
+       PFN_MISR pfnMISR;
+       void *hData;
+} MISR_DATA;
+
+/*
+       MISRWrapper
+*/
+static void MISRWrapper(unsigned long data)
+{
+       MISR_DATA *psMISRData = (MISR_DATA *) data;
+
+       psMISRData->pfnMISR(psMISRData->hData);
+}
+
+/*
+       OSInstallMISR
+*/
+PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR, void *hData)
+{
+       MISR_DATA *psMISRData;
+
+       psMISRData = OSAllocMem(sizeof(MISR_DATA));
+       if (psMISRData == NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       psMISRData->hData = hData;
+       psMISRData->pfnMISR = pfnMISR;
+
+       PVR_TRACE(("Installing MISR with cookie %p", psMISRData));
+
+       tasklet_init(&psMISRData->sMISRTasklet, MISRWrapper, (unsigned long)psMISRData);
+
+       *hMISRData = (IMG_HANDLE) psMISRData;
+
+       return PVRSRV_OK;
+}
+
+/*
+       OSUninstallMISR
+*/
+PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData)
+{
+       MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
+
+       PVR_TRACE(("Uninstalling MISR"));
+
+       tasklet_kill(&psMISRData->sMISRTasklet);
+
+       return PVRSRV_OK;
+}
+
+/*
+       OSScheduleMISR
+*/
+PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData)
+{
+       MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
+
+#if defined(NO_HARDWARE)
+       psMISRData->pfnMISR(psMISRData->hData);
+#else
+       tasklet_schedule(&psMISRData->sMISRTasklet);
+#endif
+       return PVRSRV_OK;
+}
+
+#endif /* #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) */
+#endif /* #if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
+
+/* OS specific values for thread priority */
+const IMG_INT32 ai32OSPriorityValues[LAST_PRIORITY] = { -20, /* HIGHEST_PRIORITY */
+                                                        -10, /* HIGH_PRIRIOTY */
+                                                          0, /* NORMAL_PRIORITY */
+                                                          9, /* LOW_PRIORITY */
+                                                         19, /* LOWEST_PRIORITY */
+                                                        -22};/* NOSET_PRIORITY */
+
+typedef struct {
+       struct task_struct *kthread;
+       PFN_THREAD pfnThread;
+       void *hData;
+       OS_THREAD_LEVEL eThreadPriority;
+} OSThreadData;
+
+static int OSThreadRun(void *data)
+{
+       OSThreadData *psOSThreadData = data;
+
+       /* If i32NiceValue is acceptable, set the nice value for the new thread */
+       if (psOSThreadData->eThreadPriority != NOSET_PRIORITY &&
+                psOSThreadData->eThreadPriority < LAST_PRIORITY)
+               set_user_nice(current, ai32OSPriorityValues[psOSThreadData->eThreadPriority]);
+
+       /* Call the client's kernel thread with the client's data pointer */
+       psOSThreadData->pfnThread(psOSThreadData->hData);
+
+       /* Wait for OSThreadDestroy() to call kthread_stop() */
+       while (!kthread_should_stop())
+       {
+                schedule();
+       }
+
+       return 0;
+}
+
+PVRSRV_ERROR OSThreadCreate(IMG_HANDLE *phThread,
+                                                       IMG_CHAR *pszThreadName,
+                                                       PFN_THREAD pfnThread,
+                                                       void *hData)
+{
+       return OSThreadCreatePriority(phThread, pszThreadName, pfnThread, hData, NOSET_PRIORITY);
+}
+
+PVRSRV_ERROR OSThreadCreatePriority(IMG_HANDLE *phThread,
+                                    IMG_CHAR *pszThreadName,
+                                    PFN_THREAD pfnThread,
+                                    void *hData,
+                                    OS_THREAD_LEVEL eThreadPriority)
+{
+       OSThreadData *psOSThreadData;
+       PVRSRV_ERROR eError;
+
+       psOSThreadData = OSAllocMem(sizeof(OSThreadData));
+       if (psOSThreadData == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       psOSThreadData->pfnThread = pfnThread;
+       psOSThreadData->hData = hData;
+       psOSThreadData->eThreadPriority= eThreadPriority;
+       psOSThreadData->kthread = kthread_run(OSThreadRun, psOSThreadData, pszThreadName);
+
+       if (IS_ERR(psOSThreadData->kthread))
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_kthread;
+       }
+
+       *phThread = psOSThreadData;
+
+       return PVRSRV_OK;
+
+fail_kthread:
+       OSFreeMem(psOSThreadData);
+fail_alloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+PVRSRV_ERROR OSThreadDestroy(IMG_HANDLE hThread)
+{
+       OSThreadData *psOSThreadData = hThread;
+       int ret;
+
+       /* Let the thread know we are ready for it to end and wait for it. */
+       ret = kthread_stop(psOSThreadData->kthread);
+       PVR_ASSERT(ret == 0);
+       OSFreeMem(psOSThreadData);
+
+       return PVRSRV_OK;
+}
+
+void OSPanic(void)
+{
+       BUG();
+
+#if defined(__KLOCWORK__)
+       /* Klocworks does not understand that BUG is terminal... */
+       abort();
+#endif
+}
+
+/*************************************************************************/ /*!
+@Function       OSMapPhysToLin
+@Description    Maps the physical memory into linear addr range
+@Input          BasePAddr       Physical cpu address
+@Input          ui32Bytes       Bytes to map
+@Input          ui32CacheType   Cache type
+@Return         Linear addr of mapping on success, else NULL
+ */ /**************************************************************************/
+void *
+OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
+               IMG_SIZE_T ui32Bytes,
+               IMG_UINT32 ui32MappingFlags)
+{
+       void *pvIORemapCookie;
+
+       pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
+       if(pvIORemapCookie == IMG_NULL)
+       {
+               PVR_ASSERT(0);
+               return IMG_NULL;
+       }
+
+       return pvIORemapCookie;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSUnMapPhysToLin
+@Description    Unmaps memory that was mapped with OSMapPhysToLin
+@Input          pvLinAddr
+@Input          ui32Bytes
+@Return         TRUE on success, else FALSE
+*/ /**************************************************************************/
+IMG_BOOL
+OSUnMapPhysToLin(void *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32MappingFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+       IOUnmapWrapper(pvLinAddr);
+
+       return IMG_TRUE;
+}
+
+/*
+       OSReadHWReg8
+*/
+IMG_UINT8 OSReadHWReg8(IMG_PVOID       pvLinRegBaseAddr,
+                                               IMG_UINT32      ui32Offset)
+{
+#if !defined(NO_HARDWARE)
+       return (IMG_UINT8) readb((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+       return 0x4e;    /* FIXME: OSReadHWReg should not exist in no hardware builds */
+#endif
+}
+
+/*
+       OSReadHWReg16
+*/
+IMG_UINT16 OSReadHWReg16(IMG_PVOID     pvLinRegBaseAddr,
+                                                IMG_UINT32     ui32Offset)
+{
+#if !defined(NO_HARDWARE)
+       return (IMG_UINT16) readw((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+       return 0x3a4e;  /* FIXME: OSReadHWReg should not exist in no hardware builds */
+#endif
+}
+
+/*
+       OSReadHWReg32
+*/
+IMG_UINT32 OSReadHWReg32(IMG_PVOID     pvLinRegBaseAddr,
+                                                IMG_UINT32     ui32Offset)
+{
+#if !defined(NO_HARDWARE)
+       return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#else
+       return 0x30f73a4e;      /* FIXME: OSReadHWReg should not exist in no hardware builds */
+#endif
+}
+
+
+/*
+       OSReadHWReg64
+*/
+IMG_UINT64 OSReadHWReg64(IMG_PVOID     pvLinRegBaseAddr,
+                                                IMG_UINT32     ui32Offset)
+{
+       IMG_UINT64      ui64Result;
+
+       ui64Result = OSReadHWReg32(pvLinRegBaseAddr, ui32Offset + 4);
+       ui64Result <<= 32;
+       ui64Result |= (IMG_UINT64)OSReadHWReg32(pvLinRegBaseAddr, ui32Offset);
+
+       return ui64Result;
+}
+
+/*
+       OSReadHWRegBank
+*/
+IMG_DEVMEM_SIZE_T OSReadHWRegBank(IMG_PVOID pvLinRegBaseAddr,
+                                  IMG_UINT32 ui32Offset,
+                                  IMG_UINT8 *pui8DstBuf,
+                                  IMG_DEVMEM_SIZE_T uiDstBufLen)
+{
+#if !defined(NO_HARDWARE)
+       IMG_DEVMEM_SIZE_T uiCounter;
+
+       /* FIXME: optimize this */
+
+       for(uiCounter = 0; uiCounter < uiDstBufLen; uiCounter++) {
+               *(pui8DstBuf + uiCounter) =
+                 readb(pvLinRegBaseAddr + ui32Offset + uiCounter);
+       }
+
+       return uiCounter;
+#else
+       return uiDstBufLen;
+#endif
+}
+
+/*
+       OSWriteHWReg8
+*/
+void OSWriteHWReg8(void                        *pvLinRegBaseAddr,
+                                  IMG_UINT32   ui32Offset,
+                                  IMG_UINT8    ui8Value)
+{
+#if !defined(NO_HARDWARE)
+       writeb(ui8Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#endif
+}
+
+/*
+       OSWriteHWReg16
+*/
+void OSWriteHWReg16(void               *pvLinRegBaseAddr,
+                                       IMG_UINT32      ui32Offset,
+                                       IMG_UINT16      ui16Value)
+{
+#if !defined(NO_HARDWARE)
+       writew(ui16Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#endif
+}
+
+/*
+       OSWriteHWReg32
+*/
+void OSWriteHWReg32(void               *pvLinRegBaseAddr,
+                                       IMG_UINT32      ui32Offset,
+                                       IMG_UINT32      ui32Value)
+{
+#if !defined(NO_HARDWARE)
+       writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
+#endif
+}
+
+
+/*
+       OSWriteHWReg64
+*/
+void OSWriteHWReg64(void               *pvLinRegBaseAddr,
+                                       IMG_UINT32      ui32Offset,
+                                       IMG_UINT64      ui64Value)
+{
+#if !defined(NO_HARDWARE)
+       IMG_UINT32 ui32ValueLow, ui32ValueHigh;
+
+       ui32ValueLow = ui64Value & 0xffffffff;
+       ui32ValueHigh = ((IMG_UINT64) (ui64Value >> 32)) & 0xffffffff;
+
+       writel(ui32ValueLow, pvLinRegBaseAddr + ui32Offset);
+       writel(ui32ValueHigh, pvLinRegBaseAddr + ui32Offset + 4);
+#endif
+}
+
+IMG_DEVMEM_SIZE_T OSWriteHWRegBank(void *pvLinRegBaseAddr,
+                                                                  IMG_UINT32 ui32Offset,
+                                                                  IMG_UINT8 *pui8SrcBuf,
+                                                                  IMG_DEVMEM_SIZE_T uiSrcBufLen)
+{
+#if !defined(NO_HARDWARE)
+       IMG_DEVMEM_SIZE_T uiCounter;
+
+       /* FIXME: optimize this */
+
+       for(uiCounter = 0; uiCounter < uiSrcBufLen; uiCounter++) {
+               writeb(*(pui8SrcBuf + uiCounter),
+                      pvLinRegBaseAddr + ui32Offset + uiCounter);
+       }
+
+       return uiCounter;
+#else
+       return uiSrcBufLen;
+#endif
+}
+
+#define        OS_MAX_TIMERS   8
+
+/* Timer callback strucure used by OSAddTimer */
+typedef struct TIMER_CALLBACK_DATA_TAG
+{
+       IMG_BOOL                        bInUse;
+       PFN_TIMER_FUNC          pfnTimerFunc;
+       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
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+/* The lock is used to control access to sTimers */
+static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(sTimerStructLock);
+#endif
+#endif
+
+static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
+{
+       if (!psTimerCBData->bActive)
+               return;
+
+       /* call timer callback */
+       psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
+
+       /* reset timer */
+       mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSTimerCallbackWrapper
+@Description    OS specific timer callback wrapper function
+@Input          uData    Timer callback data
+*/ /**************************************************************************/
+static void OSTimerCallbackWrapper(IMG_UINTPTR_T uData)
+{
+       TIMER_CALLBACK_DATA     *psTimerCBData = (TIMER_CALLBACK_DATA*)uData;
+
+#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
+
+/*************************************************************************/ /*!
+@Function       OSAddTimer
+@Description    OS specific function to install a timer callback
+@Input          pfnTimerFunc    Timer callback
+@Input         *pvData          Callback data
+@Input          ui32MsTimeout   Callback period
+@Return         Valid handle success, NULL failure
+*/ /**************************************************************************/
+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, 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
+
+       /* check callback */
+       if(!pfnTimerFunc)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));
+               return IMG_NULL;
+       }
+
+       /* Allocate timer callback data structure */
+#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;
+
+       /*
+               HZ = ticks per second
+               ui32MsTimeout = required ms delay
+               ticks = (Hz * ui32MsTimeout) / 1000
+       */
+       psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
+                                                               ?       1
+                                                               :       ((HZ * ui32MsTimeout) / 1000);
+       /* initialise object */
+       init_timer(&psTimerCBData->sTimer);
+
+       /* setup timer object */
+       psTimerCBData->sTimer.function = (void *)OSTimerCallbackWrapper;
+       psTimerCBData->sTimer.data = (IMG_UINTPTR_T)psTimerCBData;
+
+       return (IMG_HANDLE)(IMG_UINTPTR_T)(ui32i + 1);
+}
+
+
+static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
+{
+       IMG_UINT32 ui32i = (IMG_UINT32)((IMG_UINTPTR_T)hTimer) - 1;
+
+       PVR_ASSERT(ui32i < OS_MAX_TIMERS);
+
+       return &sTimers[ui32i];
+}
+
+/*************************************************************************/ /*!
+@Function       OSRemoveTimer
+@Description    OS specific function to remove a timer callback
+@Input          hTimer : timer handle
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
+{
+       TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+       PVR_ASSERT(psTimerCBData->bInUse);
+       PVR_ASSERT(!psTimerCBData->bActive);
+
+       /* free timer callback data struct */
+       psTimerCBData->bInUse = IMG_FALSE;
+
+       return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSEnableTimer
+@Description    OS specific function to enable a timer callback
+@Input          hTimer    Timer handle
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
+{
+       TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+       PVR_ASSERT(psTimerCBData->bInUse);
+       PVR_ASSERT(!psTimerCBData->bActive);
+
+       /* Start timer arming */
+       psTimerCBData->bActive = IMG_TRUE;
+
+       /* set the expire time */
+       psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
+
+       /* Add the timer to the list */
+       add_timer(&psTimerCBData->sTimer);
+
+       return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSDisableTimer
+@Description    OS specific function to disable a timer callback
+@Input          hTimer    Timer handle
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
+{
+       TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+       PVR_ASSERT(psTimerCBData->bInUse);
+       PVR_ASSERT(psTimerCBData->bActive);
+
+       /* Stop timer from arming */
+       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
+
+       /* remove timer */
+       del_timer_sync(&psTimerCBData->sTimer);
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+       /*
+        * This second flush is to catch the case where the timer ran
+        * before we managed to delete it, in which case, it will have
+        * queued more work for the workqueue.  Since the bActive flag
+        * has been cleared, this second flush won't result in the
+        * timer being rearmed.
+        */
+       flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+       flush_scheduled_work();
+#endif
+
+       return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectCreate
+@Description    OS specific function to create an event object
+@Input          pszName      Globally unique event object name (if null name must be autogenerated)
+@Output         hEventObject OS event object info structure
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, IMG_HANDLE *hEventObject)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVR_UNREFERENCED_PARAMETER(pszName);
+
+       if(hEventObject)
+       {
+               if(LinuxEventObjectListCreate(hEventObject) != PVRSRV_OK)
+               {
+                        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: hEventObject is not a valid pointer"));
+               eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;
+       }
+
+       return eError;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectDestroy
+@Description    OS specific function to destroy an event object
+@Input          hEventObject   OS event object info structure
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if(hEventObject)
+       {
+               LinuxEventObjectListDestroy(hEventObject);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hEventObject is not a valid pointer"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return eError;
+}
+
+/*
+ * EventObjectWaitTimeout()
+ */
+static PVRSRV_ERROR EventObjectWaitTimeout(IMG_HANDLE hOSEventKM,
+                                           IMG_UINT32 uiTimeoutMs,
+                                           IMG_BOOL bHoldBridgeLock)
+{
+    PVRSRV_ERROR eError;
+
+       if(hOSEventKM && uiTimeoutMs > 0)
+       {
+               eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutMs, bHoldBridgeLock);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: invalid arguments %p, %d", hOSEventKM, uiTimeoutMs ));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitTimeout
+@Description    Wait for an event with timeout as supplied. Called from client
+@Input          hOSEventKM    OS and kernel specific handle to event object
+@Input          uiTimeoutMs   Non zero time period in milliseconds to wait
+@Return         PVRSRV_ERROR_TIMEOUT : Wait reached wait limit and timed out
+@Return         PVRSRV_ERROR         : any other system error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs)
+{
+    return EventObjectWaitTimeout(hOSEventKM, uiTimeoutMs, IMG_FALSE);
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWait
+@Description    OS specific function to wait for an event object. Called
+                               from client. Uses a default wait with 100ms timeout.
+@Input          hOSEventKM    OS and kernel specific handle to event object
+@Return         PVRSRV_ERROR_TIMEOUT  : Reached wait limit and timed out
+@Return         PVRSRV_ERROR  : any other system error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM)
+{
+       return OSEventObjectWaitTimeout(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitTimeoutAndHoldBridgeLock
+@Description    Wait for an event with timeout as supplied. Called from client
+                NOTE: Holds bridge lock during wait.
+@Input          hOSEventKM    OS and kernel specific handle to event object
+@Input          uiTimeoutMs   Non zero time period in milliseconds to wait
+@Return         PVRSRV_ERROR_TIMEOUT : Wait reached wait limit and timed out
+@Return         PVRSRV_ERROR         : any other system error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs)
+{
+       return EventObjectWaitTimeout(hOSEventKM, uiTimeoutMs, IMG_TRUE);
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitAndHoldBridgeLock
+@Description    OS specific function to wait for an event object. Called
+                               from client. Uses a default wait with 100ms timeout.
+                NOTE: Holds bridge lock during wait.
+@Input          hOSEventKM    OS and kernel specific handle to event object
+@Return         PVRSRV_ERROR_TIMEOUT  : Reached wait limit and timed out
+@Return         PVRSRV_ERROR  : any other system error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitAndHoldBridgeLock(IMG_HANDLE hOSEventKM)
+{
+       return OSEventObjectWaitTimeoutAndHoldBridgeLock(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectOpen
+@Description    OS specific function to open an event object.  Called from client
+@Input          hEventObject  Pointer to an event object
+@Output         phOSEvent     OS and kernel specific handle to event object
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject,
+                                                                                       IMG_HANDLE *phOSEvent)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if(hEventObject)
+       {
+               if(LinuxEventObjectAdd(hEventObject, phOSEvent) != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed"));
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectOpen: hEventObject is not a valid pointer"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectClose
+@Description    OS specific function to close an event object.  Called from client
+@Input          hOSEventKM    OS and kernel specific handle to event object
+@Return         PVRSRV_ERROR  :
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       if(hOSEventKM)
+       {
+               if(LinuxEventObjectDelete(hOSEventKM) != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+               }
+
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hEventObject is not a valid pointer"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectSignal
+@Description    OS specific function to 'signal' an event object.  Called from L/MISR
+@Input          hOSEventKM   OS and kernel specific handle to event object
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject)
+{
+       PVRSRV_ERROR eError;
+
+       if(hEventObject)
+       {
+               eError = LinuxEventObjectSignal(hEventObject);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignal: hOSEventKM is not a valid handle"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       OSProcHasPrivSrvInit
+@Description    Does the process have sufficient privileges to initialise services?
+@Return         IMG_BOOL
+*/ /**************************************************************************/
+IMG_BOOL OSProcHasPrivSrvInit(void)
+{
+       return capable(CAP_SYS_ADMIN) != 0;
+}
+
+/*************************************************************************/ /*!
+@Function       OSCopyToUser
+@Description    Copy a block of data into user space
+@Input          pvSrc
+@Output         pvDest
+@Input          ui32Bytes
+@Return   PVRSRV_ERROR  :
+*/ /**************************************************************************/
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess,
+                          void *pvDest,
+                          const void *pvSrc,
+                          IMG_SIZE_T ui32Bytes)
+{
+       PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+       if(pvr_copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
+               return PVRSRV_OK;
+       else
+               return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+/*************************************************************************/ /*!
+@Function       OSCopyFromUser
+@Description    Copy a block of data from the user space
+@Output         pvDest
+@Input          pvSrc
+@Input          ui32Bytes
+@Return         PVRSRV_ERROR  :
+*/ /**************************************************************************/
+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess,
+                            void *pvDest,
+                            const void *pvSrc,
+                            IMG_SIZE_T ui32Bytes)
+{
+       PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+       if(pvr_copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
+               return PVRSRV_OK;
+       else
+               return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+/*************************************************************************/ /*!
+@Function       OSAccessOK
+@Description    Checks if a user space pointer is valide
+@Input          eVerification
+@Input          pvUserPtr
+@Input          ui32Bytes
+@Return         IMG_BOOL :
+*/ /**************************************************************************/
+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, void *pvUserPtr, IMG_SIZE_T ui32Bytes)
+{
+       IMG_INT linuxType;
+
+       if (eVerification == PVR_VERIFY_READ)
+       {
+               linuxType = VERIFY_READ;
+       }
+       else
+       {
+               PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
+               linuxType = VERIFY_WRITE;
+       }
+
+       return access_ok(linuxType, pvUserPtr, ui32Bytes);
+}
+
+
+void OSWriteMemoryBarrier(void)
+{
+       wmb();
+}
+
+
+void OSMemoryBarrier(void)
+{
+       mb();
+}
+
+IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder)
+{
+       *pui32Remainder = do_div(ui64Divident, ui32Divisor);
+
+       return ui64Divident;
+}
+
+IMG_UINT32 OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder)
+{
+       *pui32Remainder = do_div(ui64Divident, ui32Divisor);
+
+       return (IMG_UINT32) ui64Divident;
+}
+
+/* One time osfunc initialisation */
+PVRSRV_ERROR PVROSFuncInit(void)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+       {
+               PVR_ASSERT(!psTimerWorkQueue);
+
+               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;
+}
+
+/*
+ * Osfunc deinitialisation.
+ * Note that PVROSFuncInit may not have been called
+ */
+void PVROSFuncDeInit(void)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+       if (psTimerWorkQueue != NULL)
+       {
+               destroy_workqueue(psTimerWorkQueue);
+               psTimerWorkQueue = NULL;
+       }
+#endif
+}
+
+void OSDumpStack(void)
+{
+       dump_stack();
+}
+
+static struct task_struct *gsOwner;
+
+void OSAcquireBridgeLock(void)
+{
+       mutex_lock(&gPVRSRVLock);
+       gsOwner = current;
+}
+
+void OSReleaseBridgeLock(void)
+{
+       gsOwner = NULL;
+       mutex_unlock(&gPVRSRVLock);
+}
+
+struct task_struct *OSGetBridgeLockOwner(void)
+{
+       return gsOwner;
+}
+
+
+/*************************************************************************/ /*!
+@Function       OSCreateStatisticEntry
+@Description    Create a statistic entry in the specified folder.
+@Input          pszName        String containing the name for the entry.
+@Input          pvFolder       Reference from OSCreateStatisticFolder() of the
+                               folder to create the entry in, or IMG_NULL for the
+                               root.
+@Input          pfnStatsPrint  Pointer to function that can be used to print the
+                               values of all the statistics.
+@Input          pfnIncMemRefCt Pointer to function that can be used to take a
+                               reference on the memory backing the statistic
+                                                          entry.
+@Input          pfnDecMemRefCt Pointer to function that can be used to drop a
+                               reference on the memory backing the statistic
+                                                          entry.
+@Input          pvData         OS specific reference that can be used by
+                               pfnGetElement.
+@Return         Pointer void reference to the entry created, which can be
+                passed to OSRemoveStatisticEntry() to remove the entry.
+*/ /**************************************************************************/
+IMG_PVOID OSCreateStatisticEntry(IMG_CHAR* pszName, IMG_PVOID pvFolder,
+                                 OS_STATS_PRINT_FUNC* pfnStatsPrint,
+                                                            OS_INC_STATS_MEM_REFCOUNT_FUNC* pfnIncMemRefCt,
+                                                            OS_DEC_STATS_MEM_REFCOUNT_FUNC* pfnDecMemRefCt,
+                                 IMG_PVOID pvData)
+{
+       return (IMG_PVOID)PVRDebugFSCreateStatisticEntry(pszName, (PVR_DEBUGFS_DIR_DATA *)pvFolder, pfnStatsPrint, pfnIncMemRefCt, pfnDecMemRefCt, pvData);
+} /* OSCreateStatisticEntry */
+
+
+/*************************************************************************/ /*!
+@Function       OSRemoveStatisticEntry
+@Description    Removes a statistic entry.
+@Input          pvEntry  Pointer void reference to the entry created by
+                         OSCreateStatisticEntry().
+*/ /**************************************************************************/
+void OSRemoveStatisticEntry(IMG_PVOID pvEntry)
+{
+       PVRDebugFSRemoveStatisticEntry((PVR_DEBUGFS_DRIVER_STAT *)pvEntry);
+} /* OSRemoveStatisticEntry */
+
+
+/*************************************************************************/ /*!
+@Function       OSCreateStatisticFolder
+@Description    Create a statistic folder to hold statistic entries.
+@Input          pszName   String containing the name for the folder.
+@Input          pvFolder  Reference from OSCreateStatisticFolder() of the folder
+                          to create the folder in, or IMG_NULL for the root.
+@Return         Pointer void reference to the folder created, which can be
+                passed to OSRemoveStatisticFolder() to remove the folder.
+*/ /**************************************************************************/
+IMG_PVOID OSCreateStatisticFolder(IMG_CHAR *pszName, IMG_PVOID pvFolder)
+{
+       PVR_DEBUGFS_DIR_DATA *psNewStatFolder = IMG_NULL;
+       int iResult;
+
+       iResult = PVRDebugFSCreateEntryDir(pszName, (PVR_DEBUGFS_DIR_DATA *)pvFolder, &psNewStatFolder);
+       return (iResult == 0) ? (void *)psNewStatFolder : IMG_NULL;
+} /* OSCreateStatisticFolder */
+
+
+/*************************************************************************/ /*!
+@Function       OSRemoveStatisticFolder
+@Description    Removes a statistic folder.
+@Input          pvFolder  Reference from OSCreateStatisticFolder() of the
+                          folder that should be removed.
+*/ /**************************************************************************/
+void OSRemoveStatisticFolder(IMG_PVOID pvFolder)
+{
+       PVRDebugFSRemoveEntryDir((PVR_DEBUGFS_DIR_DATA *)pvFolder);
+} /* OSRemoveStatisticFolder */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm.c b/drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm.c
new file mode 100644 (file)
index 0000000..3fc0f99
--- /dev/null
@@ -0,0 +1,173 @@
+/*************************************************************************/ /*!
+@File
+@Title          arm specific OS functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS functions who's implementation are processor specific
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <linux/dma-mapping.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
+ #include <asm/system.h>
+#endif
+#include <asm/cacheflush.h>
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+
+#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
+
+static void per_cpu_cache_flush(void *arg)
+{
+       PVR_UNREFERENCED_PARAMETER(arg);
+       flush_cache_all();
+}
+
+void OSCPUOperation(PVRSRV_CACHE_OP uiCacheOp)
+{
+       switch(uiCacheOp)
+       {
+               /* Fall-through */
+               case PVRSRV_CACHE_OP_CLEAN:
+                                       /* No full (inner) cache clean op */
+                                       ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE)
+                                       outer_clean_range(0, ULONG_MAX);
+#endif
+                                       break;
+
+               case PVRSRV_CACHE_OP_FLUSH:
+                                       ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+                                       /* To use the "deferred flush" (not clean) DDK feature you need a kernel
+                                        * implementation of outer_flush_all() for ARM CPUs with an outer cache
+                                        * controller (e.g. PL310, common with Cortex A9 and later).
+                                        *
+                                        * Reference DDKs don't require this functionality, as they will only
+                                        * clean the cache, never flush (clean+invalidate) it.
+                                        */
+                                       outer_flush_all();
+#endif
+                                       break;
+
+               case PVRSRV_CACHE_OP_NONE:
+                                       break;
+
+               default:
+                                       PVR_DPF((PVR_DBG_ERROR,
+                                       "%s: Invalid cache operation type %d",
+                                       __FUNCTION__, uiCacheOp));
+                                       PVR_ASSERT(0);
+                                       break;
+       }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd)
+{
+       return (size_t)((char *)pvEnd - (char *)pvStart);
+}
+#endif
+
+void OSFlushCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+       arm_dma_ops.sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
+       arm_dma_ops.sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
+#else  /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+       /* Inner cache */
+       dmac_flush_range(pvVirtStart, pvVirtEnd);
+
+       /* Outer cache */
+       outer_flush_range(sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+}
+
+void OSCleanCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+       arm_dma_ops.sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
+#else  /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+       /* Inner cache */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+       dmac_clean_range(pvVirtStart, pvVirtEnd);
+#else
+       dmac_map_area(pvVirtStart, pvr_dmac_range_len(pvVirtStart, pvVirtEnd), DMA_TO_DEVICE);
+#endif
+
+       /* Outer cache */
+       outer_clean_range(sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+}
+
+void OSInvalidateCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                                IMG_PVOID pvVirtEnd,
+                                                                IMG_CPU_PHYADDR sCPUPhysStart,
+                                                                IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+       arm_dma_ops.sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
+#else  /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+#if defined(PVR_LINUX_DONT_USE_RANGE_BASED_INVALIDATE)
+       OSCleanCPUCacheRangeKM(pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
+#else
+       /* Inner cache */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+       dmac_inv_range(pvVirtStart, pvVirtEnd);
+#else
+       dmac_map_area(pvVirtStart, pvr_dmac_range_len(pvVirtStart, pvVirtEnd), DMA_FROM_DEVICE);
+#endif
+
+       /* Outer cache */
+       outer_inv_range(sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr);
+#endif
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm64.c b/drivers/gpu/rogue_m/services/server/env/linux/osfunc_arm64.c
new file mode 100644 (file)
index 0000000..7d1fd3d
--- /dev/null
@@ -0,0 +1,116 @@
+/*************************************************************************/ /*!
+@File
+@Title          arm specific OS functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS functions who's implementation are processor specific
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+
+#if defined(CONFIG_OUTER_CACHE)
+  /* If you encounter a 64-bit ARM system with an outer cache, you'll need
+   * to add the necessary code to manage that cache.  See osfunc_arm.c 
+   * for an example of how to do so.
+   */
+       #error "CONFIG_OUTER_CACHE not supported on arm64."
+#endif
+
+
+static void per_cpu_cache_flush(void *arg)
+{
+       PVR_UNREFERENCED_PARAMETER(arg);
+       flush_cache_all();
+}
+
+void OSCPUOperation(PVRSRV_CACHE_OP uiCacheOp)
+{
+       switch(uiCacheOp)
+       {
+               /* Fall-through */
+               case PVRSRV_CACHE_OP_CLEAN:
+                                       /* No full (inner) cache clean op */
+                                       on_each_cpu(per_cpu_cache_flush, NULL, 1);
+                                       break;
+
+               case PVRSRV_CACHE_OP_FLUSH:
+                                       on_each_cpu(per_cpu_cache_flush, NULL, 1);
+                                       break;
+
+               case PVRSRV_CACHE_OP_NONE:
+                                       break;
+
+               default:
+                                       PVR_DPF((PVR_DBG_ERROR,
+                                       "%s: Invalid cache operation type %d",
+                                       __FUNCTION__, uiCacheOp));
+                                       PVR_ASSERT(0);
+                                       break;
+       }
+}
+
+void OSFlushCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       dma_ops->sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
+       dma_ops->sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
+}
+
+void OSCleanCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       dma_ops->sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
+}
+
+void OSInvalidateCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                                IMG_PVOID pvVirtEnd,
+                                                                IMG_CPU_PHYADDR sCPUPhysStart,
+                                                                IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       dma_ops->sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/osfunc_x86.c b/drivers/gpu/rogue_m/services/server/env/linux/osfunc_x86.c
new file mode 100644 (file)
index 0000000..346a712
--- /dev/null
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@File
+@Title          x86 specific OS functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS functions who's implementation are processor specific
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <linux/smp.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+#include <asm/system.h>
+#endif
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "img_defs.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+
+#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
+
+static void per_cpu_cache_flush(void *arg)
+{
+    PVR_UNREFERENCED_PARAMETER(arg);
+    wbinvd();
+}
+
+void OSCPUOperation(PVRSRV_CACHE_OP uiCacheOp)
+{
+       switch(uiCacheOp)
+       {
+               /* Fall-through */
+               case PVRSRV_CACHE_OP_CLEAN:
+               case PVRSRV_CACHE_OP_FLUSH:
+               case PVRSRV_CACHE_OP_INVALIDATE:
+                                       on_each_cpu(per_cpu_cache_flush, NULL, 1);
+                                       break;
+
+               case PVRSRV_CACHE_OP_NONE:
+                                       break;
+
+               default:
+                                       PVR_DPF((PVR_DBG_ERROR,
+                                       "%s: Invalid cache operation type %d",
+                                       __FUNCTION__, uiCacheOp));
+                                       PVR_ASSERT(0);
+                                       break;
+       }
+}
+
+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 *)PVR_ALIGN((IMG_UINTPTR_T)pbEnd,
+                                     (IMG_UINTPTR_T)boot_cpu_data.x86_clflush_size);
+
+       mb();
+       for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size)
+       {
+               clflush(pbBase);
+       }
+       mb();
+}
+
+void OSFlushCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
+
+       x86_flush_cache_range(pvVirtStart, pvVirtEnd);
+}
+
+
+void OSCleanCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                       IMG_PVOID pvVirtEnd,
+                                                       IMG_CPU_PHYADDR sCPUPhysStart,
+                                                       IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
+
+       /* No clean feature on x86 */
+       x86_flush_cache_range(pvVirtStart, pvVirtEnd);
+}
+
+void OSInvalidateCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                                IMG_PVOID pvVirtEnd,
+                                                                IMG_CPU_PHYADDR sCPUPhysStart,
+                                                                IMG_CPU_PHYADDR sCPUPhysEnd)
+{
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
+       PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
+
+       /* No invalidate-only support */
+       x86_flush_cache_range(pvVirtStart, pvVirtEnd);
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/ossecure_export.c b/drivers/gpu/rogue_m/services/server/env/linux/ossecure_export.c
new file mode 100644 (file)
index 0000000..e1c0864
--- /dev/null
@@ -0,0 +1,189 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/dcache.h>
+#include <linux/mount.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+
+#include "img_types.h"
+#include "ossecure_export.h"
+#include "private_data.h"
+#include "pvr_debug.h"
+#include "driverlock.h"
+
+#if defined(SUPPORT_DRM)
+#include "pvr_drm.h"
+#endif
+
+PVRSRV_ERROR OSSecureExport(CONNECTION_DATA *psConnection,
+                                                       IMG_PVOID pvData,
+                                                       IMG_SECURE_TYPE *phSecure,
+                                                       CONNECTION_DATA **ppsSecureConnection)
+{
+       CONNECTION_DATA *psSecureConnection;
+       struct file *connection_file;
+       struct file *secure_file;
+       struct dentry *secure_dentry;
+       struct vfsmount *secure_mnt;
+       int secure_fd;
+       IMG_BOOL bPmrUnlocked = IMG_FALSE;
+       PVRSRV_ERROR eError;
+
+       /* Obtain the current connections struct file */
+       connection_file = LinuxFileFromConnection(psConnection);
+
+       /* Allocate a fd number */
+       secure_fd = get_unused_fd();
+       if (secure_fd < 0)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       /*
+               Get a reference to the dentry so when close is called we don't
+               drop the last reference too early and delete the file
+       */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+       secure_dentry = dget(connection_file->f_path.dentry);
+       secure_mnt = mntget(connection_file->f_path.mnt);
+#else
+       secure_dentry = dget(connection_file->f_dentry);
+       secure_mnt = mntget(connection_file->f_vfsmnt);
+#endif
+
+       /* PMR lock needs to be released before bridge lock to keep lock hierarchy
+        * and avoid deadlock situation.
+        * OSSecureExport() can be called from functions that are not acquiring
+        * PMR lock (e.g. by PVRSRVSyncPrimServerSecureExportKM()) so we have to
+        * check if PMR lock is locked. */
+       if (PMRIsLockedByMe())
+       {
+               PMRUnlock();
+               bPmrUnlocked = IMG_TRUE;
+       }
+       OSReleaseBridgeLock();
+
+       /* Open our device (using the file information from our current connection) */
+       secure_file = dentry_open(
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
+                                         &connection_file->f_path,
+#else
+                                         connection_file->f_dentry,
+                                         connection_file->f_vfsmnt,
+#endif
+                                         connection_file->f_flags,
+                                         current_cred());
+
+       OSAcquireBridgeLock();
+       if (bPmrUnlocked)
+               PMRLock();
+
+       /* Bail if the open failed */
+       if (IS_ERR(secure_file))
+       {
+               put_unused_fd(secure_fd);
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       /* Return the new services connection our secure data created */
+       psSecureConnection = LinuxConnectionFromFile(secure_file);
+
+       if(psSecureConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Invalid connection data"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       /* Bind our struct file with it's fd number */
+       fd_install(secure_fd, secure_file);
+
+       /* Save the private data */
+       PVR_ASSERT(psSecureConnection->hSecureData == IMG_NULL);
+       psSecureConnection->hSecureData = pvData;
+
+       *phSecure = secure_fd;
+       *ppsSecureConnection = psSecureConnection;
+       return PVRSRV_OK;
+
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+PVRSRV_ERROR OSSecureImport(IMG_SECURE_TYPE hSecure, IMG_PVOID *ppvData)
+{
+       struct file *secure_file;
+       CONNECTION_DATA *psSecureConnection;
+       PVRSRV_ERROR eError;
+
+       secure_file = fget(hSecure);
+
+       if (!secure_file)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto err_out;
+       }
+
+       psSecureConnection = LinuxConnectionFromFile(secure_file);
+       if ((psSecureConnection == IMG_NULL) || (psSecureConnection->hSecureData == IMG_NULL))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Invalid connection data"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto err_fput;
+       }
+
+       *ppvData = psSecureConnection->hSecureData;
+       fput(secure_file);
+       return PVRSRV_OK;
+
+err_fput:
+       fput(secure_file);
+err_out:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pdump.c b/drivers/gpu/rogue_m/services/server/env/linux/pdump.c
new file mode 100644 (file)
index 0000000..e1fbf28
--- /dev/null
@@ -0,0 +1,462 @@
+/*************************************************************************/ /*!
+@File
+@Title          Parameter dump macro target routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if defined (PDUMP)
+
+#include <asm/atomic.h>
+#include <stdarg.h>
+
+#include "pvrversion.h"
+#include "pvr_debug.h"
+#include "pvrsrv.h"
+#include "osfunc.h"
+
+#include "dbgdrvif_srv5.h"
+#include "mm.h"
+#include "allocmem.h"
+#include "pdump_km.h"
+#include "pdump_osfunc.h"
+
+#include <linux/kernel.h> // sprintf
+#include <linux/string.h> // strncpy, strlen
+#include <linux/mutex.h>
+
+#define PDUMP_DATAMASTER_PIXEL         (1)
+#define PDUMP_DATAMASTER_EDM           (3)
+
+static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
+
+
+typedef struct PDBG_PDUMP_STATE_TAG
+{
+       PDBG_STREAM psStream[PDUMP_NUM_CHANNELS];
+
+       IMG_CHAR *pszMsg;
+       IMG_CHAR *pszScript;
+       IMG_CHAR *pszFile;
+
+} PDBG_PDUMP_STATE;
+
+static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 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
+
+static struct mutex gsPDumpMutex;
+
+void DBGDrvGetServiceTable(void **fn_table);
+
+
+/*!
+ * \name       PDumpOSGetScriptString
+ */
+PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
+                                                                       IMG_UINT32 *pui32MaxLen)
+{
+       *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
+       *pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
+       if (!*phScript)
+       {
+               return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSGetMessageString
+ */
+PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg,
+                                                                        IMG_UINT32 *pui32MaxLen)
+{
+       *ppszMsg = gsDBGPdumpState.pszMsg;
+       *pui32MaxLen = SZ_MSG_SIZE_MAX;
+       if (!*ppszMsg)
+       {
+               return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSGetFilenameString
+ */
+PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
+                                                                        IMG_UINT32 *pui32MaxLen)
+{
+       *ppszFile = gsDBGPdumpState.pszFile;
+       *pui32MaxLen = SZ_FILENAME_SIZE_MAX;
+       if (!*ppszFile)
+       {
+               return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+       }
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSBufprintf
+ */
+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)   /* glibc >= 2.1 or glibc 2.0 */
+       {
+               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
+
+       /* Put line ending sequence at the end if it isn't already there */
+       PDumpOSVerifyLineEnding(pszBuf, ui32ScriptSizeMax);
+
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSVSprintf
+ */
+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)   /* glibc >= 2.1 or glibc 2.0 */
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+               return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSDebugPrintf
+ */
+void PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
+{
+       PVR_UNREFERENCED_PARAMETER(pszFormat);
+
+       /* FIXME: Implement using services PVR_DBG or otherwise with kprintf */
+}
+
+/*!
+ * \name       PDumpOSSprintf
+ */
+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)   /* glibc >= 2.1 or glibc 2.0 */
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+               return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*!
+ * \name       PDumpOSBuflen
+ */
+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);
+}
+
+/*!
+ * \name       PDumpOSVerifyLineEnding
+ */
+void PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+       IMG_UINT32 ui32Count;
+       IMG_CHAR* pszBuf = hBuffer;
+
+       /* strlen */
+       ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
+
+       /* Put \n sequence at the end if it isn't already there */
+       if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
+       {
+               pszBuf[ui32Count] = '\n';
+               ui32Count++;
+               pszBuf[ui32Count] = '\0';
+       }
+}
+
+
+
+/*!
+ * \name       PDumpOSGetStreamOffset
+ */
+IMG_BOOL PDumpOSSetSplitMarker(IMG_HANDLE hStream, IMG_UINT32 ui32Marker)
+{
+       PDBG_STREAM psStream = (PDBG_STREAM) hStream;
+
+       PVR_ASSERT(gpfnDbgDrv);
+       gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
+       return IMG_TRUE;
+}
+
+/*!
+ *     \name   PDumpOSDebugDriverWrite
+ */
+IMG_UINT32 PDumpOSDebugDriverWrite( IMG_HANDLE psStream,
+                                                                       IMG_UINT8 *pui8Data,
+                                                                       IMG_UINT32 ui32BCount)
+{
+       PVR_ASSERT(gpfnDbgDrv != IMG_NULL);
+
+       return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount);
+}
+
+/*!
+ *     \name   PDumpOSReleaseExecution
+ */
+void PDumpOSReleaseExecution(void)
+{
+       OSReleaseThreadQuanta();
+}
+
+/**************************************************************************
+ * Function Name  : PDumpOSInit
+ * Outputs        : None
+ * Returns        :
+ * Description    : Reset connection to vldbgdrv
+ *                                     Then try to connect to PDUMP streams
+**************************************************************************/
+PVRSRV_ERROR PDumpOSInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript,
+               IMG_UINT32* pui32InitCapMode, IMG_CHAR** ppszEnvComment)
+{
+       PVRSRV_ERROR     eError;
+
+       *pui32InitCapMode = DEBUG_CAPMODE_FRAMED;
+       *ppszEnvComment = IMG_NULL;
+
+       /* If we tried this earlier, then we might have connected to the driver
+        * But if pdump.exe was running then the stream connected would fail
+        */
+       if (!gpfnDbgDrv)
+       {
+               DBGDrvGetServiceTable((void **)&gpfnDbgDrv);
+
+               // If something failed then no point in trying to connect streams
+               if (gpfnDbgDrv == IMG_NULL)
+               {
+                       return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+               }
+               
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               if(!gsDBGPdumpState.pszFile)
+               {
+                       gsDBGPdumpState.pszFile = OSAllocMem(SZ_FILENAME_SIZE_MAX);
+                       if (gsDBGPdumpState.pszFile == IMG_NULL)
+                       {
+                               goto init_failed;
+                       }
+               }
+
+               if(!gsDBGPdumpState.pszMsg)
+               {
+                       gsDBGPdumpState.pszMsg = OSAllocMem(SZ_MSG_SIZE_MAX);
+                       if (gsDBGPdumpState.pszMsg == IMG_NULL)
+                       {
+                               goto init_failed;
+                       }
+               }
+
+               if(!gsDBGPdumpState.pszScript)
+               {
+                       gsDBGPdumpState.pszScript = OSAllocMem(SZ_SCRIPT_SIZE_MAX);
+                       if (gsDBGPdumpState.pszScript == IMG_NULL)
+                       {
+                               goto init_failed;
+                       }
+               }
+
+               eError = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+               if (!gpfnDbgDrv->pfnCreateStream(PDUMP_PARAM_CHANNEL_NAME, 0, 10, &psParam->hInit, &psParam->hMain, &psParam->hDeinit))
+               {
+                       goto init_failed;
+               }
+               gsDBGPdumpState.psStream[PDUMP_CHANNEL_PARAM] = psParam->hMain;
+
+
+               if (!gpfnDbgDrv->pfnCreateStream(PDUMP_SCRIPT_CHANNEL_NAME, 0, 10, &psScript->hInit, &psScript->hMain, &psScript->hDeinit))
+               {
+                       goto init_failed;
+               }
+               gsDBGPdumpState.psStream[PDUMP_CHANNEL_SCRIPT] = psScript->hMain;
+       }
+
+       return PVRSRV_OK;
+
+init_failed:
+       PDumpOSDeInit(psParam, psScript);
+       return eError;
+}
+
+
+void PDumpOSDeInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript)
+{
+       gpfnDbgDrv->pfnDestroyStream(psScript->hInit, psScript->hMain, psScript->hDeinit);
+       gpfnDbgDrv->pfnDestroyStream(psParam->hInit, psParam->hMain, psParam->hDeinit);
+
+       if(gsDBGPdumpState.pszFile)
+       {
+               OSFreeMem(gsDBGPdumpState.pszFile);
+               gsDBGPdumpState.pszFile = IMG_NULL;
+       }
+
+       if(gsDBGPdumpState.pszScript)
+       {
+               OSFreeMem(gsDBGPdumpState.pszScript);
+               gsDBGPdumpState.pszScript = IMG_NULL;
+       }
+
+       if(gsDBGPdumpState.pszMsg)
+       {
+               OSFreeMem(gsDBGPdumpState.pszMsg);
+               gsDBGPdumpState.pszMsg = IMG_NULL;
+       }
+
+       gpfnDbgDrv = IMG_NULL;
+}
+
+PVRSRV_ERROR PDumpOSCreateLock(void)
+{
+       mutex_init(&gsPDumpMutex);
+       return PVRSRV_OK;
+}
+
+void PDumpOSDestroyLock(void)
+{
+       /* no destruction work to do, just assert
+        * the lock is not held */
+       PVR_ASSERT(mutex_is_locked(&gsPDumpMutex) == 0);
+}
+
+void PDumpOSLock(void)
+{
+       mutex_lock(&gsPDumpMutex);
+}
+
+void PDumpOSUnlock(void)
+{
+       mutex_unlock(&gsPDumpMutex);
+}
+
+IMG_UINT32 PDumpOSGetCtrlState(IMG_HANDLE hDbgStream,
+               IMG_UINT32 ui32StateID)
+{
+       return (gpfnDbgDrv->pfnGetCtrlState((PDBG_STREAM)hDbgStream, ui32StateID));
+}
+
+void PDumpOSSetFrame(IMG_UINT32 ui32Frame)
+{
+       gpfnDbgDrv->pfnSetFrame(ui32Frame);
+       return;
+}
+
+IMG_BOOL PDumpOSAllowInitPhaseToComplete(IMG_UINT32 eModuleID)
+{
+       return (eModuleID != IMG_PDUMPCTRL);
+}
+
+#if defined(PVR_TESTING_UTILS)
+void PDumpOSDumpState(void);
+
+void PDumpOSDumpState(void)
+{
+       PVR_LOG(("---- PDUMP LINUX: gpfnDbgDrv( %p )  gpfnDbgDrv.ui32Size( %d )",
+                       gpfnDbgDrv, gpfnDbgDrv->ui32Size));
+
+       PVR_LOG(("---- PDUMP LINUX: gsDBGPdumpState( %p )",
+                       &gsDBGPdumpState));
+
+       PVR_LOG(("---- PDUMP LINUX: gsDBGPdumpState.psStream[0]( %p )",
+                       gsDBGPdumpState.psStream[0]));
+
+       (void) gpfnDbgDrv->pfnGetCtrlState(gsDBGPdumpState.psStream[0], 0xFE);
+
+       PVR_LOG(("---- PDUMP LINUX: gsDBGPdumpState.psStream[1]( %p )",
+                       gsDBGPdumpState.psStream[1]));
+
+       (void) gpfnDbgDrv->pfnGetCtrlState(gsDBGPdumpState.psStream[1], 0xFE);
+
+       /* Now dump non-stream specific info */
+       (void) gpfnDbgDrv->pfnGetCtrlState(gsDBGPdumpState.psStream[1], 0xFF);
+}
+#endif
+
+#endif /* #if defined (PDUMP) */
+/*****************************************************************************
+ End of file (PDUMP.C)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/physmem_dmabuf.c b/drivers/gpu/rogue_m/services/server/env/linux/physmem_dmabuf.c
new file mode 100644 (file)
index 0000000..64b6cb5
--- /dev/null
@@ -0,0 +1,718 @@
+/*************************************************************************/ /*!
+@File           physmem_dmabuf.c
+@Title          dmabuf memory allocator
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management. This module is responsible for
+                implementing the function callbacks for dmabuf memory.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(SUPPORT_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if !defined(SUPPORT_DRM) || defined(PVR_DRM_USE_PRIME)
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pvrsrv.h"
+#include "pdump_physmem.h"
+#include "pmr.h"
+#include "pmr_impl.h"
+#include "physmem_dmabuf.h"
+
+#if defined(SUPPORT_ION)
+#include "hash.h"
+#include "ion_sys.h"
+#endif
+
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
+
+#if defined(LDM_PCI)
+#include <linux/pci.h>
+#elif defined(LDM_PLATFORM)
+#include <linux/platform_device.h>
+#else
+#error Either LDM_PCI or LDM_PLATFORM must be defined
+#endif
+
+typedef struct _PMR_DMA_BUF_DATA_
+{
+       /* Filled in at PMR create time */
+       PHYS_HEAP *psPhysHeap;
+       struct dma_buf_attachment *psAttachment;
+       PFN_DESTROY_DMABUF_PMR pfnDestroy;
+       IMG_BOOL bPoisonOnFree;
+       IMG_HANDLE hPDumpAllocInfo;
+
+       /* Modified by PMR lock/unlock */
+       struct sg_table *psSgTable;
+       IMG_DEV_PHYADDR *pasDevPhysAddr;
+       IMG_UINT32 ui32PageCount;
+} PMR_DMA_BUF_DATA;
+
+/* Start size of the g_psDmaBufHash hash table */
+#define DMA_BUF_HASH_SIZE 20
+
+extern
+#if defined(LDM_PCI)
+       struct pci_dev
+#elif defined(LDM_PLATFORM)
+       struct platform_device
+#endif
+       *gpsPVRLDMDev;
+
+#if defined(SUPPORT_ION)
+static HASH_TABLE *g_psDmaBufHash = IMG_NULL;
+static IMG_UINT32 g_ui32HashRefCount = 0;
+#endif
+
+#if defined(PVR_ANDROID_ION_USE_SG_LENGTH)
+#define pvr_sg_length(sg) ((sg)->length)
+#else
+#define pvr_sg_length(sg) sg_dma_len(sg)
+#endif
+
+static const IMG_CHAR _AllocPoison[] = "^PoIsOn";
+static const IMG_UINT32 _AllocPoisonSize = 7;
+static const IMG_CHAR _FreePoison[] = "<DEAD-BEEF>";
+static const IMG_UINT32 _FreePoisonSize = 11;
+
+static void _Poison(IMG_PVOID pvKernAddr,
+                   IMG_DEVMEM_SIZE_T uiBufferSize,
+                   const IMG_CHAR *pacPoisonData,
+                   IMG_SIZE_T uiPoisonSize)
+{
+       IMG_DEVMEM_SIZE_T uiDestByteIndex;
+       IMG_CHAR *pcDest = pvKernAddr;
+       IMG_UINT32 uiSrcByteIndex = 0;
+
+       for (uiDestByteIndex = 0; uiDestByteIndex < uiBufferSize; uiDestByteIndex++)
+       {
+               pcDest[uiDestByteIndex] = pacPoisonData[uiSrcByteIndex];
+               uiSrcByteIndex++;
+               if (uiSrcByteIndex == uiPoisonSize)
+               {
+                       uiSrcByteIndex = 0;
+               }
+       }
+}
+
+
+/*****************************************************************************
+ *                       PMR callback functions                              *
+ *****************************************************************************/
+
+static PVRSRV_ERROR PMRFinalizeDmaBuf(PMR_IMPL_PRIVDATA pvPriv)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
+       PVRSRV_ERROR eError;
+
+       if (psPrivData->hPDumpAllocInfo)
+       {
+               PDumpPMRFree(psPrivData->hPDumpAllocInfo);
+               psPrivData->hPDumpAllocInfo = NULL;
+       }
+
+       if (psPrivData->bPoisonOnFree)
+       {
+               IMG_PVOID pvKernAddr;
+               int i, err;
+
+               err = dma_buf_begin_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_FROM_DEVICE);
+               if (err)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to begin cpu access for free poisoning", __func__));
+                       PVR_ASSERT(IMG_FALSE);
+                       goto exit;
+               }
+
+               for (i = 0; i < psDmaBuf->size / PAGE_SIZE; i++)
+               {
+                       pvKernAddr = dma_buf_kmap(psDmaBuf, i);
+                       if (IS_ERR_OR_NULL(pvKernAddr))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to poison allocation before free", __func__));
+                               PVR_ASSERT(IMG_FALSE);
+                               goto exit_end_access;
+                       }
+
+                       _Poison(pvKernAddr, PAGE_SIZE, _FreePoison, _FreePoisonSize);
+
+                       dma_buf_kunmap(psDmaBuf, i, pvKernAddr);
+               }
+
+exit_end_access:
+               dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_TO_DEVICE);
+       }
+
+exit:
+       if (psPrivData->pfnDestroy)
+       {
+               eError = psPrivData->pfnDestroy(psPrivData->psPhysHeap, psPrivData->psAttachment);
+               if (eError != PVRSRV_OK)
+               {
+                       return eError;
+               }
+       }
+
+       OSFreeMem(psPrivData);
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR PMRLockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
+                                              IMG_UINT32 uiLog2DevPageSize)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       struct dma_buf_attachment *psAttachment = psPrivData->psAttachment;
+       IMG_DEV_PHYADDR *pasDevPhysAddr = NULL;
+       IMG_CPU_PHYADDR sCpuPhysAddr;
+       IMG_UINT32 ui32PageCount = 0;
+       struct scatterlist *sg;
+       struct sg_table *table;
+       PVRSRV_ERROR eError;
+       IMG_UINT32 i;
+
+       table = dma_buf_map_attachment(psAttachment, DMA_BIDIRECTIONAL);
+       if (!table)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_map;
+       }
+
+       /*
+        * We do a two pass process, 1st workout how many pages there
+        * are, 2nd fill in the data.
+        */
+       for_each_sg(table->sgl, sg, table->nents, i)
+       {
+               ui32PageCount += PAGE_ALIGN(pvr_sg_length(sg)) / PAGE_SIZE;
+       }
+
+       if (WARN_ON(!ui32PageCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lock dmabuf with no pages",
+                                __func__));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_page_count;
+       }
+
+       pasDevPhysAddr = OSAllocMem(sizeof(*pasDevPhysAddr) * ui32PageCount);
+       if (!pasDevPhysAddr)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       ui32PageCount = 0;
+
+       for_each_sg(table->sgl, sg, table->nents, i)
+       {
+               IMG_UINT32 j;
+
+               for (j = 0; j < pvr_sg_length(sg); j += PAGE_SIZE)
+               {
+                       /* Pass 2: Get the page data */
+                       sCpuPhysAddr.uiAddr = sg_phys(sg) + j;
+
+                       PhysHeapCpuPAddrToDevPAddr(psPrivData->psPhysHeap, 
+                                                  1,
+                                                  &pasDevPhysAddr[ui32PageCount],
+                                                  &sCpuPhysAddr);
+                       ui32PageCount++;
+               }
+       }
+
+       psPrivData->pasDevPhysAddr = pasDevPhysAddr;
+       psPrivData->ui32PageCount = ui32PageCount;
+       psPrivData->psSgTable = table;
+
+       return PVRSRV_OK;
+
+fail_alloc:
+fail_page_count:
+       dma_buf_unmap_attachment(psAttachment, table, DMA_BIDIRECTIONAL);
+
+fail_map:
+       PVR_ASSERT(eError!= PVRSRV_OK);
+       return eError;
+}
+
+static PVRSRV_ERROR PMRUnlockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       struct dma_buf_attachment *psAttachment = psPrivData->psAttachment;
+       struct sg_table *psSgTable = psPrivData->psSgTable;
+
+       OSFreeMem(psPrivData->pasDevPhysAddr);
+
+       psPrivData->pasDevPhysAddr = NULL;
+       psPrivData->ui32PageCount = 0;
+
+       dma_buf_unmap_attachment(psAttachment, psSgTable, DMA_BIDIRECTIONAL);
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR PMRDevPhysAddrDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
+                                        IMG_UINT32 ui32NumOfPages,
+                                        IMG_DEVMEM_OFFSET_T *puiOffset,
+                                        IMG_BOOL *pbValid,
+                                        IMG_DEV_PHYADDR *psDevPAddr)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       IMG_UINT32 ui32PageIndex;
+       IMG_UINT32 idx;
+
+       for (idx=0; idx < ui32NumOfPages; idx++)
+       {
+               if (pbValid[idx])
+               {
+                       IMG_UINT32 ui32InPageOffset;
+
+                       ui32PageIndex = puiOffset[idx] >> PAGE_SHIFT;
+                       ui32InPageOffset = puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)ui32PageIndex << PAGE_SHIFT);
+
+                       PVR_ASSERT(ui32PageIndex < psPrivData->ui32PageCount);
+                       PVR_ASSERT(ui32InPageOffset < PAGE_SIZE);
+
+                       psDevPAddr[idx].uiAddr = psPrivData->pasDevPhysAddr[ui32PageIndex].uiAddr + ui32InPageOffset;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRAcquireKernelMappingDataDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
+                                 IMG_SIZE_T uiOffset,
+                                 IMG_SIZE_T uiSize,
+                                 void **ppvKernelAddressOut,
+                                 IMG_HANDLE *phHandleOut,
+                                 PMR_FLAGS_T ulFlags)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
+       IMG_PVOID pvKernAddr;
+       PVRSRV_ERROR eError;
+       int err;
+
+       err = dma_buf_begin_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+       if (err)
+       {
+               eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+               goto fail;
+       }
+
+       pvKernAddr = dma_buf_vmap(psDmaBuf);
+       if (IS_ERR_OR_NULL(pvKernAddr))
+       {
+               eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+               goto fail_kmap;
+       }
+
+       *ppvKernelAddressOut = pvKernAddr + uiOffset;
+       *phHandleOut = pvKernAddr;
+
+       return PVRSRV_OK;
+
+fail_kmap:
+       dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+
+fail:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+static void PMRReleaseKernelMappingDataDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
+                                             IMG_HANDLE hHandle)
+{
+       PMR_DMA_BUF_DATA *psPrivData = pvPriv;
+       struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
+       IMG_PVOID pvKernAddr = hHandle;
+
+       dma_buf_vunmap(psDmaBuf, pvKernAddr);
+
+       dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+}
+
+static PMR_IMPL_FUNCTAB _sPMRDmaBufFuncTab =
+{
+       .pfnLockPhysAddresses           = PMRLockPhysAddressesDmaBuf,
+       .pfnUnlockPhysAddresses         = PMRUnlockPhysAddressesDmaBuf,
+       .pfnDevPhysAddr                 = PMRDevPhysAddrDmaBuf,
+       .pfnAcquireKernelMappingData    = PMRAcquireKernelMappingDataDmaBuf,
+       .pfnReleaseKernelMappingData    = PMRReleaseKernelMappingDataDmaBuf,
+       .pfnFinalize                    = PMRFinalizeDmaBuf,
+};
+
+/*****************************************************************************
+ *                       Public facing interface                             *
+ *****************************************************************************/
+
+PVRSRV_ERROR
+PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap,
+                               struct dma_buf_attachment *psAttachment,
+                               PFN_DESTROY_DMABUF_PMR pfnDestroy,
+                               PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                               PMR **ppsPMRPtr)
+{
+       struct dma_buf *psDmaBuf = psAttachment->dmabuf;
+       PMR_DMA_BUF_DATA *psPrivData;
+       IMG_BOOL bMappingTable = IMG_TRUE;
+       PMR_FLAGS_T uiPMRFlags;
+       IMG_BOOL bZeroOnAlloc;
+       IMG_BOOL bPoisonOnAlloc;
+       IMG_BOOL bPoisonOnFree;
+       PVRSRV_ERROR eError;
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+       {
+               bZeroOnAlloc = IMG_TRUE;
+       }
+       else
+       {
+               bZeroOnAlloc = IMG_FALSE;
+       }
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)
+       {
+               bPoisonOnAlloc = IMG_TRUE;
+       }
+       else
+       {
+               bPoisonOnAlloc = IMG_FALSE;
+       }
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE)
+       {
+               bPoisonOnFree = IMG_TRUE;
+       }
+       else
+       {
+               bPoisonOnFree = IMG_FALSE;
+       }
+
+       if (bZeroOnAlloc && bPoisonOnFree)
+       {
+               /* Zero on Alloc and Poison on Alloc are mutually exclusive */
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_params;
+       }
+
+       psPrivData = OSAllocZMem(sizeof(*psPrivData));
+       if (psPrivData == NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_priv_alloc;
+       }
+
+       psPrivData->psPhysHeap = psHeap;
+       psPrivData->psAttachment = psAttachment;
+       psPrivData->pfnDestroy = pfnDestroy;
+       psPrivData->bPoisonOnFree = bPoisonOnFree;
+
+       if (bZeroOnAlloc || bPoisonOnAlloc)
+       {
+               IMG_PVOID pvKernAddr;
+               int i, err;
+
+               err = dma_buf_begin_cpu_access(psDmaBuf,
+                                              0,
+                                              psDmaBuf->size,
+                                              DMA_FROM_DEVICE);
+               if (err)
+               {
+                       eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+                       goto fail_begin;
+               }
+
+               for (i = 0; i < psDmaBuf->size / PAGE_SIZE; i++)
+               {
+                       pvKernAddr = dma_buf_kmap(psDmaBuf, i);
+                       if (IS_ERR_OR_NULL(pvKernAddr))
+                       {
+                               PVR_DPF((PVR_DBG_ERROR,
+                                        "%s: Failed to map page for %s",
+                                        __func__,
+                                        bZeroOnAlloc ? "zeroing" : "poisoning"));
+                               eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+
+                               dma_buf_end_cpu_access(psDmaBuf,
+                                                      0,
+                                                      psDmaBuf->size,
+                                                      DMA_TO_DEVICE);
+
+                               goto fail_kmap;
+                       }
+
+                       if (bZeroOnAlloc)
+                       {
+                               memset(pvKernAddr, 0, PAGE_SIZE);
+                       }
+                       else
+                       {
+                               _Poison(pvKernAddr, PAGE_SIZE, _AllocPoison, _AllocPoisonSize);
+                       }
+
+                       dma_buf_kunmap(psDmaBuf, i, pvKernAddr);
+               }
+
+               dma_buf_end_cpu_access(psDmaBuf,
+                                      0,
+                                      psDmaBuf->size,
+                                      DMA_TO_DEVICE);
+       }
+
+       uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
+
+       /*
+        * Check no significant bits were lost in cast due to different
+        * bit widths for flags
+        */
+       PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
+
+       eError = PMRCreatePMR(psHeap,
+                             psDmaBuf->size,
+                             psDmaBuf->size,
+                             1,
+                             1,
+                             &bMappingTable,
+                             PAGE_SHIFT,
+                             uiPMRFlags,
+                             "PMRDMABUF",
+                             &_sPMRDmaBufFuncTab,
+                             psPrivData,
+                             ppsPMRPtr,
+                             &psPrivData->hPDumpAllocInfo,
+                             IMG_FALSE);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create PMR", __func__));
+               goto fail_create_pmr;
+       }
+
+#if defined(PVR_RI_DEBUG)
+       eError = RIWritePMREntryKM(*ppsPMRPtr,
+                                  sizeof("DMABUF"),
+                                  "DMABUF",
+                                  psDmaBuf->size);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_WARNING,
+                        "%s: Failed to write PMR entry (%s)",
+                        __func__, PVRSRVGetErrorStringKM(eError)));
+       }
+#endif
+
+       return PVRSRV_OK;
+
+fail_create_pmr:
+fail_kmap:
+fail_begin:
+       OSFreeMem(psPrivData);
+
+fail_priv_alloc:
+fail_params:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+#if defined(SUPPORT_ION)
+static PVRSRV_ERROR PhysmemDestroyDmaBuf(PHYS_HEAP *psHeap,
+                                        struct dma_buf_attachment *psAttachment)
+{
+       struct dma_buf *psDmaBuf = psAttachment->dmabuf;
+
+       HASH_Remove(g_psDmaBufHash, (IMG_UINTPTR_T) psDmaBuf);
+       g_ui32HashRefCount--;
+
+       if (g_ui32HashRefCount == 0)
+       {
+               HASH_Delete(g_psDmaBufHash);
+               g_psDmaBufHash = IMG_NULL;
+       }
+
+       PhysHeapRelease(psHeap);
+
+       dma_buf_detach(psDmaBuf, psAttachment);
+       dma_buf_put(psDmaBuf);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+PhysmemImportDmaBuf(CONNECTION_DATA *psConnection,
+                   IMG_INT fd,
+                   PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                   PMR **ppsPMRPtr,
+                   IMG_DEVMEM_SIZE_T *puiSize,
+                   IMG_DEVMEM_ALIGN_T *puiAlign)
+{
+       PMR *psPMR;
+       struct dma_buf_attachment *psAttachment;
+       struct dma_buf *psDmaBuf;
+       PHYS_HEAP *psHeap;
+       PVRSRV_ERROR eError;
+
+       if (!psConnection)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto fail_params;
+       }
+
+       /* Get the buffer handle */
+       psDmaBuf = dma_buf_get(fd);
+       if (IS_ERR_OR_NULL(psDmaBuf))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: dma_buf_get failed", __func__));
+               eError = PVRSRV_ERROR_BAD_MAPPING;
+               goto fail_dma_buf_get;
+       }
+
+       if (g_psDmaBufHash)
+       {
+               /* We have a hash table so check if we've seen this dmabuf before */
+               psPMR = (PMR *) HASH_Retrieve(g_psDmaBufHash, (IMG_UINTPTR_T) psDmaBuf);
+               if (psPMR)
+               {
+                       /* Reuse the PMR we already created */
+                       PMRRefPMR(psPMR);
+
+                       *ppsPMRPtr = psPMR;
+                       *puiSize = psDmaBuf->size;
+                       *puiAlign = PAGE_SIZE;
+
+                       dma_buf_put(psDmaBuf);
+
+                       return PVRSRV_OK;
+               }
+       }
+
+       /* Attach a fake device to to the dmabuf */
+       psAttachment = dma_buf_attach(psDmaBuf, &gpsPVRLDMDev->dev);
+       if (IS_ERR_OR_NULL(psAttachment))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: dma_buf_get failed", __func__));
+               eError = PVRSRV_ERROR_BAD_MAPPING;
+               goto fail_dma_buf_attach;
+       }
+
+       /*
+        * Get the physical heap for this PMR
+        *      
+        * Note:
+        * While we have no way to determine the type of the buffer
+        * we just assume that all dmabufs are from the same
+        * physical heap.
+        */
+       eError = PhysHeapAcquire(IonPhysHeapID(), &psHeap);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed PhysHeapAcquire", __func__));
+               goto fail_physheap;
+       }
+
+       eError = PhysmemCreateNewDmaBufBackedPMR(psHeap,
+                                                psAttachment,
+                                                PhysmemDestroyDmaBuf,
+                                                uiFlags,
+                                                &psPMR);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_create_new_pmr;
+       }
+
+       if (!g_psDmaBufHash)
+       {
+               /*
+                * As different processes may import the same dmabuf we need to
+                * create a hash table so we don't generate a duplicate PMR but
+                * rather just take a reference on an existing one.
+                */
+               g_psDmaBufHash = HASH_Create(DMA_BUF_HASH_SIZE);
+               if (!g_psDmaBufHash)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto fail_hash_create;
+               }
+       }
+
+       /* First time we've seen this dmabuf so store it in the hash table */
+       HASH_Insert(g_psDmaBufHash, (IMG_UINTPTR_T) psDmaBuf, (IMG_UINTPTR_T) psPMR);
+       g_ui32HashRefCount++;
+
+       *ppsPMRPtr = psPMR;
+       *puiSize = psDmaBuf->size;
+       *puiAlign = PAGE_SIZE;
+
+       return PVRSRV_OK;
+
+fail_hash_create:
+       PMRUnrefPMR(psPMR);
+
+fail_create_new_pmr:
+       PhysHeapRelease(psHeap);
+
+fail_physheap:
+       dma_buf_detach(psDmaBuf, psAttachment);
+
+fail_dma_buf_attach:
+       dma_buf_put(psDmaBuf);
+
+fail_dma_buf_get:
+fail_params:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+#endif /* defined(SUPPORT_ION) */
+#endif /* !defined(SUPPORT_DRM) || defined(PVR_DRM_USE_PRIME) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.c b/drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.c
new file mode 100644 (file)
index 0000000..a0fd3a6
--- /dev/null
@@ -0,0 +1,2061 @@
+/*************************************************************************/ /*!
+@File
+@Title          Implementation of PMR functions for OS managed memory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management.  This module is responsible for
+                implementing the function callbacks for physical memory borrowed
+                from that normally managed by the operating system.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* include5/ */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pdump_physmem.h"
+#include "pdump_km.h"
+#include "pmr.h"
+#include "pmr_impl.h"
+#include "devicemem_server_utils.h"
+
+/* ourselves */
+#include "physmem_osmem.h"
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "process_stats.h"
+#endif
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,0,0))
+#include <linux/mm.h>
+#define PHYSMEM_SUPPORTS_SHRINKER
+#endif
+
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/mm_types.h>
+#include <linux/vmalloc.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <linux/atomic.h>
+#include <asm/io.h>
+#if defined(CONFIG_X86)
+#include <asm/cacheflush.h>
+#endif
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined (CONFIG_METAG)
+#include "osfunc.h"
+#endif
+
+#if defined(CONFIG_X86)
+#define PMR_UNSET_PAGES_STACK_ALLOC 64
+#endif
+
+/* Provide SHRINK_STOP definition for kernel older than 3.12 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0))
+#define SHRINK_STOP (~0UL)
+#endif
+
+#include "physmem_osmem_linux.h"
+
+#if  (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+/* split_pages() not available on older-kernels */
+#if (PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER > 0)
+/* This includes bin (i.e. bucket) for order-0 */
+#define ALLOC_ORDER_ARRAY_SIZE (PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER+1)
+#define PHYSMEM_USING_HIGH_ALLOC_ORDER
+
+static IMG_UINT32 g_uiCutOffOrder = PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER;
+#endif
+#endif
+
+/* guard against too big a backlog of deferred freeing of pages */
+#define MAX_OUTSTANDING_DEFERRED_FREE_PAGES 32768
+static atomic_t g_uiNumDeferredFreePages = ATOMIC_INIT(0);
+
+struct _PMR_OSPAGEARRAY_DATA_ {
+    /*
+      uiNumPages:
+
+      number of "pages" (a.k.a. macro pages, compound pages, higher
+      order pages, etc...)
+    */
+    IMG_UINT32 uiNumPages;
+
+    /*
+      uiLog2PageSize;
+
+      size of each "page" -- this would normally be the same as
+      PAGE_SHIFT, but we support the idea that we may allocate pages
+      in larger chunks for better contiguity, using order>0 in the
+      call to alloc_pages()
+    */
+    IMG_UINT32 uiLog2PageSize;
+
+    /*
+      the pages thusly allocated...  N.B.. One entry per compound page,
+      where compound pages are used.
+    */
+    struct page **pagearray;
+
+    /*
+      for pdump...
+    */
+    IMG_BOOL bPDumpMalloced;
+    IMG_HANDLE hPDumpAllocInfo;
+
+    /*
+      record at alloc time whether poisoning will be required when the
+      PMR is freed.
+    */
+    IMG_BOOL bZero;
+    IMG_BOOL bPoisonOnFree;
+    IMG_BOOL bPoisonOnAlloc;
+    IMG_BOOL bHasOSPages;
+    IMG_BOOL bOnDemand;
+    /*
+        The cache mode of the PMR (required at free time)
+        Boolean used to track if we need to revert the cache attributes
+        of the pages used in this allocation. Depends on OS/architecture.
+       */
+    IMG_UINT32 ui32CPUCacheFlags;
+       IMG_BOOL bUnsetMemoryType;
+
+       /* Structure which is hooked into the cleanup thread work list */
+       PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn;
+};
+
+/***********************************
+ * Page pooling for uncached pages *
+ ***********************************/
+static void
+_FreeOSPage(IMG_UINT32 ui32CPUCacheFlags,
+                       IMG_UINT32 uiOrder,
+                       IMG_BOOL bUnsetMemoryType,
+                       IMG_BOOL bFreeToOS,
+                       struct page *psPage);
+typedef        struct
+{
+       /* Linkage for page pool LRU list */
+       struct list_head sPagePoolItem;
+
+       struct page *psPage;
+} LinuxPagePoolEntry;
+
+static IMG_UINT32 g_ui32PagePoolEntryCount = 0;
+
+#if defined(PVR_LINUX_PHYSMEM_MAX_POOL_PAGES)
+static IMG_UINT32 g_ui32PagePoolMaxEntries = PVR_LINUX_PHYSMEM_MAX_POOL_PAGES;
+#else
+static IMG_UINT32 g_ui32PagePoolMaxEntries = 0;
+#endif
+
+/* Global structures we use to manage the page pool */
+static DEFINE_MUTEX(g_sPagePoolMutex);
+
+static struct kmem_cache *g_psLinuxPagePoolCache = IMG_NULL;
+
+static LIST_HEAD(g_sPagePoolList);
+static LIST_HEAD(g_sUncachedPagePoolList);
+
+static inline void
+_PagePoolLock(void)
+{
+       mutex_lock(&g_sPagePoolMutex);
+}
+
+static inline int
+_PagePoolTrylock(void)
+{
+       return mutex_trylock(&g_sPagePoolMutex);
+}
+
+static inline void
+_PagePoolUnlock(void)
+{
+       mutex_unlock(&g_sPagePoolMutex);
+}
+
+static LinuxPagePoolEntry *
+_LinuxPagePoolEntryAlloc(void)
+{
+    return kmem_cache_zalloc(g_psLinuxPagePoolCache, GFP_KERNEL);
+}
+
+static inline IMG_BOOL _GetPoolListHead(IMG_UINT32 ui32CPUCacheFlags, struct list_head **ppsPoolHead)
+{
+       switch(ui32CPUCacheFlags)
+       {
+               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+/*
+       For x86 we need to keep different lists for uncached
+       and write-combined as we must always honour the PAT
+       setting which cares about this difference.
+*/
+#if defined(CONFIG_X86)
+                       *ppsPoolHead = &g_sUncachedPagePoolList;
+                       break;
+#else
+                       /* Fall-through */
+#endif
+               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+                       *ppsPoolHead = &g_sPagePoolList;
+                       break;
+               default:
+                       return IMG_FALSE;
+       }
+       return IMG_TRUE;
+}
+
+static void
+_LinuxPagePoolEntryFree(LinuxPagePoolEntry *psPagePoolEntry)
+{
+       kmem_cache_free(g_psLinuxPagePoolCache, psPagePoolEntry);
+}
+
+static inline IMG_BOOL
+_AddEntryToPool(struct page *psPage, IMG_UINT32 ui32CPUCacheFlags)
+{
+       LinuxPagePoolEntry *psEntry;
+       struct list_head *psPoolHead = IMG_NULL;
+
+       if (!_GetPoolListHead(ui32CPUCacheFlags, &psPoolHead))
+       {
+               return IMG_FALSE;
+       }
+
+       psEntry = _LinuxPagePoolEntryAlloc();
+       if (psEntry == NULL)
+       {
+               return IMG_FALSE;
+       }
+
+       psEntry->psPage = psPage;
+       _PagePoolLock();
+       list_add_tail(&psEntry->sPagePoolItem, psPoolHead);
+       g_ui32PagePoolEntryCount++;
+       _PagePoolUnlock();
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       /* MemStats usually relies on having the bridge lock held, however
+        * the page pool code may call PVRSRVStatsIncrMemAllocPoolStat and
+        * PVRSRVStatsDecrMemAllocPoolStat without the bridge lock held, so
+        * the page pool lock is used to ensure these calls are mutually
+        * exclusive
+        */
+       _PagePoolLock();
+       PVRSRVStatsIncrMemAllocPoolStat(PAGE_SIZE);
+       _PagePoolUnlock();
+#endif
+
+       return IMG_TRUE;
+}
+
+static inline void
+_RemoveEntryFromPoolUnlocked(LinuxPagePoolEntry *psPagePoolEntry)
+{
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       /* MemStats usually relies on having the bridge lock held, however
+        * the page pool code may call PVRSRVStatsIncrMemAllocPoolStat and
+        * PVRSRVStatsDecrMemAllocPoolStat without the bridge lock held, so
+        * the page pool lock is used to ensure these calls are mutually
+        * exclusive
+        */
+       PVRSRVStatsDecrMemAllocPoolStat(PAGE_SIZE);
+#endif
+
+       list_del(&psPagePoolEntry->sPagePoolItem);
+       g_ui32PagePoolEntryCount--;
+}
+
+static inline struct page *
+_RemoveFirstEntryFromPool(IMG_UINT32 ui32CPUCacheFlags)
+{
+       LinuxPagePoolEntry *psPagePoolEntry;
+       struct page *psPage;
+       struct list_head *psPoolHead = IMG_NULL;
+
+       if (!_GetPoolListHead(ui32CPUCacheFlags, &psPoolHead))
+       {
+               return NULL;
+       }
+
+       _PagePoolLock();
+       if (list_empty(psPoolHead))
+       {
+               _PagePoolUnlock();
+               return NULL;
+       }
+
+       PVR_ASSERT(g_ui32PagePoolEntryCount > 0);
+       psPagePoolEntry = list_first_entry(psPoolHead, LinuxPagePoolEntry, sPagePoolItem);
+       _RemoveEntryFromPoolUnlocked(psPagePoolEntry);
+
+       psPage = psPagePoolEntry->psPage;
+       _LinuxPagePoolEntryFree(psPagePoolEntry);
+       _PagePoolUnlock();
+
+       return psPage;
+}
+
+#if defined(PHYSMEM_SUPPORTS_SHRINKER)
+static struct shrinker g_sShrinker;
+
+static unsigned long
+_CountObjectsInPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl)
+{
+       int remain;
+
+       PVR_ASSERT(psShrinker == &g_sShrinker);
+       (void)psShrinker;
+       (void)psShrinkControl;
+
+       /* In order to avoid possible deadlock use mutex_trylock in place of mutex_lock */
+       if (_PagePoolTrylock() == 0)
+               return 0;
+       remain = g_ui32PagePoolEntryCount;
+       _PagePoolUnlock();
+
+       return remain;
+}
+
+static unsigned long
+_ScanObjectsInPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl)
+{
+       unsigned long uNumToScan = psShrinkControl->nr_to_scan;
+       LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry;
+       int remain;
+
+       PVR_ASSERT(psShrinker == &g_sShrinker);
+       (void)psShrinker;
+
+       /* In order to avoid possible deadlock use mutex_trylock in place of mutex_lock */
+       if (_PagePoolTrylock() == 0)
+               return SHRINK_STOP;
+       list_for_each_entry_safe(psPagePoolEntry,
+                                psTempPoolEntry,
+                                &g_sPagePoolList,
+                                sPagePoolItem)
+       {
+               _RemoveEntryFromPoolUnlocked(psPagePoolEntry);
+
+               /*
+                 We don't want to save the cache type and is we need to unset the
+                 memory type as it would double the page pool structure and the
+                 values are always going to be the same anyway which is why the
+                 page is in the pool (well the page could be UNCACHED or
+                 WRITE_COMBINE but we don't even need the cache type for freeing
+                 back to the OS).
+               */
+               _FreeOSPage(PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE,
+                           0,
+                           IMG_TRUE,
+                           IMG_TRUE,
+                           psPagePoolEntry->psPage);
+               _LinuxPagePoolEntryFree(psPagePoolEntry);
+
+               if (--uNumToScan == 0)
+               {
+                       break;
+               }
+       }
+
+       /*
+         Note:
+         For anything other then x86 this list will be empty but we want to
+         keep differences between compiled code to a minimum and so
+         this isn't wrapped in #if defined(CONFIG_X86)
+       */
+       list_for_each_entry_safe(psPagePoolEntry,
+                                psTempPoolEntry,
+                                &g_sUncachedPagePoolList,
+                                sPagePoolItem)
+       {
+               _RemoveEntryFromPoolUnlocked(psPagePoolEntry);
+
+               /*
+                 We don't want to save the cache type and is we need to unset the
+                 memory type as it would double the page pool structure and the
+                 values are always going to be the same anyway which is why the
+                 page is in the pool (well the page could be UNCACHED or
+                 WRITE_COMBINE but we don't even need the cache type for freeing
+                 back to the OS).
+               */
+               _FreeOSPage(PVRSRV_MEMALLOCFLAG_CPU_UNCACHED,
+                           0,
+                           IMG_TRUE,
+                           IMG_TRUE,
+                           psPagePoolEntry->psPage);
+               _LinuxPagePoolEntryFree(psPagePoolEntry);
+
+               if (--uNumToScan == 0)
+               {
+                       break;
+               }
+       }
+
+       if (list_empty(&g_sPagePoolList) && list_empty(&g_sUncachedPagePoolList))
+       {
+               PVR_ASSERT(g_ui32PagePoolEntryCount == 0);
+       }
+       remain = g_ui32PagePoolEntryCount;
+       _PagePoolUnlock();
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0))
+       return remain;
+#else
+       return psShrinkControl->nr_to_scan - uNumToScan;
+#endif
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0))
+static int
+_ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl)
+{
+       if (psShrinkControl->nr_to_scan != 0)
+       {
+               return _ScanObjectsInPagePool(psShrinker, psShrinkControl);
+       }
+       else
+       {
+               /* No pages are being reclaimed so just return the page count */
+               return _CountObjectsInPagePool(psShrinker, psShrinkControl);
+       }
+}
+
+static struct shrinker g_sShrinker =
+{
+       .shrink = _ShrinkPagePool,
+       .seeks = DEFAULT_SEEKS
+};
+#else
+static struct shrinker g_sShrinker =
+{
+       .count_objects = _CountObjectsInPagePool,
+       .scan_objects = _ScanObjectsInPagePool,
+       .seeks = DEFAULT_SEEKS
+};
+#endif
+#endif /* defined(PHYSMEM_SUPPORTS_SHRINKER) */
+
+static void DisableOOMKiller(void)
+{
+       /* PF_DUMPCORE is treated by the VM as if the OOM killer was disabled.
+        *
+        * As oom_killer_disable() is an inline, non-exported function, we
+        * can't use it from a modular driver. Furthermore, the OOM killer
+        * API doesn't look thread safe, which `current' is.
+        */
+       WARN_ON(current->flags & PF_DUMPCORE);
+       current->flags |= PF_DUMPCORE;
+}
+
+void LinuxInitPagePool(void)
+{
+       IMG_UINT32 ui32Flags = 0;
+
+       _PagePoolLock();
+#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS)
+       ui32Flags |= SLAB_POISON|SLAB_RED_ZONE;
+#endif
+       g_psLinuxPagePoolCache = kmem_cache_create("img-pp", sizeof(LinuxPagePoolEntry), 0, ui32Flags, NULL);
+
+#if defined(PHYSMEM_SUPPORTS_SHRINKER)
+       /* Only create the shrinker if we created the cache OK */
+       if (g_psLinuxPagePoolCache)
+       {
+               register_shrinker(&g_sShrinker);
+       }
+#endif
+       _PagePoolUnlock();
+}
+
+void LinuxDeinitPagePool(void)
+{
+       LinuxPagePoolEntry *psPagePoolEntry, *psTempPPEntry;
+
+       _PagePoolLock();
+       /* Evict all the pages from the pool */
+       list_for_each_entry_safe(psPagePoolEntry,
+                                psTempPPEntry,
+                                &g_sPagePoolList,
+                                sPagePoolItem)
+       {
+               _RemoveEntryFromPoolUnlocked(psPagePoolEntry);
+
+               /*
+                       We don't want to save the cache type and is we need to unset the
+                       memory type as it would double the page pool structure and the
+                       values are always going to be the same anyway which is why the
+                       page is in the pool (well the page could be UNCACHED or
+                       WRITE_COMBINE but we don't even need the cache type for freeing
+                       back to the OS).
+               */
+               _FreeOSPage(PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE,
+                                       0,
+                                       IMG_TRUE,
+                                       IMG_TRUE,
+                                       psPagePoolEntry->psPage);
+               _LinuxPagePoolEntryFree(psPagePoolEntry);
+       }
+       
+       /*
+               Note:
+               For anything other then x86 this will be a no-op but we want to
+               keep differences between compiled code to a minimum and so
+               this isn't wrapped in #if defined(CONFIG_X86)
+       */
+       list_for_each_entry_safe(psPagePoolEntry,
+                                psTempPPEntry,
+                                &g_sUncachedPagePoolList,
+                                sPagePoolItem)
+       {
+               _RemoveEntryFromPoolUnlocked(psPagePoolEntry);
+
+               _FreeOSPage(PVRSRV_MEMALLOCFLAG_CPU_UNCACHED,
+                                       0,
+                                       IMG_TRUE,
+                                       IMG_TRUE,
+                                       psPagePoolEntry->psPage);
+               _LinuxPagePoolEntryFree(psPagePoolEntry);
+       }
+
+       PVR_ASSERT(g_ui32PagePoolEntryCount == 0);
+
+       /* Free the page cache */
+       kmem_cache_destroy(g_psLinuxPagePoolCache);
+
+#if defined(PHYSMEM_SUPPORTS_SHRINKER)
+       unregister_shrinker(&g_sShrinker);
+#endif
+       _PagePoolUnlock();
+}
+
+static void EnableOOMKiller(void)
+{
+       current->flags &= ~PF_DUMPCORE;
+}
+
+static void
+_PoisonPages(struct page *page,
+             IMG_UINT32 uiOrder,
+             const IMG_CHAR *pacPoisonData,
+             IMG_SIZE_T uiPoisonSize)
+{
+    void *kvaddr;
+    IMG_UINT32 uiSrcByteIndex;
+    IMG_UINT32 uiDestByteIndex;
+    IMG_UINT32 uiSubPageIndex;
+    IMG_CHAR *pcDest;
+
+    uiSrcByteIndex = 0;
+    for (uiSubPageIndex = 0; uiSubPageIndex < (1U << uiOrder); uiSubPageIndex++)
+    {
+        kvaddr = kmap(page + uiSubPageIndex);
+
+        pcDest = kvaddr;
+
+        for(uiDestByteIndex=0; uiDestByteIndex<PAGE_SIZE; uiDestByteIndex++)
+        {
+            pcDest[uiDestByteIndex] = pacPoisonData[uiSrcByteIndex];
+            uiSrcByteIndex++;
+            if (uiSrcByteIndex == uiPoisonSize)
+            {
+                uiSrcByteIndex = 0;
+            }
+        }
+        flush_dcache_page(page); 
+        kunmap(page + uiSubPageIndex);
+    }
+}
+
+static const IMG_CHAR _AllocPoison[] = "^PoIsOn";
+static const IMG_UINT32 _AllocPoisonSize = 7;
+static const IMG_CHAR _FreePoison[] = "<DEAD-BEEF>";
+static const IMG_UINT32 _FreePoisonSize = 11;
+
+static PVRSRV_ERROR
+_AllocOSPageArray(PMR_SIZE_T uiSize,
+        IMG_UINT32 uiLog2PageSize,
+        IMG_BOOL bZero,
+        IMG_BOOL bPoisonOnAlloc,
+        IMG_BOOL bPoisonOnFree,
+        IMG_BOOL bOnDemand,
+        IMG_UINT32 ui32CPUCacheFlags,
+               struct _PMR_OSPAGEARRAY_DATA_ **ppsPageArrayDataPtr)
+{
+    PVRSRV_ERROR eError;
+    void *pvData;
+    IMG_UINT32 uiNumPages;
+
+    struct page **ppsPageArray;
+    struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData;
+
+    if (uiSize >= 0x1000000000ULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+                 "physmem_osmem_linux.c: Do you really want 64GB of physical memory in one go?  This is likely a bug"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e_freed_pvdata;
+    }
+
+    PVR_ASSERT(PAGE_SHIFT <= uiLog2PageSize);
+    if ((uiSize & ((1ULL << uiLog2PageSize) - 1)) != 0)
+    {
+       PVR_DPF((PVR_DBG_ERROR,
+                       "Allocation size "PMR_SIZE_FMTSPEC" is not multiple of page size 2^%u !",
+                       uiSize,
+                       uiLog2PageSize));
+
+        eError = PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE;
+        goto e_freed_pvdata;
+    }
+
+    /* Use of cast below is justified by the assertion that follows to
+       prove that no significant bits have been truncated */
+    uiNumPages = (IMG_UINT32)(((uiSize-1)>>uiLog2PageSize) + 1);
+    PVR_ASSERT(((PMR_SIZE_T)uiNumPages << uiLog2PageSize) == uiSize);
+
+    pvData = OSAllocMem(sizeof(struct _PMR_OSPAGEARRAY_DATA_) +
+                        sizeof(struct page *) * uiNumPages);
+    if (pvData == IMG_NULL)
+    {
+        PVR_DPF((PVR_DBG_ERROR,
+                 "physmem_osmem_linux.c: OS refused the memory allocation for the table of pages.  Did you ask for too much?"));
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e_freed_pvdata;
+    }
+    PVR_ASSERT(pvData != IMG_NULL);
+
+    psPageArrayData = pvData;
+    ppsPageArray = pvData + sizeof(struct _PMR_OSPAGEARRAY_DATA_);
+    psPageArrayData->pagearray = ppsPageArray;
+    psPageArrayData->uiLog2PageSize = uiLog2PageSize;
+    psPageArrayData->uiNumPages = uiNumPages;
+    psPageArrayData->bZero = bZero;
+    psPageArrayData->ui32CPUCacheFlags = ui32CPUCacheFlags;
+       psPageArrayData->bPoisonOnAlloc = bPoisonOnAlloc;
+       psPageArrayData->bPoisonOnFree = bPoisonOnFree;
+       psPageArrayData->bHasOSPages = IMG_FALSE;
+       psPageArrayData->bOnDemand = bOnDemand;
+
+    psPageArrayData->bPDumpMalloced = IMG_FALSE;
+
+       psPageArrayData->bUnsetMemoryType = IMG_FALSE;
+
+       *ppsPageArrayDataPtr = psPageArrayData;
+
+       return PVRSRV_OK;
+
+e_freed_pvdata:
+   PVR_ASSERT(eError != PVRSRV_OK);
+   return eError;
+
+}
+
+static inline PVRSRV_ERROR
+_ApplyOSPagesAttribute(struct page **ppsPage, IMG_UINT32 uiNumPages, IMG_BOOL bFlush,
+#if defined (CONFIG_X86)
+                                          struct page **ppsUnsetPages, IMG_UINT32 uiUnsetPagesIndex,
+#endif
+                                          IMG_UINT32 ui32CPUCacheFlags)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       struct page **ppsPagesTemp = ppsPage;
+       IMG_UINT32 uiPageArrayLength = uiNumPages; 
+       
+       if (ppsPagesTemp != IMG_NULL)
+       {
+#if defined (CONFIG_X86)
+               
+               /* In case our allocation is CPU cached 
+                * we have to flush our x86 specific page array */
+               ppsPagesTemp = ppsUnsetPages;
+               uiPageArrayLength = uiUnsetPagesIndex;
+               
+               /* On x86 we have to set page cache attributes for non-cached pages. 
+                * The call is implicitly taking care of all flushing/invalidating
+                * and therefore we can skip the usual cache maintainance after this. */
+               if (PVRSRV_CPU_CACHE_MODE(ui32CPUCacheFlags) == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED ||
+                       PVRSRV_CPU_CACHE_MODE(ui32CPUCacheFlags) == PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE)
+               {
+                       /*  On X86 if we already have a mapping we need to change the mode of
+                               current mapping before we map it ourselves      */
+                       int ret = IMG_FALSE;
+                       IMG_UINT32 uiPageIndex;
+                       PVR_UNREFERENCED_PARAMETER(bFlush);
+       
+                       switch (ui32CPUCacheFlags)
+                       {
+                               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+                                       ret = set_pages_array_uc(ppsUnsetPages, uiUnsetPagesIndex);
+                                       if (ret)
+                                       {
+                                               eError = PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE;
+                                               PVR_DPF((PVR_DBG_ERROR, "Setting Linux page caching mode to UC failed, returned %d", ret));
+                                       }
+                                       break;
+       
+                               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+                                       ret = set_pages_array_wc(ppsUnsetPages, uiUnsetPagesIndex);
+                                       if (ret)
+                                       {
+                                               eError = PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE;
+                                               PVR_DPF((PVR_DBG_ERROR, "Setting Linux page caching mode to WC failed, returned %d", ret));
+                                       }
+                                       break;
+       
+                               case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
+                                       break;
+       
+                               default:
+                                       break;
+                       }
+       
+                       if (ret)
+                       {
+                               for(uiPageIndex = 0; uiPageIndex < uiPageArrayLength; uiPageIndex++)
+                               {
+                                       _FreeOSPage(ui32CPUCacheFlags,
+                                                               0,
+                                                               IMG_FALSE,
+                                                               IMG_FALSE,
+                                                               ppsPagesTemp[uiPageIndex]);
+                               }
+                               goto e_exit;
+                       }
+               }
+               else
+#else
+               PVR_UNREFERENCED_PARAMETER(ui32CPUCacheFlags);
+#endif
+               {
+                       /*  On ARM kernels we can be given pages which still remain in the cache.
+                               In order to make sure that the data we write through our mappings
+                               doesn't get over written by later cache evictions we invalidate the
+                               pages that get given to us.
+               
+                               Note:
+                               This still seems to be true if we request cold pages, it's just less
+                               likely to be in the cache. */
+                       IMG_UINT32 ui32Idx;
+       
+                       if (uiPageArrayLength < PVR_LINUX_ARM_PAGEALLOC_FLUSH_THRESHOLD)
+                       {
+                               for (ui32Idx = 0; ui32Idx < uiPageArrayLength;  ++ui32Idx)
+                               {
+                                       IMG_CPU_PHYADDR sCPUPhysAddrStart, sCPUPhysAddrEnd;
+                                       IMG_PVOID pvPageVAddr;
+       
+                                       pvPageVAddr = kmap(ppsPagesTemp[ui32Idx]);
+                                       sCPUPhysAddrStart.uiAddr = page_to_phys(ppsPagesTemp[ui32Idx]);
+                                       sCPUPhysAddrEnd.uiAddr = sCPUPhysAddrStart.uiAddr + PAGE_SIZE;
+       
+                                       /* If we're zeroing, we need to make sure the cleared memory is pushed out
+                                          of the cache before the cache lines are invalidated */
+                                       if (bFlush)
+                                       {
+                                               OSFlushCPUCacheRangeKM(pvPageVAddr,
+                                                                                          pvPageVAddr + PAGE_SIZE,
+                                                                                          sCPUPhysAddrStart,
+                                                                                          sCPUPhysAddrEnd);
+                                       }
+                                       else
+                                       {
+                                               OSInvalidateCPUCacheRangeKM(pvPageVAddr,
+                                                                                                       pvPageVAddr + PAGE_SIZE,
+                                                                                                       sCPUPhysAddrStart,
+                                                                                                       sCPUPhysAddrEnd);
+                                       }
+       
+                                       kunmap(ppsPagesTemp[ui32Idx]);
+                               }
+                       }
+                       else
+                       {
+                               OSCPUOperation(PVRSRV_CACHE_OP_FLUSH);
+                       }
+               }
+       }
+
+#if defined (CONFIG_X86)
+e_exit:        
+#endif
+       return eError;
+}
+
+static PVRSRV_ERROR
+_AllocOSPage(IMG_UINT32 ui32CPUCacheFlags,
+             unsigned int gfp_flags,
+             IMG_UINT32 uiOrder,
+             struct page **ppsPage,
+             IMG_BOOL *pbPageFromPool)
+{
+       struct page *psPage = IMG_NULL;
+       *pbPageFromPool = IMG_FALSE;
+
+       /* Does the requested page contiguity match the CPU page size? */
+       if (uiOrder == 0)
+       {
+               psPage = _RemoveFirstEntryFromPool(ui32CPUCacheFlags);
+               if (psPage != IMG_NULL)
+               {
+                       *pbPageFromPool = IMG_TRUE;
+                       if (gfp_flags & __GFP_ZERO)
+                       {
+                               /* The kernel will zero the page for us when we allocate it,
+                                  but if it comes from the pool then we must do this 
+                                  ourselves. */
+                               IMG_PVOID pvPageVAddr = kmap(psPage);
+                               memset(pvPageVAddr, 0, PAGE_SIZE);
+                               kunmap(psPage);
+                       }
+               }
+       }
+
+       /*  Did we check the page pool and/or was it a page pool miss,
+               either the pool was empty or it was for a cached page so we
+               must ask the OS  */
+       if (!*pbPageFromPool)
+       {
+               DisableOOMKiller();
+               psPage = alloc_pages(gfp_flags, uiOrder);
+               EnableOOMKiller();
+       }
+
+       if(IMG_NULL == (*ppsPage = psPage))
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY; 
+       }
+       
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+_AllocOSZeroOrderPages(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData,
+                                          IMG_UINT32 ui32CPUCacheFlags,
+                                          unsigned int gfp_flags)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 uiPageIndex;
+       IMG_BOOL bPageFromPool = IMG_FALSE;     
+       struct page **ppsPageArray = psPageArrayData->pagearray;
+#if defined(CONFIG_X86)
+       /* On x86 we batch applying cache attributes by storing references to all
+          pages that are not from the page pool */
+       struct page *apsUnsetPages[PMR_UNSET_PAGES_STACK_ALLOC];
+       struct page **ppsUnsetPages = apsUnsetPages;
+       IMG_UINT32 uiUnsetPagesIndex = 0;
+       
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               ppsUnsetPages = OSAllocMem(sizeof(struct page*) * psPageArrayData->uiNumPages);
+               if (ppsUnsetPages == NULL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed alloc_pages metadata allocation", __FUNCTION__));
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+       }
+#endif
+
+       /* Allocate pages one at a time.  Note that the _device_ memory
+          page size may be different from the _host_ cpu page size - we
+          have a concept of a minimum contiguity requirement, which must
+          be sufficient to meet the requirement of both device and host
+          page size (and possibly other devices or other external
+          constraints).  We are allocating ONE "minimum contiguity unit"
+          (in practice, generally a _device_ page, but not necessarily)
+          at a time, by asking the OS for 2**uiOrder _host_ pages at a
+          time. */
+       for (uiPageIndex = 0;
+                uiPageIndex < psPageArrayData->uiNumPages;
+                uiPageIndex++)
+       {
+               eError = _AllocOSPage(ui32CPUCacheFlags, gfp_flags, 0,
+                                                         &ppsPageArray[uiPageIndex], &bPageFromPool);
+#if defined(CONFIG_X86)
+               if (!bPageFromPool)
+               {
+                       ppsUnsetPages[uiUnsetPagesIndex] = ppsPageArray[uiPageIndex];
+                       uiUnsetPagesIndex += 1;
+               }
+#endif
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "%s: alloc_pages failed to honour request at %d of %d (%s)",
+                                        __FUNCTION__,
+                                        uiPageIndex,
+                                        psPageArrayData->uiNumPages,
+                                        PVRSRVGetErrorStringKM(eError)));
+                       for(--uiPageIndex;uiPageIndex < psPageArrayData->uiNumPages;--uiPageIndex)
+                       {
+                               _FreeOSPage(ui32CPUCacheFlags,
+                                                       0,
+                                                       IMG_TRUE,
+                                                       IMG_TRUE,
+                                                       ppsPageArray[uiPageIndex]);
+                       }
+                       eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES;
+                       goto e_freed_pages;
+               }
+    }
+
+       /* Do the cache management as required */
+       eError = _ApplyOSPagesAttribute (ppsPageArray,
+                                                                        psPageArrayData->uiNumPages,
+                                                                        psPageArrayData->bZero,
+#if defined(CONFIG_X86)
+                                                                        ppsUnsetPages,
+                                                                        uiUnsetPagesIndex,
+#endif
+                                                                        ui32CPUCacheFlags);
+       
+e_freed_pages:
+#if defined(CONFIG_X86)
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               OSFreeMem(ppsUnsetPages);
+       }
+#endif
+       return eError;
+}
+
+#if defined(PHYSMEM_USING_HIGH_ALLOC_ORDER)
+static PVRSRV_ERROR
+_AllocOSHigherOrderPages(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData,
+                                                IMG_UINT32 ui32CPUCacheFlags,
+                                                unsigned int gfp_flags)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 uiOrder;
+       IMG_UINT32 uiPageIndex; 
+       IMG_UINT32 uiMsbNumPages;
+       IMG_BOOL bPageFromPool = IMG_FALSE;
+       IMG_UINT32 uiCutOffOrder = g_uiCutOffOrder;
+       IMG_INT32 aiOrderCount[ALLOC_ORDER_ARRAY_SIZE]; 
+       struct page **ppsPageArray = psPageArrayData->pagearray;
+#if defined(CONFIG_X86)
+       /* On x86 we batch applying cache attributes by storing references
+          to all pages that are not from the page pool */
+       struct page *apsUnsetPages[PMR_UNSET_PAGES_STACK_ALLOC];
+       struct page **ppsUnsetPages = apsUnsetPages;
+       IMG_UINT32 uiUnsetPagesIndex = 0;
+       
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               ppsUnsetPages = OSAllocMem(sizeof(struct page*) * psPageArrayData->uiNumPages);
+               if (ppsUnsetPages == NULL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed alloc_pages metadata allocation", __FUNCTION__));
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+       }
+#endif
+
+       if (uiCutOffOrder)
+       {
+               /* Disable retry/wait at order > 0 */
+               PVR_ASSERT(psPageArrayData->uiNumPages > 1);
+               gfp_flags |= __GFP_NORETRY;
+               gfp_flags &= ~__GFP_WAIT;
+       }
+
+       /* Re-express uiNumPages in multi-order up to cut-off order */
+       for (uiOrder = 0; uiOrder <= uiCutOffOrder; ++uiOrder)
+       {
+               aiOrderCount[uiOrder] = psPageArrayData->uiNumPages & (1<<uiOrder) ? 1 : 0;
+       }
+
+       /* Accumulate top order bits into cut-off order bin */
+       uiMsbNumPages =  psPageArrayData->uiNumPages >> (g_uiCutOffOrder+1);
+       aiOrderCount[uiCutOffOrder] += uiMsbNumPages ? uiMsbNumPages << 1 : 0;
+
+       /* Allocate variable higher-order pages as per order-array specification.
+          There's currently no support for compound pages, the "minimum contiguity unit" 
+          that is supported is equal to the _host_ cpu page size (i.e. PAGE_SHIFT) */
+       for (uiOrder=uiCutOffOrder, uiPageIndex=0; uiPageIndex < psPageArrayData->uiNumPages; )
+       {
+               /* Has this order bucket been exhausted */
+               for  ( ; ! aiOrderCount[uiOrder]; --uiOrder)
+                       ;
+
+               /* Alloc uiOrder pages at uiPageIndex */
+               eError = _AllocOSPage(ui32CPUCacheFlags, gfp_flags, uiOrder,
+                                                         &ppsPageArray[uiPageIndex], &bPageFromPool);
+               if (eError == PVRSRV_OK)
+               {
+                       IMG_UINT32 uiIdx;
+
+                       if (uiOrder) 
+                       {
+                               split_page(ppsPageArray[uiPageIndex], uiOrder); 
+                       }
+
+                       for (uiIdx=0; uiIdx < (1 << uiOrder); ++uiIdx)
+                       {
+                               /* For higher order allocations, we need to return not just the 1st
+                                  pointer but all pages in the order */
+                               ppsPageArray[uiPageIndex+uiIdx] = &ppsPageArray[uiPageIndex][uiIdx];
+#if defined(CONFIG_X86)
+                               if (!bPageFromPool)
+                               {
+                                       ppsUnsetPages[uiUnsetPagesIndex+uiIdx] = ppsPageArray[uiPageIndex+uiIdx];
+                               }
+                       }
+
+                       if (!bPageFromPool)
+                       {
+                               uiUnsetPagesIndex += (1 << uiOrder);
+                       }
+#else
+                       }
+#endif
+                       /* Less one order allocation */
+                       uiPageIndex += (1 << uiOrder);
+                       aiOrderCount[uiOrder] -= 1;
+               }
+               else
+               {
+                       if (uiOrder)
+                       {
+                               /*
+                                 The strategy employed to cope with memory fragmentation is two fold:
+                                  - By speculating that it is _better_ to move any remaining failed order
+                                    allocations to a much lower order (i.e. failed-order/2) _most_ likely
+                                    to succeed (quick-failure-recovery).
+
+                                  - By ensuring that other allocations benefit from this knowledge (failure-rate)
+                                    by adjusting the global cut-off order variable used for such future 
+                                    allocations (throttling up/down).
+                                */
+                               IMG_INT32 uiFailedOrder = uiOrder;
+                               IMG_INT32 uiLowOrder = uiFailedOrder >> 1;
+                               g_uiCutOffOrder = uiFailedOrder - 1;
+
+                               if (! uiLowOrder)
+                               {
+                                       /* Enable retry/wait at order-0 */
+                                       gfp_flags &= ~__GFP_NORETRY;
+                                       gfp_flags |= __GFP_WAIT;
+                               }
+
+                               /* Accumulate remaining failed order into lower order */
+                               for  ( ; aiOrderCount[uiFailedOrder]; --aiOrderCount[uiFailedOrder])
+                               {
+                                       aiOrderCount[uiLowOrder] += 1 << (uiFailedOrder - uiLowOrder);
+                               }
+                       }
+                       else
+                       {
+                               /* At order zero, there's nothing else left to do, so we must
+                                       unwind the series of order allocations hitherto */
+                               PVR_DPF((PVR_DBG_ERROR,
+                                        "physmem_osmem_linux.c: alloc_pages failed to honour request at %d (order: %d) of %d (%s)",
+                                        uiPageIndex, uiOrder,
+                                        psPageArrayData->uiNumPages,
+                                        PVRSRVGetErrorStringKM(eError)));
+                               
+                               for(--uiPageIndex;uiPageIndex < psPageArrayData->uiNumPages;--uiPageIndex)
+                               {
+                                       _FreeOSPage(ui32CPUCacheFlags,
+                                                               0,
+                                                               IMG_TRUE,
+                                                               IMG_TRUE,
+                                                               ppsPageArray[uiPageIndex]);
+                               }
+                               
+                               eError = PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES;
+                               goto e_freed_pages;
+                       }
+               }
+       }
+
+       /* Do the cache management as required */
+       eError = _ApplyOSPagesAttribute (ppsPageArray,
+                                                                        psPageArrayData->uiNumPages,
+                                                                        psPageArrayData->bZero,
+#if defined(CONFIG_X86)
+                                                                        ppsUnsetPages,
+                                                                        uiUnsetPagesIndex,
+#endif
+                                                                        ui32CPUCacheFlags);
+
+e_freed_pages:
+#if defined(CONFIG_X86)
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               OSFreeMem(ppsUnsetPages);
+       }
+#endif
+       return eError;
+}
+#endif
+
+static PVRSRV_ERROR
+_AllocOSPages(struct _PMR_OSPAGEARRAY_DATA_ **ppsPageArrayDataPtr)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 uiOrder;
+       IMG_UINT32 uiPageIndex;
+       IMG_UINT32 ui32CPUCacheFlags;
+#if defined(PHYSMEM_USING_HIGH_ALLOC_ORDER)
+       IMG_UINT32 uiUseHighOrderFlag;
+#endif
+       struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData = *ppsPageArrayDataPtr;
+       struct page **ppsPageArray = psPageArrayData->pagearray;
+       unsigned int gfp_flags;
+
+       PVR_ASSERT(!psPageArrayData->bHasOSPages);
+
+       /* For now we don't support compound pages */
+       uiOrder = psPageArrayData->uiLog2PageSize - PAGE_SHIFT;
+       ui32CPUCacheFlags = psPageArrayData->ui32CPUCacheFlags;
+       PVR_ASSERT(uiOrder == 0);
+
+       gfp_flags = GFP_USER | __GFP_NOWARN | __GFP_NOMEMALLOC;
+
+#if !defined(CONFIG_X86_64)
+       gfp_flags |= __GFP_HIGHMEM;
+#endif
+
+       if (psPageArrayData->bZero)
+       {
+               gfp_flags |= __GFP_ZERO;
+       }
+
+       /*
+               Unset memory type is set to true as although in the "normal" case
+               (where we free the page back to the pool) we don't want to unset
+               it, we _must_ unset it in the case where the page pool was full
+               and thus we have to give the page back to the OS.
+       */
+       if (ui32CPUCacheFlags == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED
+           ||ui32CPUCacheFlags == PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE)
+       {
+               psPageArrayData->bUnsetMemoryType = IMG_TRUE;
+       }
+       else
+       {
+               psPageArrayData->bUnsetMemoryType = IMG_FALSE;
+       }
+
+#if defined(PHYSMEM_USING_HIGH_ALLOC_ORDER)
+       /* Multi-order allocations should be considered when size request >= threshold */
+       uiUseHighOrderFlag = psPageArrayData->uiNumPages >= PVR_LINUX_PHYSMEM_MIN_NUM_PAGES;
+       if (uiUseHighOrderFlag && g_uiCutOffOrder)
+       {
+               /* We neeed to throttle up slowly towards the maximum allowed order */
+               eError = _AllocOSHigherOrderPages(psPageArrayData, ui32CPUCacheFlags, gfp_flags);
+               g_uiCutOffOrder += (g_uiCutOffOrder < PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER) ? 1:0;
+       }
+       else 
+       {
+               /* When to re-enable high-order is a trade-off (accuracy vs. simplicity) */
+               eError = _AllocOSZeroOrderPages(psPageArrayData, ui32CPUCacheFlags, gfp_flags);
+               g_uiCutOffOrder += uiUseHighOrderFlag;
+       }
+#else
+       eError = _AllocOSZeroOrderPages(psPageArrayData, ui32CPUCacheFlags, gfp_flags);
+#endif
+
+       if (eError == PVRSRV_OK)
+       {
+               for (uiPageIndex = 0; uiPageIndex < psPageArrayData->uiNumPages; uiPageIndex++)
+               {
+                       /* Can't ask us to zero it and poison it */
+                       PVR_ASSERT(!psPageArrayData->bZero || !psPageArrayData->bPoisonOnAlloc);
+
+                       if (psPageArrayData->bPoisonOnAlloc)
+                       {
+                               _PoisonPages(ppsPageArray[uiPageIndex],
+                                                        uiOrder,
+                                                        _AllocPoison,
+                                                        _AllocPoisonSize);
+                       }
+                       
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+                       /* Allocation is done a page at a time */
+                       PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, PAGE_SIZE);
+#else
+                       {
+                               IMG_CPU_PHYADDR sCPUPhysAddr;
+       
+                               sCPUPhysAddr.uiAddr = page_to_phys(ppsPageArray[uiPageIndex]);
+                               PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES,
+                                                                                        IMG_NULL,
+                                                                                        sCPUPhysAddr,
+                                                                                        PAGE_SIZE,
+                                                                                        IMG_NULL);
+                       }
+#endif
+#endif
+               }
+
+               
+               /* OS Pages have been allocated */
+               psPageArrayData->bHasOSPages = IMG_TRUE;
+
+               PVR_DPF((PVR_DBG_MESSAGE, "physmem_osmem_linux.c: allocated OS memory for PMR @0x%p", psPageArrayData));
+       }
+       return eError;
+}
+
+
+/*
+       Note:
+       We must _only_ check bUnsetMemoryType in the case where we need to free
+       the page back to the OS since we may have to revert the cache properties
+       of the page to the default as given by the OS when it was allocated.
+*/
+static void
+_FreeOSPage(IMG_UINT32 ui32CPUCacheFlags,
+            IMG_UINT32 uiOrder,
+            IMG_BOOL bUnsetMemoryType,
+            IMG_BOOL bFreeToOS,
+            struct page *psPage)
+{
+       IMG_BOOL bAddedToPool = IMG_FALSE;
+#if defined (CONFIG_X86)
+       IMG_PVOID pvPageVAddr;
+#else
+       PVR_UNREFERENCED_PARAMETER(bUnsetMemoryType);
+#endif
+
+       /* Only zero order pages can be managed in the pool */
+       if ((uiOrder == 0) && (!bFreeToOS))
+       {
+               _PagePoolLock();
+               bAddedToPool = g_ui32PagePoolEntryCount < g_ui32PagePoolMaxEntries;
+               _PagePoolUnlock();
+
+               if (bAddedToPool)
+               {
+                       if (!_AddEntryToPool(psPage, ui32CPUCacheFlags))
+                       {
+                               bAddedToPool = IMG_FALSE;
+                       }
+               }
+       }
+
+       if (!bAddedToPool)
+       {
+#if defined(CONFIG_X86)
+               pvPageVAddr = page_address(psPage);
+               if (pvPageVAddr && bUnsetMemoryType == IMG_TRUE)
+               {
+                       int ret;
+
+                       ret = set_memory_wb((unsigned long)pvPageVAddr, 1);
+                       if (ret)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attribute", __FUNCTION__));
+                       }
+               }
+#endif
+               __free_pages(psPage, uiOrder);
+       }
+}
+
+static PVRSRV_ERROR
+_FreeOSPagesArray(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData)
+{
+       PVR_DPF((PVR_DBG_MESSAGE, "physmem_osmem_linux.c: freed OS memory for PMR @0x%p", psPageArrayData));
+
+       OSFreeMem(psPageArrayData);
+
+       return PVRSRV_OK;
+}
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+/* _FreeOSPages_MemStats: Depends on the bridge lock already being held */
+static void
+_FreeOSPages_MemStats(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData)
+{
+       struct page **ppsPageArray;
+       #if defined(PVRSRV_ENABLE_MEMORY_STATS)
+       IMG_UINT32 ui32PageIndex;
+       #endif
+
+       PVR_ASSERT(psPageArrayData->bHasOSPages);
+
+       ppsPageArray = psPageArrayData->pagearray;
+
+       #if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+               PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, psPageArrayData->uiNumPages * PAGE_SIZE);
+       #else
+               for(ui32PageIndex = 0; ui32PageIndex < psPageArrayData->uiNumPages; ui32PageIndex++)
+               {
+                       IMG_CPU_PHYADDR sCPUPhysAddr;
+
+                       sCPUPhysAddr.uiAddr = page_to_phys(ppsPageArray[ui32PageIndex]);
+                       PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES, sCPUPhysAddr.uiAddr);
+               }
+       #endif
+       #endif
+}
+#endif /* PVRSRV_ENABLE_PROCESS_STATS */
+
+static PVRSRV_ERROR
+_FreeOSPages_FreePages(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 uiOrder;
+       IMG_UINT32 uiPageIndex;
+       struct page **ppsPageArray;
+       IMG_BOOL bAddedToPool = IMG_FALSE;
+
+#if defined (CONFIG_X86)
+       struct page *apsUnsetPages[PMR_UNSET_PAGES_STACK_ALLOC];
+       struct page **ppsUnsetPages = apsUnsetPages;
+       IMG_UINT32 uiUnsetPagesIndex = 0;
+
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               /* OSAllocMemstatMem required because this code may be run without the bridge lock held */
+               ppsUnsetPages = OSAllocMemstatMem(sizeof(struct page*) * psPageArrayData->uiNumPages);
+               if (ppsUnsetPages == NULL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed free_pages metadata allocation", __FUNCTION__));
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto e_exit;
+               }
+       }
+#endif
+
+       PVR_ASSERT(psPageArrayData->bHasOSPages);
+
+       ppsPageArray = psPageArrayData->pagearray;
+
+        /* For now we don't support compound pages */
+       uiOrder = psPageArrayData->uiLog2PageSize - PAGE_SHIFT;
+       PVR_ASSERT(uiOrder == 0);
+
+       for (uiPageIndex = 0;
+            uiPageIndex < psPageArrayData->uiNumPages;
+            uiPageIndex++)
+       {
+               if (psPageArrayData->bPoisonOnFree)
+               {
+                       _PoisonPages(ppsPageArray[uiPageIndex],
+                                    uiOrder,
+                                    _FreePoison,
+                                    _FreePoisonSize);
+               }
+
+               /* Only zero order pages can be managed in the pool */
+               if (uiOrder == 0)
+               {
+                       _PagePoolLock();
+                       bAddedToPool = g_ui32PagePoolEntryCount < g_ui32PagePoolMaxEntries;
+                       _PagePoolUnlock();
+
+                       if (bAddedToPool)
+                       {
+                               if (!_AddEntryToPool(ppsPageArray[uiPageIndex], psPageArrayData->ui32CPUCacheFlags))
+                               {
+                                       bAddedToPool = IMG_FALSE;
+                               }
+                       }
+               }
+
+               if (!bAddedToPool)
+               {
+#if defined(CONFIG_X86)
+                       if (psPageArrayData->bUnsetMemoryType == IMG_TRUE)
+                       {
+                               /* Keeping track of the pages for which the caching needs to change */
+                               ppsUnsetPages[uiUnsetPagesIndex] = ppsPageArray[uiPageIndex];
+                               uiUnsetPagesIndex++;
+                       }
+                       else
+#endif
+                       {
+                               _FreeOSPage(0,
+                                           uiOrder,
+                                           IMG_FALSE,
+                                           IMG_TRUE,
+                                           ppsPageArray[uiPageIndex]);
+                       }
+               }
+       }
+
+#if defined(CONFIG_X86)
+       if (uiUnsetPagesIndex != 0)
+       {
+               int ret;
+               ret = set_pages_array_wb(ppsUnsetPages, uiUnsetPagesIndex);
+
+               if (ret)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: Failed to reset page attributes", __FUNCTION__));
+               }
+
+               for (uiPageIndex = 0;
+                    uiPageIndex < uiUnsetPagesIndex;
+                    uiPageIndex++)
+               {
+                       _FreeOSPage(0,
+                                   uiOrder,
+                                   IMG_FALSE,
+                                   IMG_TRUE,
+                                   ppsUnsetPages[uiPageIndex]);
+               }
+       }
+
+       if (psPageArrayData->uiNumPages > PMR_UNSET_PAGES_STACK_ALLOC)
+       {
+               OSFreeMemstatMem(ppsUnsetPages);
+       }
+#endif
+
+       eError = PVRSRV_OK;
+
+       psPageArrayData->bHasOSPages = IMG_FALSE;
+
+#if defined(CONFIG_X86)
+e_exit:
+#endif
+       return eError;
+}
+
+static PVRSRV_ERROR
+_CleanupThread_FreePagesAndPageArrayData(void *pvData)
+{
+       struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData = pvData;
+       PVRSRV_ERROR eError;
+
+       atomic_sub((int) psPageArrayData->uiNumPages, &g_uiNumDeferredFreePages);
+
+       eError = _FreeOSPages_FreePages(psPageArrayData);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_FreeOSPages_FreePages failed"));
+               goto err_out;
+       }
+
+       eError = _FreeOSPagesArray(psPageArrayData);
+
+err_out:
+       return eError;
+}
+
+/* clone a PMR_OSPAGEARRAY_DATA structure, including making a copy of
+ * the the list of physical pages it owns.
+ * returns a pointer to the newly allocated PMR_OSPAGEARRAY_DATA structure.
+ */
+static struct _PMR_OSPAGEARRAY_DATA_ *_CloneOSPageArrayData(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayDataIn)
+{
+       struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayDataOut;
+       size_t uiStructureSize;
+
+       uiStructureSize = sizeof(struct _PMR_OSPAGEARRAY_DATA_) +
+                               sizeof(struct page *) * psPageArrayDataIn->uiNumPages;
+
+       psPageArrayDataOut = OSAllocMemstatMem(uiStructureSize);
+
+       if(psPageArrayDataOut == NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_CloneOSPageArrayData: Failed to clone PMR_OSPAGEARRAY_DATA"));
+               return NULL;
+       }
+
+       memcpy(psPageArrayDataOut, psPageArrayDataIn, uiStructureSize);
+
+       psPageArrayDataOut->pagearray = (void *) ((char *) psPageArrayDataOut) +
+       sizeof(struct _PMR_OSPAGEARRAY_DATA_);
+
+       return psPageArrayDataOut;
+}
+
+static PVRSRV_ERROR
+_FreeOSPages(struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayData, IMG_BOOL bFreePageArray)
+{
+       PVRSRV_ERROR eError;
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+       _FreeOSPages_MemStats(psPageArrayData);
+#endif
+
+       if((atomic_read(&g_uiNumDeferredFreePages) + psPageArrayData->uiNumPages) <= MAX_OUTSTANDING_DEFERRED_FREE_PAGES)
+       {
+               struct _PMR_OSPAGEARRAY_DATA_ *psPageArrayToFree;
+
+               if(bFreePageArray)
+               {
+                       /* the PMR_OSPAGEARRAY_DATA structure is also being
+                        * freed, so the whole structure as-is can be pushed to
+                        * the cleanup thread, which can free the PMR_OSPAGEARRAY_DATA
+                        * structure as well as the phys pages
+                        */
+                       psPageArrayToFree = psPageArrayData;
+               }
+               else
+               {
+                       /* the caller does not want the PMR_OSPAGEARRAY_DATA
+                        * structure to be freed, only the phys pages.
+                        * to acommodate this, the PMR_OSPAGEARRAY_DATA structure
+                        * is cloned and ownership of the pages is moved to the
+                        * clone, then the clone is pushed onto the cleanup thread
+                        * work list. Now psPageArrayData owns no pages, as the caller
+                        * expects.
+                        */
+
+                        struct _PMR_OSPAGEARRAY_DATA_ *psClone;
+
+                        psClone = _CloneOSPageArrayData(psPageArrayData);
+
+                        if(psClone == NULL)
+                        {
+                               /* cloning failed so go ahead and free the
+                                * pages immediately
+                                */
+                                goto nodefer;
+                        }
+
+                        /* the clone takes ownership of the pages, so mark the
+                         * original structure as not having any pages
+                         */
+                         psPageArrayData->bHasOSPages = IMG_FALSE;
+
+                         psPageArrayToFree = psClone;
+               }
+
+               atomic_add((int) psPageArrayData->uiNumPages, &g_uiNumDeferredFreePages);
+               psPageArrayToFree->sCleanupThreadFn.pfnFree = _CleanupThread_FreePagesAndPageArrayData;
+               psPageArrayToFree->sCleanupThreadFn.pvData = psPageArrayToFree;
+               psPageArrayToFree->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
+               PVRSRVCleanupThreadAddWork(&psPageArrayToFree->sCleanupThreadFn);
+
+               return PVRSRV_OK;
+       }
+nodefer:
+       /* we are not deferring, so free the pages immediately */
+
+       eError = _FreeOSPages_FreePages(psPageArrayData);
+
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_FreeOSPages_FreePages failed"));
+               goto err_out;
+       }
+
+       if(bFreePageArray)
+       {
+               eError = _FreeOSPagesArray(psPageArrayData);
+       }
+
+err_out:
+    return eError;
+}
+
+/*
+ *
+ * Implementation of callback functions
+ *
+ */
+
+/* destructor func is called after last reference disappears, but
+   before PMR itself is freed. */
+static PVRSRV_ERROR
+PMRFinalizeOSMem(PMR_IMPL_PRIVDATA pvPriv
+                 //struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData
+                 )
+{
+    PVRSRV_ERROR eError;
+    struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData;
+
+    psOSPageArrayData = pvPriv;
+
+    /* Conditionally do the PDump free, because if CreatePMR failed we
+       won't have done the PDump MALLOC.  */
+    if (psOSPageArrayData->bPDumpMalloced)
+    {
+        PDumpPMRFree(psOSPageArrayData->hPDumpAllocInfo);
+    }
+
+       /*  We can't free pages until now. */
+       if (psOSPageArrayData->bHasOSPages)
+       {
+               eError = _FreeOSPages(psOSPageArrayData, IMG_TRUE);
+               PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */
+       }
+       else
+       {
+           eError = _FreeOSPagesArray(psOSPageArrayData);
+           PVR_ASSERT (eError == PVRSRV_OK); /* can we do better? */
+       }
+
+    return PVRSRV_OK;
+}
+
+/* callback function for locking the system physical page addresses.
+   This function must be called before the lookup address func. */
+static PVRSRV_ERROR
+PMRLockSysPhysAddressesOSMem(PMR_IMPL_PRIVDATA pvPriv,
+                             // struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData,
+                             IMG_UINT32 uiLog2DevPageSize)
+{
+    PVRSRV_ERROR eError;
+    struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData;
+
+    psOSPageArrayData = pvPriv;
+
+    if (psOSPageArrayData->bOnDemand)
+    {
+               /* Allocate Memory for deferred allocation */
+       eError = _AllocOSPages(&psOSPageArrayData);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+    }
+
+    /* Physical page addresses are already locked down in this
+       implementation, so there is no need to acquire physical
+       addresses.  We do need to verify that the physical contiguity
+       requested by the caller (i.e. page size of the device they
+       intend to map this memory into) is compatible with (i.e. not of
+       coarser granularity than) our already known physicial
+       contiguity of the pages */
+    if (uiLog2DevPageSize > psOSPageArrayData->uiLog2PageSize)
+    {
+        /* or NOT_MAPPABLE_TO_THIS_PAGE_SIZE ? */
+        eError = PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
+        return eError;
+    }
+
+    eError = PVRSRV_OK;
+    return eError;
+
+}
+
+static PVRSRV_ERROR
+PMRUnlockSysPhysAddressesOSMem(PMR_IMPL_PRIVDATA pvPriv
+                               //struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData
+                               )
+{
+    /* Just drops the refcount. */
+
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData;
+
+    psOSPageArrayData = pvPriv;
+    if (psOSPageArrayData->bOnDemand)
+    {
+               /* Free Memory for deferred allocation */
+       eError = _FreeOSPages(psOSPageArrayData, IMG_FALSE);
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+    }
+
+    PVR_ASSERT (eError == PVRSRV_OK);
+    return eError;
+}
+
+/* N.B.  It is assumed that PMRLockSysPhysAddressesOSMem() is called _before_ this function! */
+static PVRSRV_ERROR
+PMRSysPhysAddrOSMem(PMR_IMPL_PRIVDATA pvPriv,
+                    IMG_UINT32 ui32NumOfPages,
+                    IMG_DEVMEM_OFFSET_T *puiOffset,
+                                       IMG_BOOL *pbValid,
+                    IMG_DEV_PHYADDR *psDevPAddr)
+{
+    const struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData = pvPriv;
+    struct page **ppsPageArray = psOSPageArrayData->pagearray;
+       IMG_UINT32 uiPageSize = 1U << psOSPageArrayData->uiLog2PageSize;
+       IMG_UINT32 uiInPageOffset;
+    IMG_UINT32 uiPageIndex;
+    IMG_UINT32 idx;
+
+    for (idx=0; idx < ui32NumOfPages; idx++)
+    {
+               if (pbValid[idx])
+               {       
+                       uiPageIndex = puiOffset[idx] >> psOSPageArrayData->uiLog2PageSize;
+               uiInPageOffset = puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)uiPageIndex << psOSPageArrayData->uiLog2PageSize);
+
+                       PVR_ASSERT(uiPageIndex < psOSPageArrayData->uiNumPages);
+                       PVR_ASSERT(uiInPageOffset < uiPageSize);
+
+                       psDevPAddr[idx].uiAddr = page_to_phys(ppsPageArray[uiPageIndex]) + uiInPageOffset;
+               }
+    }
+
+    return PVRSRV_OK;
+}
+
+typedef struct _PMR_OSPAGEARRAY_KERNMAP_DATA_ {
+       void *pvBase;
+       IMG_UINT32 ui32PageCount;
+} PMR_OSPAGEARRAY_KERNMAP_DATA;
+
+static PVRSRV_ERROR
+PMRAcquireKernelMappingDataOSMem(PMR_IMPL_PRIVDATA pvPriv,
+                                 IMG_SIZE_T uiOffset,
+                                 IMG_SIZE_T uiSize,
+                                 void **ppvKernelAddressOut,
+                                 IMG_HANDLE *phHandleOut,
+                                 PMR_FLAGS_T ulFlags)
+{
+    PVRSRV_ERROR eError;
+    struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData;
+    void *pvAddress;
+    pgprot_t prot = PAGE_KERNEL;
+    IMG_UINT32 ui32CPUCacheFlags;
+    IMG_UINT32 ui32PageOffset;
+    IMG_SIZE_T uiMapOffset;
+    IMG_UINT32 ui32PageCount;
+    PMR_OSPAGEARRAY_KERNMAP_DATA *psData;
+
+    psOSPageArrayData = pvPriv;
+       ui32CPUCacheFlags = DevmemCPUCacheMode(ulFlags);
+
+       /*
+               Zero offset and size as a special meaning which means map in the
+               whole of the PMR, this is due to fact that the places that call
+               this callback might not have access to be able to determine the
+               physical size
+       */
+       if ((uiOffset == 0) && (uiSize == 0))
+       {
+               ui32PageOffset = 0;
+               uiMapOffset = 0;
+               ui32PageCount = psOSPageArrayData->uiNumPages;
+       }
+       else
+       {
+               IMG_SIZE_T uiEndoffset;
+
+               ui32PageOffset = uiOffset >> psOSPageArrayData->uiLog2PageSize;
+               uiMapOffset = uiOffset - (ui32PageOffset << psOSPageArrayData->uiLog2PageSize);
+               uiEndoffset = uiOffset + uiSize - 1;
+               // Add one as we want the count, not the offset
+               ui32PageCount = (uiEndoffset >> psOSPageArrayData->uiLog2PageSize) + 1;
+               ui32PageCount -= ui32PageOffset;
+       }
+
+    if (psOSPageArrayData->uiLog2PageSize != PAGE_SHIFT)
+    {
+        /* we only know how to use vmap on allocations comprising
+           individual pages.  Higher-order "pages" are not supported
+           with this. */
+        eError = PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
+        goto e0;
+    }
+
+#if defined(CONFIG_ARM64)
+    //zxl:ARM64 use noncached,which is setted MT_DEVICE,And Device type may unsupport some operations.
+    //    Force to use pgprot_writecombine now.
+    if(ui32CPUCacheFlags == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED)
+    {
+        ui32CPUCacheFlags = PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE;
+    }
+#endif
+
+       switch (ui32CPUCacheFlags)
+       {
+               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+                               prot = pgprot_noncached(prot);
+                               break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+                               prot = pgprot_writecombine(prot);
+                               break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
+                               break;
+
+               default:
+                               eError = PVRSRV_ERROR_INVALID_PARAMS;
+                               goto e0;
+       }
+       
+       psData = OSAllocMem(sizeof(PMR_OSPAGEARRAY_KERNMAP_DATA));
+       if (psData == NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+       
+#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS)
+       pvAddress = vmap(&psOSPageArrayData->pagearray[ui32PageOffset],
+                        ui32PageCount,
+                        VM_READ | VM_WRITE,
+                        prot);
+#else
+       pvAddress = vm_map_ram(&psOSPageArrayData->pagearray[ui32PageOffset],
+                                                  ui32PageCount,
+                                                  -1,
+                                                  prot);
+#endif
+       if (pvAddress == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e1;
+       }
+
+    *ppvKernelAddressOut = pvAddress + uiMapOffset;
+    psData->pvBase = pvAddress;
+    psData->ui32PageCount = ui32PageCount;
+    *phHandleOut = psData;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+ e1:
+    OSFreeMem(psData);
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+static void PMRReleaseKernelMappingDataOSMem(PMR_IMPL_PRIVDATA pvPriv,
+                                                 IMG_HANDLE hHandle)
+{
+    struct _PMR_OSPAGEARRAY_DATA_ *psOSPageArrayData;
+    PMR_OSPAGEARRAY_KERNMAP_DATA *psData;
+
+    psOSPageArrayData = pvPriv;
+    psData = hHandle;
+#if !defined(CONFIG_64BIT) || defined(PVRSRV_FORCE_SLOWER_VMAP_ON_64BIT_BUILDS)
+    vunmap(psData->pvBase);
+#else
+    vm_unmap_ram(psData->pvBase, psData->ui32PageCount);
+#endif
+    OSFreeMem(psData);
+}
+
+static PMR_IMPL_FUNCTAB _sPMROSPFuncTab = {
+    .pfnLockPhysAddresses = &PMRLockSysPhysAddressesOSMem,
+    .pfnUnlockPhysAddresses = &PMRUnlockSysPhysAddressesOSMem,
+    .pfnDevPhysAddr = &PMRSysPhysAddrOSMem,
+    .pfnAcquireKernelMappingData = &PMRAcquireKernelMappingDataOSMem,
+    .pfnReleaseKernelMappingData = &PMRReleaseKernelMappingDataOSMem,
+    .pfnReadBytes = IMG_NULL,
+    .pfnWriteBytes = IMG_NULL,
+    .pfnFinalize = &PMRFinalizeOSMem
+};
+
+static PVRSRV_ERROR
+_NewOSAllocPagesPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                    IMG_DEVMEM_SIZE_T uiSize,
+                                       IMG_DEVMEM_SIZE_T uiChunkSize,
+                                       IMG_UINT32 ui32NumPhysChunks,
+                                       IMG_UINT32 ui32NumVirtChunks,
+                                       IMG_BOOL *pabMappingTable,
+                    IMG_UINT32 uiLog2PageSize,
+                    PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                    PMR **ppsPMRPtr)
+{
+    PVRSRV_ERROR eError;
+    PVRSRV_ERROR eError2;
+    PMR *psPMR;
+    struct _PMR_OSPAGEARRAY_DATA_ *psPrivData;
+    IMG_HANDLE hPDumpAllocInfo = IMG_NULL;
+    PMR_FLAGS_T uiPMRFlags;
+    IMG_BOOL bZero;
+    IMG_BOOL bPoisonOnAlloc;
+    IMG_BOOL bPoisonOnFree;
+    IMG_BOOL bOnDemand = ((uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) > 0);
+       IMG_BOOL bCpuLocal = ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_LOCAL) > 0);
+       IMG_UINT32 ui32CPUCacheFlags = (IMG_UINT32) DevmemCPUCacheMode(uiFlags);
+
+
+    if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+    {
+        bZero = IMG_TRUE;
+    }
+    else
+    {
+        bZero = IMG_FALSE;
+    }
+
+    if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)
+    {
+        bPoisonOnAlloc = IMG_TRUE;
+    }
+    else
+    {
+        bPoisonOnAlloc = IMG_FALSE;
+    }
+
+    if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE)
+    {
+        bPoisonOnFree = IMG_TRUE;
+    }
+    else
+    {
+        bPoisonOnFree = IMG_FALSE;
+    }
+
+    if ((uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
+        (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+    {
+        /* Zero on Alloc and Poison on Alloc are mutually exclusive */
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto errorOnParam;
+    }
+
+       /* Silently round up alignment/pagesize if request was less that
+          PAGE_SHIFT, because it would never be harmful for memory to be
+          _more_ contiguous that was desired */
+       uiLog2PageSize = PAGE_SHIFT > uiLog2PageSize
+               ? PAGE_SHIFT
+               : uiLog2PageSize;
+
+       /* Create Array structure that hold the physical pages */
+       eError = _AllocOSPageArray(uiChunkSize * ui32NumPhysChunks,
+                                                  uiLog2PageSize,
+                                                  bZero,
+                                                  bPoisonOnAlloc,
+                                                  bPoisonOnFree,
+                                                  bOnDemand,
+                                                  ui32CPUCacheFlags,
+                                                  &psPrivData);
+       if (eError != PVRSRV_OK)
+       {
+               goto errorOnAllocPageArray;
+       }
+
+       if (!bOnDemand)
+       {
+               /* Allocate the physical pages */
+               eError = _AllocOSPages(&psPrivData);
+               if (eError != PVRSRV_OK)
+               {
+                       goto errorOnAllocPages;
+               }
+       }
+
+    /* In this instance, we simply pass flags straight through.
+
+       Generically, uiFlags can include things that control the PMR
+       factory, but we don't need any such thing (at the time of
+       writing!), and our caller specifies all PMR flags so we don't
+       need to meddle with what was given to us.
+    */
+    uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
+    /* check no significant bits were lost in cast due to different
+       bit widths for flags */
+    PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
+
+    if (bOnDemand)
+    {
+       PDUMPCOMMENT("Deferred Allocation PMR (UMA)");
+    }
+    if (bCpuLocal)
+    {
+       PDUMPCOMMENT("CPU_LOCAL allocation requested");
+    }
+    eError = PMRCreatePMR(psDevNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL],
+                          uiSize,
+                          uiChunkSize,
+                          ui32NumPhysChunks,
+                          ui32NumVirtChunks,
+                          pabMappingTable,
+                          uiLog2PageSize,
+                          uiPMRFlags,
+                          "PMROSAP",
+                          &_sPMROSPFuncTab,
+                          psPrivData,
+                          &psPMR,
+                          &hPDumpAllocInfo,
+                                         IMG_FALSE);
+    if (eError != PVRSRV_OK)
+    {
+        goto errorOnCreate;
+    }
+
+       psPrivData->hPDumpAllocInfo = hPDumpAllocInfo;
+       psPrivData->bPDumpMalloced = IMG_TRUE;
+
+    *ppsPMRPtr = psPMR;
+    return PVRSRV_OK;
+
+errorOnCreate:
+       if (!bOnDemand)
+       {
+               eError2 = _FreeOSPages(psPrivData, IMG_FALSE);
+               PVR_ASSERT(eError2 == PVRSRV_OK);
+       }
+
+errorOnAllocPages:
+       eError2 = _FreeOSPagesArray(psPrivData);
+       PVR_ASSERT(eError2 == PVRSRV_OK);
+
+errorOnAllocPageArray:
+errorOnParam:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+PVRSRV_ERROR
+PhysmemNewOSRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                         IMG_DEVMEM_SIZE_T uiSize,
+                                                IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                IMG_UINT32 ui32NumPhysChunks,
+                                                IMG_UINT32 ui32NumVirtChunks,
+                                                IMG_BOOL *pabMappingTable,
+                         IMG_UINT32 uiLog2PageSize,
+                         PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                         PMR **ppsPMRPtr)
+{
+    return _NewOSAllocPagesPMR(psDevNode,
+                               uiSize,
+                               uiChunkSize,
+                               ui32NumPhysChunks,
+                               ui32NumVirtChunks,
+                               pabMappingTable,
+                               uiLog2PageSize,
+                               uiFlags,
+                               ppsPMRPtr);
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.h b/drivers/gpu/rogue_m/services/server/env/linux/physmem_osmem_linux.h
new file mode 100644 (file)
index 0000000..f30f964
--- /dev/null
@@ -0,0 +1,49 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux OS physmem implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PHYSMEM_OSMEM_LINUX_H__
+#define __PHYSMEM_OSMEM_LINUX_H__
+
+void LinuxInitPagePool(void);
+void LinuxDeinitPagePool(void);
+
+#endif /* __PHYSMEM_OSMEM_LINUX_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/physmem_tdmetacode_linux.c b/drivers/gpu/rogue_m/services/server/env/linux/physmem_tdmetacode_linux.c
new file mode 100644 (file)
index 0000000..789ed63
--- /dev/null
@@ -0,0 +1,386 @@
+/*************************************************************************/ /*!
+@File
+@Title          Implementation of PMR functions for Trusted Device firmware code memory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management.  This module is responsible for
+                implementing the function callbacks for physical memory borrowed
+                from that normally managed by the operating system.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* include5/ */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pdump_physmem.h"
+#include "pdump_km.h"
+#include "pmr.h"
+#include "pmr_impl.h"
+
+/* ourselves */
+#include "physmem_osmem.h"
+
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif
+
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/mm_types.h>
+#include <linux/vmalloc.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#if defined(CONFIG_X86)
+#include <asm/cacheflush.h>
+#endif
+
+#include "rgxdevice.h"
+
+/* This is a placeholder implementation of a PMR factory to wrap allocations into
+   the protected META code regions. It has been consciously heavily inspired by the
+   standard osmem PMR factory to supply dummy functionality. Most things here will
+   change in a real implementation.
+
+   Your starting point for re-implementing this module should be by inspecting the 
+   sTDMETACodePMRFuncTab structure below and determining which callbacks you need
+   to implement for your system.
+*/
+
+typedef struct {
+       void *token;
+       IMG_UINT32 ui32Log2PageSizeBytes;
+       struct page **apsPageArray;
+       IMG_UINT64 ui64NumPages;
+
+       PHYS_HEAP *psTDMetaCodePhysHeap;
+    IMG_HANDLE hPDumpAllocInfo;
+} sTDMetaCodePageList;
+
+static void
+_FreeTDMetaCodePageContainer(void *pvPagecontainer)
+{
+       sTDMetaCodePageList *psPageContainer = (sTDMetaCodePageList *) pvPagecontainer;
+
+       if(! psPageContainer)
+       {
+               return;
+       }
+
+       if(psPageContainer->apsPageArray)
+       {
+               IMG_UINT64 i;
+               for(i = 0; i < psPageContainer->ui64NumPages; i++)
+               {
+                       if(psPageContainer->apsPageArray[i])
+                       {
+                               __free_page(psPageContainer->apsPageArray[i]);
+                       }
+               }
+               OSFreeMem(psPageContainer->apsPageArray);
+       }
+
+       PhysHeapRelease(psPageContainer->psTDMetaCodePhysHeap);
+
+    PDumpPMRFree(psPageContainer->hPDumpAllocInfo);
+
+    OSFreeMem(psPageContainer);
+}
+
+static PVRSRV_ERROR
+PMRSysPhysAddrTDMetaCode(PMR_IMPL_PRIVDATA pvPriv,
+                         IMG_UINT32 ui32NumOfPages,
+                         IMG_DEVMEM_OFFSET_T *puiOffset,
+                                                IMG_BOOL *pbValid,
+                         IMG_DEV_PHYADDR *psDevPAddr)
+{
+       sTDMetaCodePageList *psPageContainer = (sTDMetaCodePageList *) pvPriv;
+       IMG_UINT64 ui64PageNum;
+       IMG_UINT32 idx;
+
+       for (idx=0; idx < ui32NumOfPages; idx++)
+       {
+               if (pbValid[idx])
+               {
+                       IMG_UINT32 ui32PageOffset;
+
+                       ui64PageNum = puiOffset[idx] >> psPageContainer->ui32Log2PageSizeBytes;
+                       ui32PageOffset = puiOffset[idx] - (ui64PageNum << psPageContainer->ui32Log2PageSizeBytes);
+                       PVR_ASSERT(ui64PageNum < psPageContainer->ui64NumPages);
+
+                       psDevPAddr[idx].uiAddr = page_to_phys(psPageContainer->apsPageArray[ui64PageNum]) + ui32PageOffset;
+               }
+       }
+       
+       return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR
+PMRFinalizeTDMetaCode(PMR_IMPL_PRIVDATA pvPriv)
+{
+       _FreeTDMetaCodePageContainer((void *) pvPriv);
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRReadBytesTDMetaCode(PMR_IMPL_PRIVDATA pvPriv,
+                       IMG_DEVMEM_OFFSET_T uiOffset,
+                       IMG_UINT8 *pcBuffer,
+                       IMG_SIZE_T uiBufSz,
+                       IMG_SIZE_T *puiNumBytes)
+{
+       sTDMetaCodePageList *psPageContainer = (sTDMetaCodePageList *) pvPriv;
+    IMG_UINT8 *pvMapping;
+       IMG_UINT32 uiPageSize = 1 << psPageContainer->ui32Log2PageSizeBytes;
+       IMG_UINT32 uiPageIndex;
+       IMG_UINT32 uiReadOffset;
+       IMG_UINT32 uiReadBytes;
+
+       *puiNumBytes = 0;
+       
+       while(uiBufSz)
+       {
+       uiPageIndex = uiOffset >> psPageContainer->ui32Log2PageSizeBytes;
+               uiReadOffset = uiOffset - uiPageIndex * uiPageSize;
+               uiReadBytes = uiPageSize - uiReadOffset;
+
+               if(uiReadBytes > uiBufSz)
+               {
+                       uiReadBytes = uiBufSz;
+               }
+               
+        pvMapping = kmap(psPageContainer->apsPageArray[uiPageIndex]);
+        PVR_ASSERT(pvMapping);
+        memcpy(pcBuffer, pvMapping + uiReadOffset, uiReadBytes);
+        kunmap(psPageContainer->apsPageArray[uiPageIndex]);
+               
+               uiBufSz -= uiReadBytes;
+               pcBuffer += uiReadBytes;
+               *puiNumBytes += uiReadBytes;
+
+               uiOffset += uiReadBytes;
+       }
+    return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRKernelMapTDMetaCode(PMR_IMPL_PRIVDATA pvPriv,
+                       IMG_SIZE_T uiOffset,
+                       IMG_SIZE_T uiSize,
+                       void **ppvKernelAddressOut,
+                       IMG_HANDLE *phHandleOut,
+                       PMR_FLAGS_T ulFlags)
+{
+    sTDMetaCodePageList *psPageContainer;
+    void *pvAddress;
+
+    psPageContainer = pvPriv;
+
+       pvAddress = vm_map_ram(psPageContainer->apsPageArray,
+                                                  psPageContainer->ui64NumPages,
+                                                  -1,
+                                                  PAGE_KERNEL);
+
+       if(! pvAddress)
+       {
+               return PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+       }
+
+    *ppvKernelAddressOut = pvAddress + uiOffset;
+    *phHandleOut = pvAddress;
+
+    return PVRSRV_OK;
+}
+
+static void
+PMRKernelUnmapTDMetaCode(PMR_IMPL_PRIVDATA pvPriv,
+                         IMG_HANDLE hHandle)
+{
+    sTDMetaCodePageList *psPageContainer;
+    psPageContainer = pvPriv;
+    vm_unmap_ram(hHandle, psPageContainer->ui64NumPages);
+}
+
+static PMR_IMPL_FUNCTAB sTDMETACodePMRFuncTab = {
+       .pfnLockPhysAddresses = IMG_NULL,           /* pages are always available in these PMRs */
+       .pfnUnlockPhysAddresses = IMG_NULL,         /* as above */
+       .pfnDevPhysAddr = PMRSysPhysAddrTDMetaCode,
+       .pfnPDumpSymbolicAddr = IMG_NULL,           /* nothing special needed */
+       .pfnAcquireKernelMappingData = PMRKernelMapTDMetaCode,
+       .pfnReleaseKernelMappingData = PMRKernelUnmapTDMetaCode,
+       .pfnReadBytes = PMRReadBytesTDMetaCode,
+       .pfnFinalize = PMRFinalizeTDMetaCode
+};
+
+
+static PVRSRV_ERROR
+_AllocTDMetaCodePageContainer(IMG_UINT64 ui64NumPages,
+                              IMG_UINT32 uiLog2PageSize,
+                              PHYS_HEAP *psTDMetaCodePhysHeap,
+                              void **ppvPageContainer)
+{
+       IMG_UINT64 i;
+       PVRSRV_ERROR eStatus = PVRSRV_OK;
+       sTDMetaCodePageList *psPageContainer;
+
+       psPageContainer = OSAllocMem(sizeof(sTDMetaCodePageList));
+       if(!psPageContainer)
+       {
+               eStatus = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail;
+       }
+       psPageContainer->ui32Log2PageSizeBytes = uiLog2PageSize;
+       psPageContainer->ui64NumPages = ui64NumPages;
+       psPageContainer->psTDMetaCodePhysHeap = psTDMetaCodePhysHeap;
+       psPageContainer->apsPageArray = OSAllocMem(ui64NumPages * sizeof(psPageContainer->apsPageArray[0]));
+       if(!psPageContainer->apsPageArray)
+       {
+               eStatus = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail;
+       }
+       for(i = 0; i < ui64NumPages; i++)
+       {
+               psPageContainer->apsPageArray[i] = IMG_NULL;
+       }
+
+       for(i = 0; i < ui64NumPages; i++)
+       {
+               psPageContainer->apsPageArray[i] = alloc_page(GFP_KERNEL);
+               if(! psPageContainer->apsPageArray[i])
+               {
+                       eStatus = PVRSRV_ERROR_REQUEST_TDMETACODE_PAGES_FAIL;
+                       goto fail;
+               }
+       }
+
+       *ppvPageContainer = psPageContainer;
+       return eStatus;
+
+fail:
+       _FreeTDMetaCodePageContainer((void *) psPageContainer);
+       *ppvPageContainer = IMG_NULL;
+       return eStatus;
+}
+
+PVRSRV_ERROR
+PhysmemNewTDMetaCodePMR(PVRSRV_DEVICE_NODE *psDevNode,
+                        IMG_DEVMEM_SIZE_T uiSize,
+                        IMG_UINT32 uiLog2PageSize,
+                        PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                        PMR **ppsPMRPtr)
+{
+       sTDMetaCodePageList *psPageContainer = IMG_NULL;
+       IMG_UINT32 uiPageSize = 1 << uiLog2PageSize;
+       IMG_UINT64 ui64NumPages = (uiSize >> uiLog2PageSize) + ((uiSize & (uiPageSize-1)) != 0);
+       PVRSRV_ERROR eStatus;
+       PHYS_HEAP *psTDMetaCodePhysHeap;
+       IMG_BOOL bMappingTable = IMG_TRUE;
+    IMG_HANDLE hPDumpAllocInfo = IMG_NULL;
+       RGX_DATA *psRGXData;
+
+    IMG_UINT32 uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
+    /* check no significant bits were lost in cast due to different
+       bit widths for flags */
+    PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
+       
+       /* get the physical heap for TD Meta Code */
+       psRGXData = (RGX_DATA *)(psDevNode->psDevConfig->hDevData);
+       if(! psRGXData->bHasTDMetaCodePhysHeap)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed allocation from non-existent Trusted Device physical heap!"));
+               eStatus = PVRSRV_ERROR_REQUEST_TDMETACODE_PAGES_FAIL;
+               goto fail;
+       }
+       eStatus = PhysHeapAcquire(psRGXData->uiTDMetaCodePhysHeapID,
+                                 &psTDMetaCodePhysHeap);
+       if(eStatus)
+       {
+               goto fail;
+       }
+
+       /* allocate and initialize the page container structure */
+       eStatus = _AllocTDMetaCodePageContainer(ui64NumPages,
+                                               uiLog2PageSize,
+                                               psTDMetaCodePhysHeap,
+                                               (void *)&psPageContainer);
+       if(eStatus)
+       {
+               goto fail;
+       }
+
+       /* wrap the container in a PMR */
+    eStatus = PMRCreatePMR(psTDMetaCodePhysHeap,
+                           ui64NumPages * uiPageSize,
+                           ui64NumPages * uiPageSize,
+                           1,
+                           1,
+                           &bMappingTable,
+                           uiLog2PageSize,
+                           uiPMRFlags,
+                           "PMRTDMETACODE",
+                           &sTDMETACodePMRFuncTab,
+                           (void *)psPageContainer,
+                           ppsPMRPtr,
+                           &hPDumpAllocInfo,
+                           IMG_FALSE);
+       
+#if defined(PVR_RI_DEBUG)
+       {
+               RIWritePMREntryKM (*ppsPMRPtr,
+                                                  sizeof("TD META Code"),
+                                                  "TD META Code",
+                                                  (ui64NumPages * uiPageSize));
+       }
+#endif
+
+       /* this is needed when the allocation is finalized and we need to free it. */
+       psPageContainer->hPDumpAllocInfo = hPDumpAllocInfo;
+
+       return eStatus;
+
+       /* error cleanup */
+
+fail:
+       return eStatus;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/physmem_tdsecbuf_linux.c b/drivers/gpu/rogue_m/services/server/env/linux/physmem_tdsecbuf_linux.c
new file mode 100644 (file)
index 0000000..531973f
--- /dev/null
@@ -0,0 +1,385 @@
+/*************************************************************************/ /*!
+@File
+@Title          Implementation of PMR functions for Trusted Device secure buffers
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management.  This module is responsible for
+                implementing the function callbacks for physical memory borrowed
+                from that normally managed by the operating system.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* include5/ */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pdump_physmem.h"
+#include "pdump_km.h"
+#include "pmr.h"
+#include "pmr_impl.h"
+
+/* ourselves */
+#include "physmem_osmem.h"
+
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif
+
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/mm_types.h>
+#include <linux/vmalloc.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#if defined(CONFIG_X86)
+#include <asm/cacheflush.h>
+#endif
+
+#include "rgxdevice.h"
+
+/* This is a placeholder implementation of a PMR factory to wrap allocations into
+   the secure buffer regions. It has been consciously heavily inspired by the
+   standard osmem PMR factory to supply dummy functionality. Most things here will
+   change in a real implementation.
+
+   Your starting point for re-implementing this module should be by inspecting the 
+   sTDSecureBufPMRFuncTab structure below and determining which callbacks you need
+   to implement for your system.
+*/
+
+typedef struct {
+       void *token;
+       IMG_UINT32 ui32Log2PageSizeBytes;
+       struct page **apsPageArray;
+       IMG_UINT64 ui64NumPages;
+
+       PHYS_HEAP *psTDSecureBufPhysHeap;
+    IMG_HANDLE hPDumpAllocInfo;
+} sTDSecureBufPageList;
+
+static void
+_FreeTDSecureBufPageContainer(void *pvPagecontainer)
+{
+       sTDSecureBufPageList *psPageContainer = (sTDSecureBufPageList *) pvPagecontainer;
+
+       if(! psPageContainer)
+       {
+               return;
+       }
+
+       if(psPageContainer->apsPageArray)
+       {
+               IMG_UINT64 i;
+               for(i = 0; i < psPageContainer->ui64NumPages; i++)
+               {
+                       if(psPageContainer->apsPageArray[i])
+                       {
+                               __free_page(psPageContainer->apsPageArray[i]);
+                       }
+               }
+               OSFreeMem(psPageContainer->apsPageArray);
+       }
+
+       PhysHeapRelease(psPageContainer->psTDSecureBufPhysHeap);
+
+    PDumpPMRFree(psPageContainer->hPDumpAllocInfo);
+
+       OSFreeMem(psPageContainer);
+}
+
+static PVRSRV_ERROR
+PMRSysPhysAddrTDSecureBuf(PMR_IMPL_PRIVDATA pvPriv,
+                         IMG_UINT32 ui32NumOfPages,
+                         IMG_DEVMEM_OFFSET_T *puiOffset,
+                                                IMG_BOOL *pbValid,
+                         IMG_DEV_PHYADDR *psDevPAddr)
+{
+       sTDSecureBufPageList *psPageContainer = (sTDSecureBufPageList *) pvPriv;
+       IMG_UINT32 ui32PageOffset;
+       IMG_UINT64 ui64PageNum;
+       IMG_UINT32 idx;
+
+       for (idx=0; idx < ui32NumOfPages; idx++)
+       {
+               if (pbValid[idx])
+               {
+                       ui64PageNum = puiOffset[idx] >> psPageContainer->ui32Log2PageSizeBytes;
+                       ui32PageOffset = puiOffset[idx] - (ui64PageNum << psPageContainer->ui32Log2PageSizeBytes);
+                       PVR_ASSERT(ui64PageNum < psPageContainer->ui64NumPages);
+
+                       psDevPAddr[idx].uiAddr = page_to_phys(psPageContainer->apsPageArray[ui64PageNum]) + ui32PageOffset;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR
+PMRFinalizeTDSecureBuf(PMR_IMPL_PRIVDATA pvPriv)
+{
+       _FreeTDSecureBufPageContainer((void *) pvPriv);
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRReadBytesTDSecureBuf(PMR_IMPL_PRIVDATA pvPriv,
+                       IMG_DEVMEM_OFFSET_T uiOffset,
+                       IMG_UINT8 *pcBuffer,
+                       IMG_SIZE_T uiBufSz,
+                       IMG_SIZE_T *puiNumBytes)
+{
+       sTDSecureBufPageList *psPageContainer = (sTDSecureBufPageList *) pvPriv;
+    IMG_UINT8 *pvMapping;
+       IMG_UINT32 uiPageSize = 1 << psPageContainer->ui32Log2PageSizeBytes;
+       IMG_UINT32 uiPageIndex;
+       IMG_UINT32 uiReadOffset;
+       IMG_UINT32 uiReadBytes;
+
+       *puiNumBytes = 0;
+       
+       while(uiBufSz)
+       {
+       uiPageIndex = uiOffset >> psPageContainer->ui32Log2PageSizeBytes;
+               uiReadOffset = uiOffset - uiPageIndex * uiPageSize;
+               uiReadBytes = uiPageSize - uiReadOffset;
+
+               if(uiReadBytes > uiBufSz)
+               {
+                       uiReadBytes = uiBufSz;
+               }
+               
+        pvMapping = kmap(psPageContainer->apsPageArray[uiPageIndex]);
+        PVR_ASSERT(pvMapping);
+        memcpy(pcBuffer, pvMapping + uiReadOffset, uiReadBytes);
+        kunmap(psPageContainer->apsPageArray[uiPageIndex]);
+               
+               uiBufSz -= uiReadBytes;
+               pcBuffer += uiReadBytes;
+               *puiNumBytes += uiReadBytes;
+
+               uiOffset += uiReadBytes;
+       }
+    return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PMRKernelMapTDSecureBuf(PMR_IMPL_PRIVDATA pvPriv,
+                       IMG_SIZE_T uiOffset,
+                       IMG_SIZE_T uiSize,
+                       void **ppvKernelAddressOut,
+                       IMG_HANDLE *phHandleOut,
+                       PMR_FLAGS_T ulFlags)
+{
+    sTDSecureBufPageList *psPageContainer;
+    void *pvAddress;
+
+    psPageContainer = pvPriv;
+
+       pvAddress = vm_map_ram(psPageContainer->apsPageArray,
+                                                  psPageContainer->ui64NumPages,
+                                                  -1,
+                                                  PAGE_KERNEL);
+
+       if(! pvAddress)
+       {
+               return PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+       }
+
+    *ppvKernelAddressOut = pvAddress + uiOffset;
+    *phHandleOut = pvAddress;
+
+    return PVRSRV_OK;
+}
+
+static void
+PMRKernelUnmapTDSecureBuf(PMR_IMPL_PRIVDATA pvPriv,
+                         IMG_HANDLE hHandle)
+{
+    sTDSecureBufPageList *psPageContainer;
+    psPageContainer = pvPriv;
+    vm_unmap_ram(hHandle, psPageContainer->ui64NumPages);
+}
+
+static PMR_IMPL_FUNCTAB sTDSecureBufPMRFuncTab = {
+       .pfnLockPhysAddresses = IMG_NULL,           /* pages are always available in these PMRs */
+       .pfnUnlockPhysAddresses = IMG_NULL,         /* as above */
+       .pfnDevPhysAddr = PMRSysPhysAddrTDSecureBuf,
+       .pfnPDumpSymbolicAddr = IMG_NULL,           /* nothing special needed */
+       .pfnAcquireKernelMappingData = PMRKernelMapTDSecureBuf,
+       .pfnReleaseKernelMappingData = PMRKernelUnmapTDSecureBuf,
+       .pfnReadBytes = PMRReadBytesTDSecureBuf,
+       .pfnFinalize = PMRFinalizeTDSecureBuf
+};
+
+
+static PVRSRV_ERROR
+_AllocTDSecureBufPageContainer(IMG_UINT64 ui64NumPages,
+                              IMG_UINT32 uiLog2PageSize,
+                              PHYS_HEAP *psTDSecureBufPhysHeap,
+                              void **ppvPageContainer)
+{
+       IMG_UINT64 i;
+       PVRSRV_ERROR eStatus = PVRSRV_OK;
+       sTDSecureBufPageList *psPageContainer;
+
+       psPageContainer = OSAllocMem(sizeof(sTDSecureBufPageList));
+       if(!psPageContainer)
+       {
+               eStatus = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail;
+       }
+       psPageContainer->ui32Log2PageSizeBytes = uiLog2PageSize;
+       psPageContainer->ui64NumPages = ui64NumPages;
+       psPageContainer->psTDSecureBufPhysHeap = psTDSecureBufPhysHeap;
+       psPageContainer->apsPageArray = OSAllocMem(ui64NumPages * sizeof(psPageContainer->apsPageArray[0]));
+       if(!psPageContainer->apsPageArray)
+       {
+               eStatus = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail;
+       }
+       for(i = 0; i < ui64NumPages; i++)
+       {
+               psPageContainer->apsPageArray[i] = IMG_NULL;
+       }
+
+       for(i = 0; i < ui64NumPages; i++)
+       {
+               psPageContainer->apsPageArray[i] = alloc_page(GFP_KERNEL);
+               if(! psPageContainer->apsPageArray[i])
+               {
+                       eStatus = PVRSRV_ERROR_REQUEST_TDSECUREBUF_PAGES_FAIL;
+                       goto fail;
+               }
+       }
+
+       *ppvPageContainer = psPageContainer;
+       return eStatus;
+
+fail:
+       _FreeTDSecureBufPageContainer((void *) psPageContainer);
+       *ppvPageContainer = IMG_NULL;
+       return eStatus;
+}
+
+PVRSRV_ERROR
+PhysmemNewTDSecureBufPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                        IMG_DEVMEM_SIZE_T uiSize,
+                        IMG_UINT32 uiLog2PageSize,
+                        PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                        PMR **ppsPMRPtr)
+{
+       sTDSecureBufPageList *psPageContainer = IMG_NULL;
+       IMG_UINT32 uiPageSize = 1 << uiLog2PageSize;
+       IMG_UINT64 ui64NumPages = (uiSize >> uiLog2PageSize) + ((uiSize & (uiPageSize-1)) != 0);
+       PVRSRV_ERROR eStatus;
+       PHYS_HEAP *psTDSecureBufPhysHeap;
+       IMG_BOOL bMappingTable = IMG_TRUE;
+       IMG_HANDLE hPDumpAllocInfo = IMG_NULL;
+       RGX_DATA *psRGXData;
+
+    IMG_UINT32 uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
+    /* check no significant bits were lost in cast due to different
+       bit widths for flags */
+    PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
+       
+       /* get the physical heap for TD secure buffers */
+       psRGXData = (RGX_DATA *)(psDevNode->psDevConfig->hDevData);
+       if(! psRGXData->bHasTDSecureBufPhysHeap)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"Failed allocation from non-existent Trusted Device physical heap!"));
+               eStatus = PVRSRV_ERROR_REQUEST_TDSECUREBUF_PAGES_FAIL;
+               goto fail;
+       }
+       eStatus = PhysHeapAcquire(psRGXData->uiTDSecureBufPhysHeapID,
+                                 &psTDSecureBufPhysHeap);
+       if(eStatus)
+       {
+               goto fail;
+       }
+
+       /* allocate and initialize the page container structure */
+       eStatus = _AllocTDSecureBufPageContainer(ui64NumPages,
+                                               uiLog2PageSize,
+                                               psTDSecureBufPhysHeap,
+                                               (void *)&psPageContainer);
+       if(eStatus)
+       {
+               goto fail;
+       }
+
+       /* wrap the container in a PMR */
+    eStatus = PMRCreatePMR(psTDSecureBufPhysHeap,
+                           ui64NumPages * uiPageSize,
+                           ui64NumPages * uiPageSize,
+                           1,
+                           1,
+                           &bMappingTable,
+                           uiLog2PageSize,
+                           uiPMRFlags,
+                           "PMRTDSECUREBUF",
+                           &sTDSecureBufPMRFuncTab,
+                           (void *)psPageContainer,
+                           ppsPMRPtr,
+                           &hPDumpAllocInfo,
+                           IMG_FALSE);
+       
+#if defined(PVR_RI_DEBUG)
+       {
+               RIWritePMREntryKM (*ppsPMRPtr,
+                                                  sizeof("TD Secure Buffer"),
+                                                  "TD Secure Buffer",
+                                                  (ui64NumPages * uiPageSize));
+       }
+#endif
+
+       /* this is needed when the allocation is finalized and we need to free it. */
+       psPageContainer->hPDumpAllocInfo = hPDumpAllocInfo;
+
+       return eStatus;
+
+       /* error cleanup */
+
+fail:
+       return eStatus;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/private_data.h b/drivers/gpu/rogue_m/services/server/env/linux/private_data.h
new file mode 100644 (file)
index 0000000..6d63f15
--- /dev/null
@@ -0,0 +1,53 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linux private data structure
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__INCLUDED_PRIVATE_DATA_H_)
+#define __INCLUDED_PRIVATE_DATA_H_
+
+#include <linux/fs.h>
+
+#include "connection_server.h"
+
+CONNECTION_DATA *LinuxConnectionFromFile(struct file *pFile);
+struct file *LinuxFileFromConnection(CONNECTION_DATA *psConnection);
+
+#endif /* !defined(__INCLUDED_PRIVATE_DATA_H_) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_bridge_k.c b/drivers/gpu/rogue_m/services/server/env/linux/pvr_bridge_k.c
new file mode 100644 (file)
index 0000000..edb2a03
--- /dev/null
@@ -0,0 +1,839 @@
+/*************************************************************************/ /*!
+@File
+@Title          PVR Bridge Module (kernel side)
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Receives calls from the user portion of services and
+                despatches them to functions in the kernel portion.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "img_defs.h"
+#include "pvr_bridge.h"
+#include "connection_server.h"
+#include "syscommon.h"
+#include "pvr_debug.h"
+#include "pvr_debugfs.h"
+#include "private_data.h"
+#include "linkage.h"
+
+#if defined(SUPPORT_DRM)
+#include <drm/drmP.h>
+#include "pvr_drm.h"
+#endif /* defined(SUPPORT_DRM) */
+
+/* RGX: */
+#if defined(SUPPORT_RGX)
+#include "rgx_bridge.h"
+#endif
+
+#include "srvcore.h"
+#include "common_srvcore_bridge.h"
+#include "cache_defines.h"
+
+#if defined(MODULE_TEST)
+/************************************************************************/
+// additional includes for services testing
+/************************************************************************/
+#include "pvr_test_bridge.h"
+#include "kern_test.h"
+/************************************************************************/
+// end of additional includes
+/************************************************************************/
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+static PVR_DEBUGFS_ENTRY_DATA *gpsPVRDebugFSBridgeStatsEntry = NULL;
+static struct seq_operations gsBridgeStatsReadOps;
+#endif
+
+/* These will go when full bridge gen comes in */
+PVRSRV_ERROR InitPDUMPCTRLBridge(void);
+PVRSRV_ERROR DeinitPDUMPCTRLBridge(void);
+#if defined(SUPPORT_DISPLAY_CLASS)
+PVRSRV_ERROR InitDCBridge(void);
+PVRSRV_ERROR DeinitDCBridge(void);
+#endif
+PVRSRV_ERROR InitMMBridge(void);
+PVRSRV_ERROR DeinitMMBridge(void);
+PVRSRV_ERROR InitCMMBridge(void);
+PVRSRV_ERROR DeinitCMMBridge(void);
+PVRSRV_ERROR InitPDUMPMMBridge(void);
+PVRSRV_ERROR DeinitPDUMPMMBridge(void);
+PVRSRV_ERROR InitPDUMPBridge(void);
+PVRSRV_ERROR DeinitPDUMPBridge(void);
+PVRSRV_ERROR InitSRVCOREBridge(void);
+PVRSRV_ERROR DeinitSRVCOREBridge(void);
+PVRSRV_ERROR InitSYNCBridge(void);
+PVRSRV_ERROR DeinitSYNCBridge(void);
+#if defined(SUPPORT_INSECURE_EXPORT)
+PVRSRV_ERROR InitSYNCEXPORTBridge(void);
+PVRSRV_ERROR DeinitSYNCEXPORTBridge(void);
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+PVRSRV_ERROR InitSYNCSEXPORTBridge(void);
+PVRSRV_ERROR DeinitSYNCSEXPORTBridge(void);
+#endif
+#if defined (SUPPORT_RGX)
+PVRSRV_ERROR InitRGXINITBridge(void);
+PVRSRV_ERROR DeinitRGXINITBridge(void);
+PVRSRV_ERROR InitRGXTA3DBridge(void);
+PVRSRV_ERROR DeinitRGXTA3DBridge(void);
+PVRSRV_ERROR InitRGXTQBridge(void);
+PVRSRV_ERROR DeinitRGXTQBridge(void);
+PVRSRV_ERROR InitRGXCMPBridge(void);
+PVRSRV_ERROR DeinitRGXCMPBridge(void);
+PVRSRV_ERROR InitBREAKPOINTBridge(void);
+PVRSRV_ERROR DeinitBREAKPOINTBridge(void);
+PVRSRV_ERROR InitDEBUGMISCBridge(void);
+PVRSRV_ERROR DeinitDEBUGMISCBridge(void);
+PVRSRV_ERROR InitRGXPDUMPBridge(void);
+PVRSRV_ERROR DeinitRGXPDUMPBridge(void);
+PVRSRV_ERROR InitRGXHWPERFBridge(void);
+PVRSRV_ERROR DeinitRGXHWPERFBridge(void);
+#if defined(RGX_FEATURE_RAY_TRACING)
+PVRSRV_ERROR InitRGXRAYBridge(void);
+PVRSRV_ERROR DeinitRGXRAYBridge(void);
+#endif /* RGX_FEATURE_RAY_TRACING */
+PVRSRV_ERROR InitREGCONFIGBridge(void);
+PVRSRV_ERROR DeinitREGCONFIGBridge(void);
+PVRSRV_ERROR InitTIMERQUERYBridge(void);
+PVRSRV_ERROR DeinitTIMERQUERYBridge(void);
+#endif /* SUPPORT_RGX */
+#if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
+PVRSRV_ERROR InitCACHEGENERICBridge(void);
+PVRSRV_ERROR DeinitCACHEGENERICBridge(void);
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+PVRSRV_ERROR InitSMMBridge(void);
+PVRSRV_ERROR DeinitSMMBridge(void);
+#endif
+PVRSRV_ERROR InitPVRTLBridge(void);
+PVRSRV_ERROR DeinitPVRTLBridge(void);
+#if defined(PVR_RI_DEBUG)
+PVRSRV_ERROR InitRIBridge(void);
+PVRSRV_ERROR DeinitRIBridge(void);
+#endif
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(IMG_VOID);
+PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(IMG_VOID);
+#endif
+#if defined(SUPPORT_ION)
+PVRSRV_ERROR InitDMABUFBridge(void);
+PVRSRV_ERROR DeinitDMABUFBridge(void);
+#endif
+#if defined(SUPPORT_VALIDATION)
+PVRSRV_ERROR InitVALIDATIONBridge(void);
+#endif
+#if defined(PVR_TESTING_UTILS)
+PVRSRV_ERROR InitTUTILSBridge(void);
+PVRSRV_ERROR DeinitTUTILSBridge(void);
+#endif
+
+PVRSRV_ERROR
+LinuxBridgeInit(void)
+{
+       PVRSRV_ERROR eError;
+#if defined(DEBUG_BRIDGE_KM)
+       IMG_INT iResult;
+
+       iResult = PVRDebugFSCreateEntry("bridge_stats",
+                                       NULL,
+                                       &gsBridgeStatsReadOps,
+                                       NULL,
+                                       &g_BridgeDispatchTable[0],
+                                       &gpsPVRDebugFSBridgeStatsEntry);
+       if (iResult != 0)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+#endif
+
+       eError = InitSRVCOREBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitSYNCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+       eError = InitSYNCEXPORTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+       eError = InitSYNCSEXPORTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       eError = InitPDUMPCTRLBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = InitMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = InitCMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = InitPDUMPMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = InitPDUMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(SUPPORT_ION)
+       eError = InitDMABUFBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+       eError = InitDCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
+       eError = InitCACHEGENERICBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(SUPPORT_SECURE_EXPORT)
+       eError = InitSMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       eError = InitPVRTLBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       #if defined(PVR_RI_DEBUG)
+       eError = InitRIBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       #endif
+
+#if defined(SUPPORT_VALIDATION)
+       eError = InitVALIDATIONBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(PVR_TESTING_UTILS)
+       eError = InitTUTILSBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       eError = InitDEVICEMEMHISTORYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       #if defined (SUPPORT_RGX)
+       eError = InitRGXTQBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitRGXCMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitRGXINITBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitRGXTA3DBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitBREAKPOINTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitDEBUGMISCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       
+       eError = InitRGXPDUMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitRGXHWPERFBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       eError = InitRGXRAYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+       eError = InitREGCONFIGBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = InitTIMERQUERYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#endif /* SUPPORT_RGX */
+
+       return eError;
+}
+
+PVRSRV_ERROR
+LinuxBridgeDeInit(void)
+{
+       PVRSRV_ERROR eError;
+#if defined(DEBUG_BRIDGE_KM)
+       if (gpsPVRDebugFSBridgeStatsEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsPVRDebugFSBridgeStatsEntry);
+               gpsPVRDebugFSBridgeStatsEntry = NULL;
+       }
+#endif
+
+       eError = DeinitSRVCOREBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitSYNCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+       eError = DeinitSYNCEXPORTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+#if defined(SUPPORT_SECURE_EXPORT)
+       eError = DeinitSYNCSEXPORTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       eError = DeinitPDUMPCTRLBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = DeinitMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = DeinitCMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = DeinitPDUMPMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       eError = DeinitPDUMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(SUPPORT_ION)
+       eError = DeinitDMABUFBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(PVR_TESTING_UTILS)
+       eError = DeinitTUTILSBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+       eError = DeinitDCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
+       eError = DeinitCACHEGENERICBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+#if defined(SUPPORT_SECURE_EXPORT)
+       eError = DeinitSMMBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       eError = DeinitPVRTLBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       #if defined(PVR_RI_DEBUG)
+       eError = DeinitRIBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       #endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       eError = DeinitDEVICEMEMHISTORYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif
+
+       #if defined (SUPPORT_RGX)
+       eError = DeinitRGXTQBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitRGXCMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitRGXINITBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitRGXTA3DBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitBREAKPOINTBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitDEBUGMISCBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+       
+       eError = DeinitRGXPDUMPBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitRGXHWPERFBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#if defined(RGX_FEATURE_RAY_TRACING)
+       eError = DeinitRGXRAYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+#endif /* RGX_FEATURE_RAY_TRACING */
+
+       eError = DeinitREGCONFIGBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+       eError = DeinitTIMERQUERYBridge();
+       if (eError != PVRSRV_OK)
+       {
+               return eError;
+       }
+
+#endif /* SUPPORT_RGX */
+
+       return eError;
+}
+
+#if defined(DEBUG_BRIDGE_KM)
+static void *BridgeStatsSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
+
+       OSAcquireBridgeLock();
+
+       if (psDispatchTable == NULL || (*puiPosition) > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+       {
+               return NULL;
+       }
+
+       if ((*puiPosition) == 0) 
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return &(psDispatchTable[(*puiPosition) - 1]);
+}
+
+static void BridgeStatsSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       OSReleaseBridgeLock();
+}
+
+static void *BridgeStatsSeqNext(struct seq_file *psSeqFile,
+                              void *pvData,
+                              loff_t *puiPosition)
+{
+       PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
+       loff_t uiItemAskedFor = *puiPosition; /* puiPosition on entry is the index to return */
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       /* Is the item asked for (starts at 0) a valid table index? */
+       if (uiItemAskedFor < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+       {
+               (*puiPosition)++; /* on exit it is the next seq index to ask for */
+               return &(psDispatchTable[uiItemAskedFor]);
+       }
+
+       /* Now passed the end of the table to indicate stop */
+       return IMG_NULL;
+}
+
+static int BridgeStatsSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData == SEQ_START_TOKEN)
+       {
+               seq_printf(psSeqFile,
+                          "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"
+                          "%-60s | %-48s | %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");
+       }
+       else if (pvData != NULL)
+       {
+               PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)pvData;
+
+               seq_printf(psSeqFile,
+                          "%3d: %-60s   %-48s   %-10u   %-20u   %-10u\n",
+                          (IMG_UINT32)(((IMG_SIZE_T)psEntry-(IMG_SIZE_T)g_BridgeDispatchTable)/sizeof(PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY)),
+                          psEntry->pszIOCName,
+                          psEntry->pszFunctionName,
+                          psEntry->ui32CallCount,
+                          psEntry->ui32CopyFromUserTotalBytes,
+                          psEntry->ui32CopyToUserTotalBytes);
+       }
+
+       return 0;
+}
+
+static struct seq_operations gsBridgeStatsReadOps =
+{
+       .start = BridgeStatsSeqStart,
+       .stop = BridgeStatsSeqStop,
+       .next = BridgeStatsSeqNext,
+       .show = BridgeStatsSeqShow,
+};
+#endif /* defined(DEBUG_BRIDGE_KM) */
+
+
+#if defined(SUPPORT_DRM)
+int
+PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pDRMFile)
+#else
+long
+PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int ioctlCmd, unsigned long arg)
+#endif
+{
+#if defined(SUPPORT_DRM)
+       struct file *pFile = PVR_FILE_FROM_DRM_FILE(pDRMFile);
+#else
+       PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+       PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
+#endif
+       PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
+       CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile);
+
+       if(psConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
+               return -EFAULT;
+       }
+
+       if(OSGetDriverSuspended())
+       {
+               return -EINTR;
+       }
+
+#if defined(SUPPORT_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__));
+
+               return -EFAULT;
+       }
+       
+       /* FIXME - Currently the CopyFromUserWrapper which collects stats about
+        * how much data is shifted to/from userspace isn't available to us
+        * here. */
+       if (OSCopyFromUser(IMG_NULL,
+                                         psBridgePackageKM,
+                                         psBridgePackageUM,
+                                         sizeof(PVRSRV_BRIDGE_PACKAGE))
+         != PVRSRV_OK)
+       {
+               return -EFAULT;
+       }
+
+       if (PVRSRV_GET_BRIDGE_ID(ioctlCmd) != psBridgePackageKM->ui32BridgeID ||
+           psBridgePackageKM->ui32Size != sizeof(PVRSRV_BRIDGE_PACKAGE))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Inconsistent data passed from user space",
+                               __FUNCTION__));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+#endif
+
+#if defined(DEBUG_BRIDGE_CALLS)
+       {
+               IMG_UINT32 mangledID;
+               mangledID = psBridgePackageKM->ui32BridgeID;
+
+               psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
+
+               PVR_DPF((PVR_DBG_WARNING, "%s: Bridge ID (x%8x) %8u (mangled: x%8x) ", __FUNCTION__, psBridgePackageKM->ui32BridgeID, psBridgePackageKM->ui32BridgeID, mangledID));
+       }
+#else
+               psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
+#endif
+
+       return BridgedDispatchKM(psConnection, psBridgePackageKM);
+}
+
+
+#if defined(CONFIG_COMPAT)
+#if defined(SUPPORT_DRM)
+int
+#else
+long
+#endif
+PVRSRV_BridgeCompatDispatchKM(struct file *pFile,
+                             unsigned int ioctlCmd,
+                             unsigned long arg)
+{
+       struct bridge_package_from_32
+       {
+               IMG_UINT32                              bridge_id;                      /*!< ioctl bridge group */
+               IMG_UINT32                              function_id;        /*!< ioctl function index */
+               IMG_UINT32                              size;                           /*!< size of structure */
+               IMG_UINT32                              addr_param_in;          /*!< input data buffer */ 
+               IMG_UINT32                              in_buffer_size;         /*!< size of input data buffer */
+               IMG_UINT32                              addr_param_out;         /*!< output data buffer */
+               IMG_UINT32                              out_buffer_size;        /*!< size of output data buffer */
+       };
+
+       PVRSRV_BRIDGE_PACKAGE params_for_64;
+       struct bridge_package_from_32 params;
+       struct bridge_package_from_32 * const params_addr = &params;
+       CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile);
+
+       if(psConnection == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
+               return -EFAULT;
+       }
+
+       if(OSGetDriverSuspended())
+       {
+               return -EINTR;
+       }
+
+       /* make sure there is no padding inserted by compiler */
+       BUILD_BUG_ON(sizeof(struct bridge_package_from_32) != 7 * sizeof(IMG_UINT32));
+
+       if(!OSAccessOK(PVR_VERIFY_READ, (void *) arg,
+                                  sizeof(struct bridge_package_from_32)))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
+                                __FUNCTION__));
+
+               return -EFAULT;
+       }
+       
+       if(OSCopyFromUser(NULL, params_addr, (void*) arg,
+                                         sizeof(struct bridge_package_from_32))
+          != PVRSRV_OK)
+       {
+               return -EFAULT;
+       }
+
+#if defined(SUPPORT_DRM)
+       if (params_addr->size != sizeof(struct bridge_package_from_32))
+#else
+       if (PVRSRV_GET_BRIDGE_ID(ioctlCmd) != PVRSRV_GET_BRIDGE_ID(params_addr->bridge_id) ||
+           params_addr->size != sizeof(struct bridge_package_from_32))
+#endif
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Inconsistent data passed from user space",
+                       __FUNCTION__));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       params_for_64.ui32BridgeID = PVRSRV_GET_BRIDGE_ID(params_addr->bridge_id);
+       params_for_64.ui32FunctionID = params_addr->function_id;
+       params_for_64.ui32Size = sizeof(params_for_64);
+       params_for_64.pvParamIn = (void*) ((size_t) params_addr->addr_param_in);
+       params_for_64.pvParamOut = (void*) ((size_t) params_addr->addr_param_out);
+       params_for_64.ui32InBufferSize = params_addr->in_buffer_size;
+       params_for_64.ui32OutBufferSize = params_addr->out_buffer_size;
+
+       return BridgedDispatchKM(psConnection, &params_for_64);
+}
+#endif /* defined(CONFIG_COMPAT) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_debug.c b/drivers/gpu/rogue_m/services/server/env/linux/pvr_debug.c
new file mode 100644 (file)
index 0000000..7b56714
--- /dev/null
@@ -0,0 +1,1386 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Provides kernel side Debug Functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <stdarg.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+#include <generated/compile.h>
+#include <generated/utsrelease.h>
+#else
+#include <linux/compile.h>
+#include <linux/utsrelease.h>
+#endif
+
+#include "allocmem.h"
+#include "pvrversion.h"
+#include "img_types.h"
+#include "servicesext.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "pvr_debugfs.h"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+#include "pvrsrv.h"
+#include "rgxdevice.h"
+#include "rgxdebug.h"
+#include "lists.h"
+#include "osfunc.h"
+
+/* Handle used by DebugFS to get GPU utilisation stats */
+static IMG_HANDLE ghGpuUtilUserDebugFS = NULL;
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+/******** BUFFERED LOG MESSAGES ********/
+
+/* Because we don't want to have to handle CCB wrapping, each buffered
+ * message is rounded up to PVRSRV_DEBUG_CCB_MESG_MAX bytes. This means
+ * there is the same fixed number of messages that can be stored,
+ * regardless of message length.
+ */
+
+#if defined(PVRSRV_DEBUG_CCB_MAX)
+
+#define PVRSRV_DEBUG_CCB_MESG_MAX      PVR_MAX_DEBUG_MESSAGE_LEN
+
+#include <linux/syscalls.h>
+#include <linux/time.h>
+
+typedef struct
+{
+       const IMG_CHAR *pszFile;
+       IMG_INT iLine;
+       IMG_UINT32 ui32TID;
+       IMG_CHAR pcMesg[PVRSRV_DEBUG_CCB_MESG_MAX];
+       struct timeval sTimeVal;
+}
+PVRSRV_DEBUG_CCB;
+
+static PVRSRV_DEBUG_CCB gsDebugCCB[PVRSRV_DEBUG_CCB_MAX] = { { 0 } };
+
+static IMG_UINT giOffset = 0;
+
+static DEFINE_MUTEX(gsDebugCCBMutex);
+
+static void
+AddToBufferCCB(const IMG_CHAR *pszFileName, IMG_UINT32 ui32Line,
+                          const IMG_CHAR *szBuffer)
+{
+       mutex_lock(&gsDebugCCBMutex);
+
+       gsDebugCCB[giOffset].pszFile = pszFileName;
+       gsDebugCCB[giOffset].iLine   = ui32Line;
+       gsDebugCCB[giOffset].ui32TID = current->tgid;
+
+       do_gettimeofday(&gsDebugCCB[giOffset].sTimeVal);
+
+       strncpy(gsDebugCCB[giOffset].pcMesg, szBuffer, PVRSRV_DEBUG_CCB_MESG_MAX - 1);
+       gsDebugCCB[giOffset].pcMesg[PVRSRV_DEBUG_CCB_MESG_MAX - 1] = 0;
+
+       giOffset = (giOffset + 1) % PVRSRV_DEBUG_CCB_MAX;
+
+       mutex_unlock(&gsDebugCCBMutex);
+}
+
+IMG_EXPORT void PVRSRVDebugPrintfDumpCCB(void)
+{
+       int i;
+
+       mutex_lock(&gsDebugCCBMutex);
+       
+       for (i = 0; i < PVRSRV_DEBUG_CCB_MAX; i++)
+       {
+               PVRSRV_DEBUG_CCB *psDebugCCBEntry =
+                       &gsDebugCCB[(giOffset + i) % PVRSRV_DEBUG_CCB_MAX];
+
+               /* Early on, we won't have PVRSRV_DEBUG_CCB_MAX messages */
+               if (!psDebugCCBEntry->pszFile)
+               {
+                       continue;
+               }
+
+               printk(KERN_ERR "%s:%d: (%ld.%ld,tid=%u) %s\n",
+                          psDebugCCBEntry->pszFile,
+                          psDebugCCBEntry->iLine,
+                          (long)psDebugCCBEntry->sTimeVal.tv_sec,
+                          (long)psDebugCCBEntry->sTimeVal.tv_usec,
+                          psDebugCCBEntry->ui32TID,
+                          psDebugCCBEntry->pcMesg);
+
+               /* Clear this entry so it doesn't get printed the next time again. */
+               psDebugCCBEntry->pszFile = IMG_NULL;
+       }
+
+       mutex_unlock(&gsDebugCCBMutex);
+}
+
+#else /* defined(PVRSRV_DEBUG_CCB_MAX) */
+static INLINE void
+AddToBufferCCB(const IMG_CHAR *pszFileName, IMG_UINT32 ui32Line,
+               const IMG_CHAR *szBuffer)
+{
+       (void)pszFileName;
+       (void)szBuffer;
+       (void)ui32Line;
+}
+
+IMG_EXPORT void PVRSRVDebugPrintfDumpCCB(void)
+{
+       /* Not available */
+}
+
+#endif /* defined(PVRSRV_DEBUG_CCB_MAX) */
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+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);
+
+/* NOTE: Must NOT be static! Used in module.c.. */
+IMG_UINT32 gPVRDebugLevel =
+       (
+        DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING
+
+#if defined(PVRSRV_DEBUG_CCB_MAX)
+        | DBGPRIV_BUFFERED
+#endif /* defined(PVRSRV_DEBUG_CCB_MAX) */
+
+#if defined(PVR_DPF_ADHOC_DEBUG_ON)
+        | DBGPRIV_DEBUG
+#endif /* defined(PVR_DPF_ADHOC_DEBUG_ON) */
+       );
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(PVRSRV_NEED_PVR_TRACE) */
+
+#define        PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
+
+/* Message buffer for non-IRQ messages */
+static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
+
+/* Message buffer for IRQ messages */
+static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
+
+/* The lock is used to control access to gszBufferNonIRQ */
+static DEFINE_MUTEX(gsDebugMutexNonIRQ);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+/* The lock is used to control access to gszBufferIRQ */
+static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(gsDebugLockIRQ);
+#endif
+
+#define        USE_SPIN_LOCK (in_interrupt() || !preemptible())
+
+static inline void GetBufferLock(unsigned long *pulLockFlags)
+{
+       if (USE_SPIN_LOCK)
+       {
+               spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
+       }
+       else
+       {
+               mutex_lock(&gsDebugMutexNonIRQ);
+       }
+}
+
+static inline void ReleaseBufferLock(unsigned long ulLockFlags)
+{
+       if (USE_SPIN_LOCK)
+       {
+               spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
+       }
+       else
+       {
+               mutex_unlock(&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);
+       }
+}
+
+/*
+ * Append a string to a buffer using formatted conversion.
+ * The function takes a variable number of arguments, pointed
+ * to by the var args list.
+ */
+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 true if string was truncated */
+       return i32Len < 0 || i32Len >= (IMG_INT32)ui32Space;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRSRVReleasePrintf
+@Description    To output an important message to the user in release builds
+@Input          pszFormat   The message format string
+@Input          ...         Zero or more arguments for use by the format string
+*/ /**************************************************************************/
+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 - 2));
+       pszBuf[ui32BufSiz - 1] = '\0';
+
+       if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+       {
+               printk(KERN_ERR "PVR_K:(Message Truncated): %s\n", pszBuf);
+       }
+       else
+       {
+               printk(KERN_ERR "%s\n", pszBuf);
+       }
+
+       ReleaseBufferLock(ulLockFlags);
+       va_end(vaArgs);
+}
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+/*************************************************************************/ /*!
+@Function       PVRTrace
+@Description    To output a debug message to the user
+@Input          pszFormat   The message format string
+@Input          ...         Zero or more arguments for use by the format string
+*/ /**************************************************************************/
+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 - 2));
+       pszBuf[ui32BufSiz - 1] = '\0';
+
+       if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
+       {
+               printk(KERN_ERR "PVR_K:(Message Truncated): %s\n", pszBuf);
+       }
+       else
+       {
+               printk(KERN_ERR "%s\n", pszBuf);
+       }
+
+       ReleaseBufferLock(ulLockFlags);
+
+       va_end(VArgs);
+}
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+/*
+ * Append a string to a buffer using formatted conversion.
+ * The function takes a variable number of arguments, calling
+ * VBAppend to do the actual work.
+ */
+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;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRSRVDebugPrintf
+@Description    To output a debug message to the user
+@Input          uDebugLevel The current debug level
+@Input          pszFile     The source file generating the message
+@Input          uLine       The line of the source file
+@Input          pszFormat   The message format string
+@Input          ...         Zero or more arguments for use by the format string
+*/ /**************************************************************************/
+void PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
+                          const IMG_CHAR *pszFullFileName,
+                          IMG_UINT32 ui32Line,
+                          const IMG_CHAR *pszFormat,
+                          ...)
+{
+       IMG_BOOL bNoLoc;
+       const IMG_CHAR *pszFileName = pszFullFileName;
+       IMG_CHAR *pszLeafName;
+
+       bNoLoc = (IMG_BOOL)((ui32DebugLevel & DBGPRIV_CALLTRACE) |
+                                               (ui32DebugLevel & DBGPRIV_BUFFERED)) ? 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);
+
+               switch (ui32DebugLevel)
+               {
+                       case DBGPRIV_FATAL:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_ERROR:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Error): ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_WARNING:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Warn):  ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_MESSAGE:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Mesg):  ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_VERBOSE:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Verb):  ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_DEBUG:
+                       {
+                               strncpy(pszBuf, "PVR_K:(Debug): ", (ui32BufSiz - 2));
+                               break;
+                       }
+                       case DBGPRIV_CALLTRACE:
+                       case DBGPRIV_ALLOC:
+                       case DBGPRIV_BUFFERED:
+                       default:
+                       {
+                               strncpy(pszBuf, "PVR_K:  ", (ui32BufSiz - 2));
+                               break;
+                       }
+               }
+               pszBuf[ui32BufSiz - 1] = '\0';
+
+               (void) BAppend(pszBuf, ui32BufSiz, "%u: ", current->pid);
+
+
+               if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+               {
+                       printk(KERN_ERR "PVR_K:(Message Truncated): %s\n", pszBuf);
+               }
+               else
+               {
+#if !defined(__sh__)
+                       pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '/');
+
+                       if (pszLeafName)
+                       {
+                               pszFileName = pszLeafName+1;
+                       }
+#endif /* __sh__ */
+
+                       if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
+                       {
+                               printk(KERN_ERR "PVR_K:(Message Truncated): %s\n", pszBuf);
+                       }
+                       else
+                       {
+                               if (ui32DebugLevel & DBGPRIV_BUFFERED)
+                               {
+                                       AddToBufferCCB(pszFileName, ui32Line, pszBuf);
+                               }
+                               else
+                               {
+                                       printk(KERN_ERR "%s\n", pszBuf);
+                               }
+                       }
+               }
+
+               ReleaseBufferLock(ulLockFlags);
+
+               va_end (vaArgs);
+       }
+}
+
+#endif /* PVRSRV_NEED_PVR_DPF */
+
+#if 0
+static void *_DebugFreqSeqStart(struct seq_file *psSeqFile,
+                                  loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       if (*puiPosition == 0)
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugVersionCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static void _DebugFreqSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugFreqSeqNext(struct seq_file *psSeqFile,
+                                 void *pvData,
+                                 loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       (*puiPosition)++;
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugVersionCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static int _DebugFreqSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData == SEQ_START_TOKEN)
+       {
+               const IMG_CHAR *pszSystemVersionString = PVRSRVGetSystemName();
+
+               seq_printf(psSeqFile, "Freq %s (%s) %s\n",
+                          PVRVERSION_STRING,
+                          PVR_BUILD_TYPE, PVR_BUILD_DIR);
+
+               seq_printf(psSeqFile, "Freq: %s\n", pszSystemVersionString);
+       }
+       else if (pvData != NULL)
+       {
+               PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)pvData;
+
+               if (psDevNode->pfnDeviceVersionString)
+               {
+                       IMG_CHAR *pszDeviceVersionString;
+                       
+                       if (psDevNode->pfnDeviceVersionString(psDevNode, &pszDeviceVersionString) == PVRSRV_OK)
+                       {
+                               seq_printf(psSeqFile, "%s\n", pszDeviceVersionString);
+                               
+                               kfree(pszDeviceVersionString);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static struct seq_operations gsDebugFreqReadOps =
+{
+       .start = _DebugFreqSeqStart,
+       .stop = _DebugFreqSeqStop,
+       .next = _DebugFreqSeqNext,
+       .show = _DebugFreqSeqShow,
+};
+#endif
+
+/*************************************************************************/ /*!
+ Version DebugFS entry
+*/ /**************************************************************************/
+
+static void *_DebugVersionCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode,
+                                         va_list va)
+{
+       loff_t *puiCurrentPosition = va_arg(va, loff_t *);
+       loff_t uiPosition = va_arg(va, loff_t);
+       loff_t uiCurrentPosition = *puiCurrentPosition;
+
+       (*puiCurrentPosition)++;
+
+       return (uiCurrentPosition == uiPosition) ? psDevNode : NULL;
+}
+
+static void *_DebugVersionSeqStart(struct seq_file *psSeqFile,
+                                  loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       if (*puiPosition == 0)
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugVersionCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static void _DebugVersionSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugVersionSeqNext(struct seq_file *psSeqFile,
+                                 void *pvData,
+                                 loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       (*puiPosition)++;
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugVersionCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static int _DebugVersionSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData == SEQ_START_TOKEN)
+       {
+               const IMG_CHAR *pszSystemVersionString = PVRSRVGetSystemName();
+
+               seq_printf(psSeqFile, "Version: %s (%s) %s\n",
+                          PVRVERSION_STRING,
+                          PVR_BUILD_TYPE, PVR_BUILD_DIR);
+
+               seq_printf(psSeqFile, "System Version String: %s\n", pszSystemVersionString);
+
+               seq_printf(psSeqFile, "Kernel Version: " UTS_RELEASE " (" UTS_MACHINE ")\n");
+       }
+       else if (pvData != NULL)
+       {
+               PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)pvData;
+
+               if (psDevNode->pfnDeviceVersionString)
+               {
+                       IMG_CHAR *pszDeviceVersionString;
+                       
+                       if (psDevNode->pfnDeviceVersionString(psDevNode, &pszDeviceVersionString) == PVRSRV_OK)
+                       {
+                               seq_printf(psSeqFile, "%s\n", pszDeviceVersionString);
+                               
+                               OSFreeMem(pszDeviceVersionString);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static struct seq_operations gsDebugVersionReadOps =
+{
+       .start = _DebugVersionSeqStart,
+       .stop = _DebugVersionSeqStop,
+       .next = _DebugVersionSeqNext,
+       .show = _DebugVersionSeqShow,
+};
+
+/*************************************************************************/ /*!
+ Status DebugFS entry
+*/ /**************************************************************************/
+
+static void *_DebugStatusCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode,
+                                        va_list va)
+{
+       loff_t *puiCurrentPosition = va_arg(va, loff_t *);
+       loff_t uiPosition = va_arg(va, loff_t);
+       loff_t uiCurrentPosition = *puiCurrentPosition;
+
+       (*puiCurrentPosition)++;
+
+       return (uiCurrentPosition == uiPosition) ? psDevNode : NULL;
+}
+
+static void *_DebugStatusSeqStart(struct seq_file *psSeqFile,
+                                 loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       if (*puiPosition == 0)
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugStatusCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static void _DebugStatusSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugStatusSeqNext(struct seq_file *psSeqFile,
+                                   void *pvData,
+                                   loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       (*puiPosition)++;
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugVersionCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static int _DebugStatusSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData == SEQ_START_TOKEN)
+       {
+               PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+
+               if (psPVRSRVData != NULL)
+               {
+                       switch (psPVRSRVData->eServicesState)
+                       {
+                               case PVRSRV_SERVICES_STATE_OK:
+                                       seq_printf(psSeqFile, "Driver Status:   OK\n");
+                                       break;
+                               case PVRSRV_SERVICES_STATE_BAD:
+                                       seq_printf(psSeqFile, "Driver Status:   BAD\n");
+                                       break;
+                               default:
+                                       seq_printf(psSeqFile, "Driver Status:   %d\n", psPVRSRVData->eServicesState);
+                                       break;
+                       }
+               }
+       }
+       else if (pvData != NULL)
+       {
+               PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+               IMG_CHAR           *pszStatus = "";
+               IMG_CHAR           *pszReason = "";
+               
+               /* Update the health status now if possible... */
+               if (psDeviceNode->pfnUpdateHealthStatus)
+               {
+                       psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, IMG_FALSE);
+               }
+               
+               switch (psDeviceNode->eHealthStatus)
+               {
+                       case PVRSRV_DEVICE_HEALTH_STATUS_OK:  pszStatus = "OK";  break;
+                       case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING:  pszStatus = "NOT RESPONDING";  break;
+                       case PVRSRV_DEVICE_HEALTH_STATUS_DEAD:  pszStatus = "DEAD";  break;
+                       default:  pszStatus = "UNKNOWN";  break;
+               }
+
+               /* Write the device status to the sequence file... */
+               if (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_RGX)
+               {
+                       switch (psDeviceNode->eHealthReason)
+                       {
+                               case PVRSRV_DEVICE_HEALTH_REASON_NONE:  pszReason = "";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED:  pszReason = " (FW Assert)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING:  pszReason = " (Poll failure)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS:  pszReason = " (Global Event Object timeouts rising)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT:  pszReason = " (KCCB offset invalid)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED:  pszReason = " (KCCB stalled)";  break;
+                               default:  pszReason = " (Unknown reason)";  break;
+                       }
+
+                       seq_printf(psSeqFile, "Firmware Status: %s%s\n", pszStatus, pszReason);
+
+                       /* Write other useful stats to aid the test cycle... */
+                       if (psDeviceNode->pvDevice != NULL)
+                       {
+                               PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+                               RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
+
+                               /* Calculate the number of HWR events in total across all the DMs... */
+                               if (psRGXFWIfTraceBufCtl != NULL)
+                               {
+                                       IMG_UINT32 ui32HWREventCount = 0;
+                                       IMG_UINT32 ui32CRREventCount = 0;
+                                       IMG_UINT32 ui32DMIndex;
+
+                                       for (ui32DMIndex = 0; ui32DMIndex < RGXFWIF_DM_MAX; ui32DMIndex++)
+                                       {
+                                               ui32HWREventCount += psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[ui32DMIndex];
+                                               ui32CRREventCount += psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[ui32DMIndex];
+                                       }
+
+                                       seq_printf(psSeqFile, "HWR Event Count: %d\n", ui32HWREventCount);
+                                       seq_printf(psSeqFile, "CRR Event Count: %d\n", ui32CRREventCount);
+                               }
+                               
+                               /* Write the number of APM events... */
+                               seq_printf(psSeqFile, "APM Event Count: %d\n", psDevInfo->ui32ActivePMReqTotal);
+                               
+                               /* Write the current GPU Utilisation values... */
+                               if (psDevInfo->pfnRegisterGpuUtilStats && psDevInfo->pfnGetGpuUtilStats &&
+                                   psDeviceNode->eHealthStatus == PVRSRV_DEVICE_HEALTH_STATUS_OK)
+                               {
+                                       RGXFWIF_GPU_UTIL_STATS sGpuUtilStats;
+                                       PVRSRV_ERROR eError = PVRSRV_OK;
+
+                                       if (ghGpuUtilUserDebugFS == NULL)
+                                       {
+                                               eError = psDevInfo->pfnRegisterGpuUtilStats(&ghGpuUtilUserDebugFS);
+                                       }
+
+                                       if (eError == PVRSRV_OK)
+                                       {
+                                               eError = psDevInfo->pfnGetGpuUtilStats(psDeviceNode,
+                                                                                      ghGpuUtilUserDebugFS,
+                                                                                      &sGpuUtilStats);
+                                       }
+
+                                       if ((eError == PVRSRV_OK) &&
+                                           ((IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative))
+                                       {
+                                               IMG_UINT64 util;
+                                               IMG_UINT32 rem;
+
+                                               util = 100 * (sGpuUtilStats.ui64GpuStatActiveHigh +
+                                                             sGpuUtilStats.ui64GpuStatActiveLow);
+                                               util = OSDivide64(util, (IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative, &rem);
+
+                                               seq_printf(psSeqFile, "GPU Utilisation: %u%%\n", (IMG_UINT32)util);
+                                       }
+                                       else
+                                       {
+                                               seq_printf(psSeqFile, "GPU Utilisation: -\n");
+                                       }
+                               }
+                       }
+               }
+               else
+               {
+                       switch (psDeviceNode->eHealthReason)
+                       {
+                               case PVRSRV_DEVICE_HEALTH_REASON_NONE:  pszReason = "";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED:  pszReason = " (ASSERTED)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING:  pszReason = " (POLL FAILING)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS:  pszReason = " (TIMEOUTS)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT:  pszReason = " (QUEUE CORRUPT)";  break;
+                               case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED:  pszReason = " (QUEUE STALLED)";  break;
+                               default:  pszReason = " (UNKNOWN)";  break;
+                       }
+
+                       seq_printf(psSeqFile, "Device %d Status: %s%s\n",
+                                          psDeviceNode->sDevId.ui32DeviceIndex, pszStatus, pszReason);
+               }
+       }
+
+       return 0;
+}
+
+static IMG_INT DebugStatusSet(const char __user *pcBuffer,
+                            size_t uiCount,
+                            loff_t uiPosition,
+                            void *pvData)
+{
+       IMG_CHAR acDataBuffer[6];
+
+       if (uiPosition != 0)
+       {
+               return -EIO;
+       }
+
+       if (uiCount > (sizeof(acDataBuffer) / sizeof(acDataBuffer[0])))
+       {
+               return -EINVAL;
+       }
+
+       if (pvr_copy_from_user(acDataBuffer, pcBuffer, uiCount))
+       {
+               return -EINVAL;
+       }
+
+       if (acDataBuffer[uiCount - 1] != '\n')
+       {
+               return -EINVAL;
+       }
+
+       if (((acDataBuffer[0] == 'k') || ((acDataBuffer[0] == 'K'))) && uiCount == 2)
+       {
+               PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+               psPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_BAD;
+       }
+       else
+       {
+               return -EINVAL;
+       }
+
+       return uiCount;
+}
+
+static struct seq_operations gsDebugStatusReadOps =
+{
+       .start = _DebugStatusSeqStart,
+       .stop = _DebugStatusSeqStop,
+       .next = _DebugStatusSeqNext,
+       .show = _DebugStatusSeqShow,
+};
+
+/*************************************************************************/ /*!
+ Dump Debug DebugFS entry
+*/ /**************************************************************************/
+
+static void *_DebugDumpDebugCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode, va_list va)
+{
+       loff_t *puiCurrentPosition = va_arg(va, loff_t *);
+       loff_t uiPosition = va_arg(va, loff_t);
+       loff_t uiCurrentPosition = *puiCurrentPosition;
+
+       (*puiCurrentPosition)++;
+
+       return (uiCurrentPosition == uiPosition) ? psDevNode : NULL;
+}
+
+static void *_DebugDumpDebugSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       if (*puiPosition == 0)
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugDumpDebugCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static void _DebugDumpDebugSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugDumpDebugSeqNext(struct seq_file *psSeqFile,
+                                   void *pvData,
+                                   loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       (*puiPosition)++;
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugDumpDebugCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static struct seq_file *gpsDumpDebugPrintfSeqFile = IMG_NULL;
+
+static void _DumpDebugSeqPrintf(const IMG_CHAR *pszFormat, ...)
+{
+       if (gpsDumpDebugPrintfSeqFile)
+       {
+               IMG_CHAR  szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+               va_list  ArgList;
+
+               va_start(ArgList, pszFormat);
+               vsnprintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, pszFormat, ArgList);
+               seq_printf(gpsDumpDebugPrintfSeqFile, "%s\n", szBuffer);
+               va_end(ArgList);
+       }
+}
+
+static int _DebugDumpDebugSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData != NULL  &&  pvData != SEQ_START_TOKEN)
+       {
+               PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+               
+               if (psDeviceNode->pvDevice != NULL)
+               {
+                       gpsDumpDebugPrintfSeqFile = psSeqFile;
+                       PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, _DumpDebugSeqPrintf);
+                       gpsDumpDebugPrintfSeqFile = IMG_NULL;
+                       
+               }
+       }
+
+       return 0;
+}
+
+static struct seq_operations gsDumpDebugReadOps = 
+{
+       .start = _DebugDumpDebugSeqStart,
+       .stop  = _DebugDumpDebugSeqStop,
+       .next  = _DebugDumpDebugSeqNext,
+       .show  = _DebugDumpDebugSeqShow,
+};
+/*************************************************************************/ /*!
+ Firmware Trace DebugFS entry
+*/ /**************************************************************************/
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+static void *_DebugFWTraceCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode, va_list va)
+{
+       loff_t *puiCurrentPosition = va_arg(va, loff_t *);
+       loff_t uiPosition = va_arg(va, loff_t);
+       loff_t uiCurrentPosition = *puiCurrentPosition;
+
+       (*puiCurrentPosition)++;
+
+       return (uiCurrentPosition == uiPosition) ? psDevNode : NULL;
+}
+
+static void *_DebugFWTraceSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       if (*puiPosition == 0)
+       {
+               return SEQ_START_TOKEN;
+       }
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugFWTraceCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static void _DebugFWTraceSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugFWTraceSeqNext(struct seq_file *psSeqFile,
+                                   void *pvData,
+                                   loff_t *puiPosition)
+{
+       PVRSRV_DATA *psPVRSRVData = (PVRSRV_DATA *)psSeqFile->private;
+       loff_t uiCurrentPosition = 1;
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       (*puiPosition)++;
+
+       return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+                                             _DebugFWTraceCompare_AnyVaCb,
+                                             &uiCurrentPosition,
+                                             *puiPosition);
+}
+
+static struct seq_file *gpsFWTracePrintfSeqFile = IMG_NULL;
+
+static void _FWTraceSeqPrintf(const IMG_CHAR *pszFormat, ...)
+{
+       if (gpsFWTracePrintfSeqFile)
+       {
+               IMG_CHAR  szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+               va_list  ArgList;
+
+               va_start(ArgList, pszFormat);
+               vsnprintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, pszFormat, ArgList);
+               seq_printf(gpsFWTracePrintfSeqFile, "%s\n", szBuffer);
+               va_end(ArgList);
+       }
+}
+
+static int _DebugFWTraceSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData != NULL  &&  pvData != SEQ_START_TOKEN)
+       {
+               PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+               
+               if (psDeviceNode->pvDevice != NULL)
+               {
+                       PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+                       gpsFWTracePrintfSeqFile = psSeqFile;
+                       RGXDumpFirmwareTrace(_FWTraceSeqPrintf, psDevInfo);
+                       gpsFWTracePrintfSeqFile = IMG_NULL;
+               }
+       }
+
+       return 0;
+}
+
+static struct seq_operations gsFWTraceReadOps = 
+{
+       .start = _DebugFWTraceSeqStart,
+       .stop  = _DebugFWTraceSeqStop,
+       .next  = _DebugFWTraceSeqNext,
+       .show  = _DebugFWTraceSeqShow,
+};
+#endif
+
+
+/*************************************************************************/ /*!
+ Debug level DebugFS entry
+*/ /**************************************************************************/
+
+#if defined(DEBUG)
+static void *DebugLevelSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       if (*puiPosition == 0)
+       {
+               return psSeqFile->private;
+       }
+
+       return NULL;
+}
+
+static void DebugLevelSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *DebugLevelSeqNext(struct seq_file *psSeqFile,
+                              void *pvData,
+                              loff_t *puiPosition)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       PVR_UNREFERENCED_PARAMETER(pvData);
+       PVR_UNREFERENCED_PARAMETER(puiPosition);
+
+       return NULL;
+}
+
+static int DebugLevelSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       if (pvData != NULL)
+       {
+               IMG_UINT32 uiDebugLevel = *((IMG_UINT32 *)pvData);
+
+               seq_printf(psSeqFile, "%u\n", uiDebugLevel);
+
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static struct seq_operations gsDebugLevelReadOps =
+{
+       .start = DebugLevelSeqStart,
+       .stop = DebugLevelSeqStop,
+       .next = DebugLevelSeqNext,
+       .show = DebugLevelSeqShow,
+};
+
+
+static IMG_INT DebugLevelSet(const char __user *pcBuffer,
+                            size_t uiCount,
+                            loff_t uiPosition,
+                            void *pvData)
+{
+       IMG_UINT32 *uiDebugLevel = (IMG_UINT32 *)pvData;
+       IMG_CHAR acDataBuffer[6];
+
+       if (uiPosition != 0)
+       {
+               return -EIO;
+       }
+
+       if (uiCount > (sizeof(acDataBuffer) / sizeof(acDataBuffer[0])))
+       {
+               return -EINVAL;
+       }
+
+       if (pvr_copy_from_user(acDataBuffer, pcBuffer, uiCount))
+       {
+               return -EINVAL;
+       }
+
+       if (acDataBuffer[uiCount - 1] != '\n')
+       {
+               return -EINVAL;
+       }
+
+       if (sscanf(acDataBuffer, "%u", &gPVRDebugLevel) == 0)
+       {
+               return -EINVAL;
+       }
+
+       /* As this is Linux the next line uses a GCC builtin function */
+       (*uiDebugLevel) &= (1 << __builtin_ffsl(DBGPRIV_LAST)) - 1;
+
+       return uiCount;
+}
+#endif /* defined(DEBUG) */
+
+static PVR_DEBUGFS_ENTRY_DATA *gpsVersionDebugFSEntry;
+
+static PVR_DEBUGFS_ENTRY_DATA *gpsStatusDebugFSEntry;
+static PVR_DEBUGFS_ENTRY_DATA *gpsDumpDebugDebugFSEntry;
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+static PVR_DEBUGFS_ENTRY_DATA *gpsFWTraceDebugFSEntry;
+#endif
+
+#if defined(DEBUG)
+static PVR_DEBUGFS_ENTRY_DATA *gpsDebugLevelDebugFSEntry;
+#endif
+
+int PVRDebugCreateDebugFSEntries(void)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       int iResult;
+
+       PVR_ASSERT(psPVRSRVData != NULL);
+       PVR_ASSERT(gpsVersionDebugFSEntry == NULL);
+
+       iResult = PVRDebugFSCreateEntry("version",
+                                       NULL,
+                                       &gsDebugVersionReadOps,
+                                       NULL,
+                                       psPVRSRVData,
+                                       &gpsVersionDebugFSEntry);
+       if (iResult != 0)
+       {
+               return iResult;
+       }
+
+       iResult = PVRDebugFSCreateEntry("status",
+                                       NULL,
+                                       &gsDebugStatusReadOps,
+                                       (PVRSRV_ENTRY_WRITE_FUNC *)DebugStatusSet,
+                                       psPVRSRVData,
+                                       &gpsStatusDebugFSEntry);
+       if (iResult != 0)
+       {
+               goto ErrorRemoveVersionEntry;
+       }
+
+       iResult = PVRDebugFSCreateEntry("debug_dump",
+                                       NULL,
+                                       &gsDumpDebugReadOps,
+                                       NULL,
+                                       psPVRSRVData,
+                                       &gpsDumpDebugDebugFSEntry);
+       if (iResult != 0)
+       {
+               goto ErrorRemoveStatusEntry;
+       }
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+       iResult = PVRDebugFSCreateEntry("firmware_trace",
+                                       NULL,
+                                       &gsFWTraceReadOps,
+                                       NULL,
+                                       psPVRSRVData,
+                                       &gpsFWTraceDebugFSEntry);
+       if (iResult != 0)
+       {
+               goto ErrorRemoveDumpDebugEntry;
+       }
+#endif
+
+#if defined(DEBUG)
+       iResult = PVRDebugFSCreateEntry("debug_level",
+                                       NULL,
+                                       &gsDebugLevelReadOps,
+                                       (PVRSRV_ENTRY_WRITE_FUNC *)DebugLevelSet,
+                                       &gPVRDebugLevel,
+                                       &gpsDebugLevelDebugFSEntry);
+       if (iResult != 0)
+       {
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+               goto ErrorRemoveFWTraceLogEntry;
+#else
+               goto ErrorRemoveDumpDebugEntry;
+#endif
+       }
+#endif
+
+       return 0;
+
+#if (defined(DEBUG) && defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS))
+ErrorRemoveFWTraceLogEntry:
+       PVRDebugFSRemoveEntry(gpsFWTraceDebugFSEntry);
+       gpsFWTraceDebugFSEntry = NULL;
+#endif
+
+#if (defined(DEBUG) || defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS))
+ErrorRemoveDumpDebugEntry:
+       PVRDebugFSRemoveEntry(gpsDumpDebugDebugFSEntry);
+       gpsDumpDebugDebugFSEntry = NULL;
+#endif
+
+ErrorRemoveStatusEntry:
+       PVRDebugFSRemoveEntry(gpsStatusDebugFSEntry);
+       gpsStatusDebugFSEntry = NULL;
+
+ErrorRemoveVersionEntry:
+       PVRDebugFSRemoveEntry(gpsVersionDebugFSEntry);
+       gpsVersionDebugFSEntry = NULL;
+
+       return iResult;
+}
+
+void PVRDebugRemoveDebugFSEntries(void)
+{
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+       PVRSRV_DEVICE_NODE *psDeviceNode;
+       PVRSRV_RGXDEV_INFO *psDevInfo;
+
+       psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[0];
+       if (psDeviceNode)
+       {
+               psDevInfo = psDeviceNode->pvDevice;
+               if (psDevInfo && psDevInfo->pfnUnregisterGpuUtilStats)
+               {
+                       psDevInfo->pfnUnregisterGpuUtilStats(ghGpuUtilUserDebugFS);
+               }
+       }
+
+#if defined(DEBUG)
+       if (gpsDebugLevelDebugFSEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsDebugLevelDebugFSEntry);
+               gpsDebugLevelDebugFSEntry = NULL;
+       }
+#endif
+
+#if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
+       if (gpsFWTraceDebugFSEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsFWTraceDebugFSEntry);
+               gpsFWTraceDebugFSEntry = NULL;
+       }
+#endif
+
+       if (gpsDumpDebugDebugFSEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsDumpDebugDebugFSEntry);
+               gpsDumpDebugDebugFSEntry = NULL;
+       }
+
+       if (gpsStatusDebugFSEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsStatusDebugFSEntry);
+               gpsStatusDebugFSEntry = NULL;
+       }
+
+       if (gpsVersionDebugFSEntry != NULL)
+       {
+               PVRDebugFSRemoveEntry(gpsVersionDebugFSEntry);
+               gpsVersionDebugFSEntry = NULL;
+       }
+}
+
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.c b/drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.c
new file mode 100644 (file)
index 0000000..e71ac45
--- /dev/null
@@ -0,0 +1,857 @@
+/*************************************************************************/ /*!
+@File
+@Title          Functions for creating debugfs directories and entries.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "pvr_debug.h"
+#include "pvr_debugfs.h"
+#include "allocmem.h"
+
+#define PVR_DEBUGFS_DIR_NAME "pvr"
+
+/* Define to set the PVR_DPF debug output level for pvr_debugfs.
+ * Normally, leave this set to PVR_DBGDRIV_MESSAGE, but when debugging
+ * you can temporarily change this to PVR_DBG_ERROR.
+ */
+#if defined(PVRSRV_NEED_PVR_DPF)
+#define PVR_DEBUGFS_PVR_DPF_LEVEL      PVR_DBGDRIV_MESSAGE
+#else
+#define PVR_DEBUGFS_PVR_DPF_LEVEL      0
+#endif
+
+static struct dentry *gpsPVRDebugFSEntryDir = NULL;
+
+/* Lock used when adjusting refCounts and deleting entries */
+static struct mutex gDebugFSLock;
+
+/*************************************************************************/ /*!
+ Statistic entry read functions
+*/ /**************************************************************************/
+
+typedef struct _PVR_DEBUGFS_DRIVER_STAT_
+{
+       void                             *pvData;
+       OS_STATS_PRINT_FUNC  *pfnStatsPrint;
+       PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC       *pfnIncStatMemRefCount;
+       PVRSRV_DEC_STAT_MEM_REFCOUNT_FUNC       *pfnDecStatMemRefCount;
+       IMG_UINT32                              ui32RefCount;
+       PVR_DEBUGFS_ENTRY_DATA  *pvDebugFSEntry;
+} PVR_DEBUGFS_DRIVER_STAT;
+
+typedef struct _PVR_DEBUGFS_DIR_DATA_
+{
+       struct dentry *psDir;
+       PVR_DEBUGFS_DIR_DATA *psParentDir;
+       IMG_UINT32      ui32RefCount;
+} PVR_DEBUGFS_DIR_DATA;
+
+typedef struct _PVR_DEBUGFS_ENTRY_DATA_
+{
+       struct dentry *psEntry;
+       PVR_DEBUGFS_DIR_DATA *psParentDir;
+       IMG_UINT32      ui32RefCount;
+       PVR_DEBUGFS_DRIVER_STAT *psStatData;
+} PVR_DEBUGFS_ENTRY_DATA;
+
+typedef struct _PVR_DEBUGFS_PRIV_DATA_
+{
+       struct seq_operations   *psReadOps;
+       PVRSRV_ENTRY_WRITE_FUNC *pfnWrite;
+       void                    *pvData;
+       IMG_BOOL                bValid;
+       PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry;
+} PVR_DEBUGFS_PRIV_DATA;
+
+static void _RefDirEntry(PVR_DEBUGFS_DIR_DATA *psDirEntry);
+static void _UnrefAndMaybeDestroyDirEntry(PVR_DEBUGFS_DIR_DATA *psDirEntry);
+static void _UnrefAndMaybeDestroyDirEntryWhileLocked(PVR_DEBUGFS_DIR_DATA *psDirEntry);
+static IMG_BOOL _RefDebugFSEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry);
+static void _UnrefAndMaybeDestroyDebugFSEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry);
+static IMG_BOOL _RefStatEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry);
+static IMG_BOOL _UnrefAndMaybeDestroyStatEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry);
+
+static void _StatsSeqPrintf(void *pvFile, const IMG_CHAR *pszFormat, ...)
+{
+       IMG_CHAR  szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+       va_list  ArgList;
+
+       va_start(ArgList, pszFormat);
+       vsnprintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, pszFormat, ArgList);
+       seq_printf((struct seq_file *)pvFile, "%s", szBuffer);
+       va_end(ArgList);
+}
+
+static void *_DebugFSStatisticSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       PVR_DEBUGFS_DRIVER_STAT *psStatData = (PVR_DEBUGFS_DRIVER_STAT *)psSeqFile->private;
+
+       if (psStatData)
+       {
+               if (psStatData->pvData)
+               {
+                       /* take reference on psStatData (for duration of stat iteration) */
+                       if (!_RefStatEntry((void*)psStatData))
+                       {
+                               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called for '%s' but failed to take ref on stat entry, returning -EIO(%d)", __FUNCTION__, psStatData->pvDebugFSEntry->psEntry->d_iname, -EIO));
+                               return NULL;
+                       }
+               }
+               else
+               {
+                       /* NB This is valid if the stat has no structure associated with it (eg. driver_stats, which prints totals stored in a number of global vars) */
+               }
+
+               if (*puiPosition == 0)
+               {
+                       return psStatData;
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData is NULL", __FUNCTION__));
+       }
+
+       return NULL;
+}
+
+static void _DebugFSStatisticSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_DEBUGFS_DRIVER_STAT *psStatData = (PVR_DEBUGFS_DRIVER_STAT *)psSeqFile->private;
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       if (psStatData)
+       {
+               /* drop ref taken on stat memory, and if it is now zero, be sure we don't try to read it again */
+               if ((psStatData->ui32RefCount > 0) && (psStatData->pvData))
+               {
+                       /* drop reference on psStatData (held for duration of stat iteration) */
+                       _UnrefAndMaybeDestroyStatEntry((void*)psStatData);
+               }
+               else
+               {
+                       if (psStatData->ui32RefCount > 0)
+                       {
+                               /* psStatData->pvData is NULL */
+                               /* NB This is valid if the stat has no structure associated with it (eg. driver_stats, which prints totals stored in a number of global vars) */
+                       }
+                       if (psStatData->pvData)
+                       {
+                               /* psStatData->ui32RefCount is zero */
+                               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData->ui32RefCount is %d", __FUNCTION__, psStatData->ui32RefCount));
+                       }
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData is NULL", __FUNCTION__));
+       }
+}
+
+static void *_DebugFSStatisticSeqNext(struct seq_file *psSeqFile,
+                                     void *pvData,
+                                     loff_t *puiPosition)
+{
+       PVR_DEBUGFS_DRIVER_STAT *psStatData = (PVR_DEBUGFS_DRIVER_STAT *)psSeqFile->private;
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       if (psStatData)
+       {
+               if (psStatData->pvData)
+               {
+                       if (puiPosition)
+                       {
+                               (*puiPosition)++;
+                       }
+                       else
+                       {
+                               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called with puiPosition NULL", __FUNCTION__));
+                       }
+               }
+               else
+               {
+                       /* psStatData->pvData is NULL */
+                       /* NB This is valid if the stat has no structure associated with it (eg. driver_stats, which prints totals stored in a number of global vars) */
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData is NULL", __FUNCTION__));
+       }
+
+       return NULL;
+}
+
+static int _DebugFSStatisticSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_DEBUGFS_DRIVER_STAT *psStatData = (PVR_DEBUGFS_DRIVER_STAT *)pvData;
+
+       if (psStatData != NULL)
+       {
+               psStatData->pfnStatsPrint((void*)psSeqFile, psStatData->pvData, _StatsSeqPrintf);
+               return 0;
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData is NULL, returning -ENODATA(%d)", __FUNCTION__, -ENODATA));
+       }
+
+       return -ENODATA;
+}
+
+static struct seq_operations gsDebugFSStatisticReadOps =
+{
+       .start = _DebugFSStatisticSeqStart,
+       .stop  = _DebugFSStatisticSeqStop,
+       .next  = _DebugFSStatisticSeqNext,
+       .show  = _DebugFSStatisticSeqShow,
+};
+
+
+/*************************************************************************/ /*!
+ Common internal API
+*/ /**************************************************************************/
+
+static int _DebugFSFileOpen(struct inode *psINode, struct file *psFile)
+{
+       PVR_DEBUGFS_PRIV_DATA *psPrivData;
+       int iResult = -EIO;
+       IMG_BOOL bRefRet = IMG_FALSE;
+       PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry = NULL;
+
+       PVR_ASSERT(psINode);
+       psPrivData = (PVR_DEBUGFS_PRIV_DATA *)psINode->i_private;
+
+       if (psPrivData)
+       {
+               /* Check that psPrivData is still valid to use */
+               if (psPrivData->bValid)
+               {
+                       psDebugFSEntry = psPrivData->psDebugFSEntry;
+
+                       /* Take ref on stat entry before opening seq file - this ref will be dropped if we
+                        * fail to open the seq file or when we close it
+                        */
+                       if (psDebugFSEntry)
+                       {
+                               bRefRet = _RefDebugFSEntry(psDebugFSEntry);
+                               if (bRefRet)
+                               {
+                                       iResult = seq_open(psFile, psPrivData->psReadOps);
+                                       if (iResult == 0)
+                                       {
+                                               struct seq_file *psSeqFile = psFile->private_data;
+
+                                               psSeqFile->private = psPrivData->pvData;
+                                       }
+                                       else
+                                       {
+                                               /* Drop ref if we failed to open seq file */
+                                               _UnrefAndMaybeDestroyDebugFSEntry(psDebugFSEntry);
+                                               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to seq_open psFile, returning %d", __FUNCTION__, iResult));
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return iResult;
+}
+
+static int _DebugFSFileClose(struct inode *psINode, struct file *psFile)
+{
+       int iResult;
+       PVR_DEBUGFS_PRIV_DATA *psPrivData = (PVR_DEBUGFS_PRIV_DATA *)psINode->i_private;
+       PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry = NULL;
+
+       if (psPrivData)
+       {
+               psDebugFSEntry = psPrivData->psDebugFSEntry;
+       }
+       iResult = seq_release(psINode, psFile);
+       if (psDebugFSEntry)
+       {
+               _UnrefAndMaybeDestroyDebugFSEntry(psDebugFSEntry);
+       }
+       return iResult;
+}
+
+static ssize_t _DebugFSFileWrite(struct file *psFile,
+                                const char __user *pszBuffer,
+                                size_t uiCount,
+                                loff_t *puiPosition)
+{
+       struct inode *psINode = psFile->f_path.dentry->d_inode;
+       PVR_DEBUGFS_PRIV_DATA *psPrivData = (PVR_DEBUGFS_PRIV_DATA *)psINode->i_private;
+
+       if (psPrivData->pfnWrite == NULL)
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called for file '%s', which does not have pfnWrite defined, returning -EIO(%d)", __FUNCTION__, psFile->f_path.dentry->d_iname, -EIO));
+               return -EIO;
+       }
+
+       return psPrivData->pfnWrite(pszBuffer, uiCount, *puiPosition, psPrivData->pvData);
+}
+
+static const struct file_operations gsPVRDebugFSFileOps =
+{
+       .owner = THIS_MODULE,
+       .open = _DebugFSFileOpen,
+       .read = seq_read,
+       .write = _DebugFSFileWrite,
+       .llseek = seq_lseek,
+       .release = _DebugFSFileClose,
+};
+
+
+/*************************************************************************/ /*!
+ Public API
+*/ /**************************************************************************/
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSInit
+@Description    Initialise PVR debugfs support. This should be called before
+                using any PVRDebugFS functions.
+@Return         int      On success, returns 0. Otherwise, returns an
+                         error code.
+*/ /**************************************************************************/
+int PVRDebugFSInit(void)
+{
+       PVR_ASSERT(gpsPVRDebugFSEntryDir == NULL);
+
+       mutex_init(&gDebugFSLock);
+
+       gpsPVRDebugFSEntryDir = debugfs_create_dir(PVR_DEBUGFS_DIR_NAME, NULL);
+       if (gpsPVRDebugFSEntryDir == NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "%s: Cannot create '%s' debugfs root directory",
+                        __FUNCTION__, PVR_DEBUGFS_DIR_NAME));
+
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSDeInit
+@Description    Deinitialise PVR debugfs support. This should be called only
+                if PVRDebugFSInit() has already been called. All debugfs
+                directories and entries should be removed otherwise this
+                function will fail.
+@Return         void
+*/ /**************************************************************************/
+void PVRDebugFSDeInit(void)
+{
+       debugfs_remove(gpsPVRDebugFSEntryDir);
+       gpsPVRDebugFSEntryDir = NULL;
+       mutex_destroy(&gDebugFSLock);
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSCreateEntryDir
+@Description    Create a directory for debugfs entries that will be located
+                under the root directory, as created by
+                PVRDebugFSCreateEntries().
+@Input          pszName      String containing the name for the directory.
+@Input          psParentDir  The parent directory in which to create the new
+                             directory. This should either be NULL, meaning it
+                             should be created in the root directory, or a
+                             pointer to a directory as returned by this
+                             function.
+@Output         ppsNewDir    On success, points to the newly created
+                             directory.
+@Return         int          On success, returns 0. Otherwise, returns an
+                             error code.
+*/ /**************************************************************************/
+int PVRDebugFSCreateEntryDir(IMG_CHAR *pszName,
+                                PVR_DEBUGFS_DIR_DATA *psParentDir,
+                                PVR_DEBUGFS_DIR_DATA **ppsNewDir)
+{
+       PVR_DEBUGFS_DIR_DATA *psNewDir;
+
+       PVR_ASSERT(gpsPVRDebugFSEntryDir != NULL);
+
+       if (pszName == NULL || ppsNewDir == NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s:   Invalid param", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       psNewDir = OSAllocMemstatMem(sizeof(*psNewDir));
+
+       if (psNewDir == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "%s: Cannot allocate memory for '%s' pvr_debugfs structure",
+                        __FUNCTION__, pszName));
+               return -ENOMEM;
+       }
+
+       psNewDir->psParentDir = psParentDir;
+       psNewDir->psDir = debugfs_create_dir(pszName, (psNewDir->psParentDir) ? psNewDir->psParentDir->psDir : gpsPVRDebugFSEntryDir);
+
+       if (psNewDir->psDir == NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "%s: Cannot create '%s' debugfs directory",
+                        __FUNCTION__, pszName));
+
+               OSFreeMemstatMem(psNewDir);
+               return -ENOMEM;
+       }
+
+       *ppsNewDir = psNewDir;
+       psNewDir->ui32RefCount = 1;
+
+       /* if parent directory is not gpsPVRDebugFSEntryDir, increment its refCount */
+       if (psNewDir->psParentDir)
+       {
+               _RefDirEntry(psNewDir->psParentDir);
+       }
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSRemoveEntryDir
+@Description    Remove a directory that was created by
+                PVRDebugFSCreateEntryDir(). Any directories or files created
+                under the directory being removed should be removed first.
+@Input          psDir        Pointer representing the directory to be removed.
+@Return         void
+*/ /**************************************************************************/
+void PVRDebugFSRemoveEntryDir(PVR_DEBUGFS_DIR_DATA *psDir)
+{
+       _UnrefAndMaybeDestroyDirEntry(psDir);
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSCreateEntry
+@Description    Create an entry in the specified directory.
+@Input          pszName         String containing the name for the entry.
+@Input          psParentDir     Pointer from PVRDebugFSCreateEntryDir()
+                                representing the directory in which to create
+                                the entry or NULL for the root directory.
+@Input          psReadOps       Pointer to structure containing the necessary
+                                functions to read from the entry.
+@Input          pfnWrite        Callback function used to write to the entry.
+@Input          pvData          Private data to be passed to the read
+                                functions, in the seq_file private member, and
+                                the write function callback.
+@Output         ppsNewEntry     On success, points to the newly created entry.
+@Return         int             On success, returns 0. Otherwise, returns an
+                                error code.
+*/ /**************************************************************************/
+int PVRDebugFSCreateEntry(const char *pszName,
+                         PVR_DEBUGFS_DIR_DATA *psParentDir,
+                         struct seq_operations *psReadOps,
+                         PVRSRV_ENTRY_WRITE_FUNC *pfnWrite,
+                         void *pvData,
+                         PVR_DEBUGFS_ENTRY_DATA **ppsNewEntry)
+{
+       PVR_DEBUGFS_PRIV_DATA *psPrivData;
+       PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry;
+       struct dentry *psEntry;
+       umode_t uiMode;
+
+       PVR_ASSERT(gpsPVRDebugFSEntryDir != NULL);
+
+       psPrivData = OSAllocMemstatMem(sizeof(*psPrivData));
+       if (psPrivData == NULL)
+       {
+               return -ENOMEM;
+       }
+       psDebugFSEntry = OSAllocMemstatMem(sizeof(*psDebugFSEntry));
+       if (psDebugFSEntry == NULL)
+       {
+               OSFreeMemstatMem(psPrivData);
+               return -ENOMEM;
+       }
+
+       psPrivData->psReadOps = psReadOps;
+       psPrivData->pfnWrite = pfnWrite;
+       psPrivData->pvData = (void*)pvData;
+       psPrivData->bValid = IMG_TRUE;
+       /* Store ptr to debugFSEntry in psPrivData, so a ref can be taken on it
+        * when the client opens a file */
+       psPrivData->psDebugFSEntry = psDebugFSEntry;
+
+       uiMode = S_IFREG;
+
+       if (psReadOps != NULL)
+       {
+               uiMode |= S_IRUGO;
+       }
+
+       if (pfnWrite != NULL)
+       {
+               uiMode |= S_IWUSR;
+       }
+
+       psDebugFSEntry->psParentDir = psParentDir;
+       psDebugFSEntry->ui32RefCount = 1;
+       psDebugFSEntry->psStatData = (PVR_DEBUGFS_DRIVER_STAT*)pvData;
+
+       if (psDebugFSEntry->psParentDir)
+       {
+               /* increment refCount of parent directory */
+               _RefDirEntry(psDebugFSEntry->psParentDir);
+       }
+
+       psEntry = debugfs_create_file(pszName,
+                                         uiMode,
+                                         (psParentDir != NULL) ? psParentDir->psDir : gpsPVRDebugFSEntryDir,
+                                         psPrivData,
+                                         &gsPVRDebugFSFileOps);
+       if (IS_ERR(psEntry))
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "%s: Cannot create debugfs '%s' file",
+                        __FUNCTION__, pszName));
+
+               return PTR_ERR(psEntry);
+       }
+
+       psDebugFSEntry->psEntry = psEntry;
+       *ppsNewEntry = (void*)psDebugFSEntry;
+
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSRemoveEntry
+@Description    Removes an entry that was created by PVRDebugFSCreateEntry().
+@Input          psDebugFSEntry  Pointer representing the entry to be removed.
+@Return         void
+*/ /**************************************************************************/
+void PVRDebugFSRemoveEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry)
+{
+       _UnrefAndMaybeDestroyDebugFSEntry(psDebugFSEntry);
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSCreateStatisticEntry
+@Description    Create a statistic entry in the specified directory.
+@Input          pszName         String containing the name for the entry.
+@Input          psDir           Pointer from PVRDebugFSCreateEntryDir()
+                                representing the directory in which to create
+                                the entry or NULL for the root directory.
+@Input          pfnStatsPrint   A callback function used to print all the
+                                statistics when reading from the statistic
+                                entry.
+@Input          pfnIncStatMemRefCount   A callback function used take a
+                                                                               reference on the memory backing the
+                                               statistic.
+@Input          pfnDecStatMemRefCount   A callback function used drop a
+                                                                               reference on the memory backing the
+                                               statistic.
+@Input          pvData          Private data to be passed to the provided
+                                callback function.
+
+@Return         PVR_DEBUGFS_DRIVER_STAT*   On success, a pointer representing
+                                                                                  the newly created statistic entry.
+                                                                                  Otherwise, NULL.
+*/ /**************************************************************************/
+PVR_DEBUGFS_DRIVER_STAT *PVRDebugFSCreateStatisticEntry(const char *pszName,
+                                        PVR_DEBUGFS_DIR_DATA *psDir,
+                                    OS_STATS_PRINT_FUNC *pfnStatsPrint,
+                                        PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC      *pfnIncStatMemRefCount,
+                                        PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC      *pfnDecStatMemRefCount,
+                                        void *pvData)
+{
+       PVR_DEBUGFS_DRIVER_STAT *psStatData;
+       PVR_DEBUGFS_ENTRY_DATA * psDebugFSEntry;
+
+       int iResult;
+
+       if (pszName == NULL || pfnStatsPrint == NULL)
+       {
+               return NULL;
+       }
+       if ((pfnIncStatMemRefCount != NULL || pfnDecStatMemRefCount != NULL) && pvData == NULL)
+       {
+               return NULL;
+       }
+
+       psStatData = OSAllocMemstatZMem(sizeof(*psStatData));
+       if (psStatData == NULL)
+       {
+               return NULL;
+       }
+
+       psStatData->pvData = pvData;
+       psStatData->pfnStatsPrint = pfnStatsPrint;
+       psStatData->pfnIncStatMemRefCount = pfnIncStatMemRefCount;
+       psStatData->pfnDecStatMemRefCount = pfnDecStatMemRefCount;
+       psStatData->ui32RefCount = 1;
+
+       iResult = PVRDebugFSCreateEntry(pszName,
+                                       psDir,
+                                       &gsDebugFSStatisticReadOps,
+                                       NULL,
+                                       psStatData,
+                                       &psDebugFSEntry);
+       if (iResult != 0)
+       {
+               OSFreeMemstatMem(psStatData);
+               return NULL;
+       }
+       psStatData->pvDebugFSEntry = (void*)psDebugFSEntry;
+
+       if (pfnIncStatMemRefCount)
+       {
+               /* call function to take reference on the memory holding the stat */
+               psStatData->pfnIncStatMemRefCount((void*)psStatData->pvData);
+       }
+
+       psDebugFSEntry->ui32RefCount = 1;
+
+       return psStatData;
+}
+
+/*************************************************************************/ /*!
+@Function       PVRDebugFSRemoveStatisticEntry
+@Description    Removes a statistic entry that was created by
+                PVRDebugFSCreateStatisticEntry().
+@Input          psStatEntry  Pointer representing the statistic entry to be
+                                removed.
+@Return         void
+*/ /**************************************************************************/
+void PVRDebugFSRemoveStatisticEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry)
+{
+       /* drop reference on pvStatEntry*/
+       _UnrefAndMaybeDestroyStatEntry(psStatEntry);
+}
+
+static void _RefDirEntry(PVR_DEBUGFS_DIR_DATA *psDirEntry)
+{
+       mutex_lock(&gDebugFSLock);
+
+       if (psDirEntry->ui32RefCount > 0)
+       {
+               /* Increment refCount */
+               psDirEntry->ui32RefCount++;
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to ref psDirEntry '%s' when ui32RefCount is zero", __FUNCTION__, psDirEntry->psDir->d_iname));
+       }
+
+       mutex_unlock(&gDebugFSLock);
+}
+
+static void _UnrefAndMaybeDestroyDirEntryWhileLocked(PVR_DEBUGFS_DIR_DATA *psDirEntry)
+{
+       if (psDirEntry->ui32RefCount > 0)
+       {
+               /* Decrement refCount and free if now zero */
+               if (--psDirEntry->ui32RefCount == 0)
+               {
+                       /* if parent directory is not gpsPVRDebugFSEntryDir, decrement its refCount */
+                       debugfs_remove(psDirEntry->psDir);
+                       if (psDirEntry->psParentDir)
+                       {
+                               _UnrefAndMaybeDestroyDirEntryWhileLocked(psDirEntry->psParentDir);
+                       }
+                       OSFreeMemstatMem(psDirEntry);
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to unref psDirEntry '%s' when ui32RefCount is zero", __FUNCTION__, psDirEntry->psDir->d_iname));
+       }
+}
+
+static void _UnrefAndMaybeDestroyDirEntry(PVR_DEBUGFS_DIR_DATA *psDirEntry)
+{
+       mutex_lock(&gDebugFSLock);
+
+       if (psDirEntry->ui32RefCount > 0)
+       {
+               /* Decrement refCount and free if now zero */
+               if (--psDirEntry->ui32RefCount == 0)
+               {
+                       /* if parent directory is not gpsPVRDebugFSEntryDir, decrement its refCount */
+                       debugfs_remove(psDirEntry->psDir);
+                       if (psDirEntry->psParentDir)
+                       {
+                               _UnrefAndMaybeDestroyDirEntryWhileLocked(psDirEntry->psParentDir);
+                       }
+                       OSFreeMemstatMem(psDirEntry);
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to unref psDirEntry '%s' when ui32RefCount is zero", __FUNCTION__, psDirEntry->psDir->d_iname));
+       }
+
+       mutex_unlock(&gDebugFSLock);
+}
+
+static IMG_BOOL _RefDebugFSEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry)
+{
+       IMG_BOOL bResult = IMG_FALSE;
+
+       PVR_ASSERT(psDebugFSEntry != NULL);
+
+       mutex_lock(&gDebugFSLock);
+
+       bResult = (psDebugFSEntry->ui32RefCount > 0);
+       if (bResult)
+       {
+               /* Increment refCount of psDebugFSEntry */
+               psDebugFSEntry->ui32RefCount++;
+       }
+
+       mutex_unlock(&gDebugFSLock);
+
+       return bResult;
+}
+
+static void _UnrefAndMaybeDestroyDebugFSEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry)
+{
+       mutex_lock(&gDebugFSLock);
+       /* Decrement refCount of psDebugFSEntry, and free if now zero */
+       PVR_ASSERT(psDebugFSEntry != IMG_NULL);
+
+       if (psDebugFSEntry->ui32RefCount > 0)
+       {
+               if (--psDebugFSEntry->ui32RefCount == 0)
+               {
+                       struct dentry *psEntry = psDebugFSEntry->psEntry;
+
+                       if (psEntry)
+                       {
+                               /* Free any private data that was provided to debugfs_create_file() */
+                               if (psEntry->d_inode->i_private != NULL)
+                               {
+                                       PVR_DEBUGFS_PRIV_DATA *psPrivData = (PVR_DEBUGFS_PRIV_DATA*)psDebugFSEntry->psEntry->d_inode->i_private;
+
+                                       psPrivData->bValid = IMG_FALSE;
+                                       psPrivData->psDebugFSEntry = NULL;
+                                       OSFreeMemstatMem(psEntry->d_inode->i_private);
+                               }
+                               debugfs_remove(psEntry);
+                       }
+                       /* decrement refcount of parent directory */
+                       if (psDebugFSEntry->psParentDir)
+                       {
+                               _UnrefAndMaybeDestroyDirEntryWhileLocked(psDebugFSEntry->psParentDir);
+                       }
+
+                       /* now free the memory allocated for psDebugFSEntry */
+                       OSFreeMemstatMem(psDebugFSEntry);
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to unref psDebugFSEntry '%s' when ui32RefCount is zero", __FUNCTION__, psDebugFSEntry->psEntry->d_iname));
+       }
+
+       mutex_unlock(&gDebugFSLock);
+}
+
+static IMG_BOOL _RefStatEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry)
+{
+       IMG_BOOL bResult = IMG_FALSE;
+
+       PVR_ASSERT(psStatEntry != NULL);
+
+       mutex_lock(&gDebugFSLock);
+
+       bResult = (psStatEntry->ui32RefCount > 0);
+       if (bResult)
+       {
+               /* Increment refCount of psStatEntry */
+               psStatEntry->ui32RefCount++;
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to ref psStatEntry '%s' when ui32RefCount is zero", __FUNCTION__, psStatEntry->pvDebugFSEntry->psEntry->d_iname));
+       }
+
+       mutex_unlock(&gDebugFSLock);
+
+       return bResult;
+}
+
+static IMG_BOOL _UnrefAndMaybeDestroyStatEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry)
+{
+       IMG_BOOL bResult;
+
+       PVR_ASSERT(psStatEntry != IMG_NULL);
+
+       mutex_lock(&gDebugFSLock);
+
+       bResult = (psStatEntry->ui32RefCount > 0);
+
+       if (bResult)
+       {
+               /* Decrement refCount of psStatData, and free if now zero */
+               if (--psStatEntry->ui32RefCount == 0)
+               {
+                       mutex_unlock(&gDebugFSLock);
+
+                       if (psStatEntry->pvDebugFSEntry)
+                       {
+                               _UnrefAndMaybeDestroyDebugFSEntry((PVR_DEBUGFS_ENTRY_DATA*)psStatEntry->pvDebugFSEntry);
+                       }
+                       if (psStatEntry->pfnDecStatMemRefCount)
+                       {
+                               /* call function to drop reference on the memory holding the stat */
+                               psStatEntry->pfnDecStatMemRefCount((void*)psStatEntry->pvData);
+                       }
+               }
+               else
+               {
+                       mutex_unlock(&gDebugFSLock);
+               }
+       }
+       else
+       {
+               PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called to unref psStatEntry '%s' when ui32RefCount is zero", __FUNCTION__, psStatEntry->pvDebugFSEntry->psEntry->d_iname));
+               mutex_unlock(&gDebugFSLock);
+       }
+
+       return bResult;
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.h b/drivers/gpu/rogue_m/services/server/env/linux/pvr_debugfs.h
new file mode 100644 (file)
index 0000000..8895e03
--- /dev/null
@@ -0,0 +1,91 @@
+/*************************************************************************/ /*!
+@File
+@Title          Functions for creating debugfs directories and entries.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__PVR_DEBUGFS_H__)
+#define __PVR_DEBUGFS_H__
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include "img_types.h"
+#include "osfunc.h"
+
+typedef ssize_t (PVRSRV_ENTRY_WRITE_FUNC)(const char __user *pszBuffer,
+                                         size_t uiCount,
+                                         loff_t uiPosition,
+                                         void *pvData);
+
+
+typedef IMG_UINT32 (PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC)(void *pvStatPtr);
+typedef IMG_UINT32 (PVRSRV_DEC_STAT_MEM_REFCOUNT_FUNC)(void *pvStatPtr);
+
+typedef struct _PVR_DEBUGFS_DIR_DATA_ PVR_DEBUGFS_DIR_DATA;
+typedef struct _PVR_DEBUGFS_ENTRY_DATA_ PVR_DEBUGFS_ENTRY_DATA;
+typedef struct _PVR_DEBUGFS_DRIVER_STAT_ PVR_DEBUGFS_DRIVER_STAT;
+
+int PVRDebugFSInit(void);
+void PVRDebugFSDeInit(void);
+
+int PVRDebugFSCreateEntryDir(IMG_CHAR *pszName,
+                                                        PVR_DEBUGFS_DIR_DATA *psParentDir,
+                                                        PVR_DEBUGFS_DIR_DATA **ppsNewDir);
+
+void PVRDebugFSRemoveEntryDir(PVR_DEBUGFS_DIR_DATA *psDir);
+
+int PVRDebugFSCreateEntry(const char *pszName,
+                                                 PVR_DEBUGFS_DIR_DATA *psParentDir,
+                                                 struct seq_operations *psReadOps,
+                                                 PVRSRV_ENTRY_WRITE_FUNC *pfnWrite,
+                                                 void *pvData,
+                                                 PVR_DEBUGFS_ENTRY_DATA **ppsNewEntry);
+
+void PVRDebugFSRemoveEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry);
+
+PVR_DEBUGFS_DRIVER_STAT *PVRDebugFSCreateStatisticEntry(const char *pszName,
+                                                                                                               PVR_DEBUGFS_DIR_DATA *psDir,
+                                                                                                               OS_STATS_PRINT_FUNC *pfnStatsPrint,
+                                                                                                               PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnIncStatMemRefCount,
+                                                                                                               PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnDecStatMemRefCount,
+                                                                                                               void *pvData);
+void PVRDebugFSRemoveStatisticEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry);
+
+#endif /* !defined(__PVR_DEBUGFS_H__) */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.c b/drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.c
new file mode 100644 (file)
index 0000000..3f14769
--- /dev/null
@@ -0,0 +1,414 @@
+/*************************************************************************/ /*!
+@File           pvr_gputrace.c
+@Title          PVR GPU Trace module Linux implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_error.h"
+#include "srvkm.h"
+#include "pvr_debug.h"
+#include "pvr_debugfs.h"
+#include "pvr_uaccess.h"
+
+#include "pvr_gputrace.h"
+
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/gpu.h>
+
+#define KM_FTRACE_NO_PRIORITY (0)
+
+
+/******************************************************************************
+ Module internal implementation
+******************************************************************************/
+
+/* Circular buffer sizes, must be a power of two */
+#define PVRSRV_KM_FTRACE_JOB_MAX       (512)
+#define PVRSRV_KM_FTRACE_CTX_MAX        (16)
+
+#define PVRSRV_FTRACE_JOB_FLAG_MASK     (0xFF000000)
+#define PVRSRV_FTRACE_JOB_ID_MASK       (0x00FFFFFF)
+#define PVRSRV_FTRACE_JOB_FLAG_ENQUEUED (0x80000000)
+
+#define PVRSRV_FTRACE_JOB_GET_ID(pa)               ((pa)->ui32FlagsAndID & PVRSRV_FTRACE_JOB_ID_MASK)
+#define PVRSRV_FTRACE_JOB_SET_ID_CLR_FLAGS(pa, id) ((pa)->ui32FlagsAndID = PVRSRV_FTRACE_JOB_ID_MASK & (id))
+
+#define PVRSRV_FTRACE_JOB_GET_FLAGS(pa)     ((pa)->ui32FlagsAndID & PVRSRV_FTRACE_JOB_FLAG_MASK)
+#define PVRSRV_FTRACE_JOB_SET_FLAGS(pa, fl) ((pa)->ui32FlagsAndID |= PVRSRV_FTRACE_JOB_FLAG_MASK & (fl))
+
+typedef struct _PVRSRV_FTRACE_JOB_
+{
+       /* Job ID calculated, no need to store it. */
+       IMG_UINT32 ui32FlagsAndID;
+       IMG_UINT32 ui32ExtJobRef;
+       IMG_UINT32 ui32IntJobRef;
+} PVRSRV_FTRACE_GPU_JOB;
+
+
+typedef struct _PVRSRV_FTRACE_GPU_CTX_
+{
+       /* Context ID is calculated, no need to store it IMG_UINT32 ui32CtxID; */
+       IMG_UINT32            ui32PID;
+
+       /* Every context has a circular buffer of jobs */
+       IMG_UINT16            ui16JobWrite;             /*!< Next position to write to */
+       PVRSRV_FTRACE_GPU_JOB asJobs[PVRSRV_KM_FTRACE_JOB_MAX];
+} PVRSRV_FTRACE_GPU_CTX;
+
+
+typedef struct _PVRSRV_FTRACE_GPU_DATA_
+{
+       IMG_UINT16 ui16CtxWrite;                                /*!< Next position to write to */
+       PVRSRV_FTRACE_GPU_CTX asFTraceContext[PVRSRV_KM_FTRACE_CTX_MAX];
+} PVRSRV_FTRACE_GPU_DATA;
+
+PVRSRV_FTRACE_GPU_DATA gsFTraceGPUData;
+
+static void CreateJob(IMG_UINT32 ui32PID, IMG_UINT32 ui32ExtJobRef,
+               IMG_UINT32 ui32IntJobRef)
+{
+       PVRSRV_FTRACE_GPU_CTX* psContext = IMG_NULL;
+       PVRSRV_FTRACE_GPU_JOB* psJob = IMG_NULL;
+       IMG_UINT32 i;
+
+       /* Search for a previously created CTX object */
+       for (i = 0; i < PVRSRV_KM_FTRACE_CTX_MAX; ++i)
+       {
+               if(gsFTraceGPUData.asFTraceContext[i].ui32PID == ui32PID)
+               {
+                       psContext = &(gsFTraceGPUData.asFTraceContext[i]);
+                       break;
+               } /* */
+       }
+
+       /* If not present in the CB history, create it */
+       if (psContext == NULL)
+       {
+               /*
+                 We overwrite old contexts as we don't get a "finished" indication
+                 so we assume PVRSRV_KM_FTRACE_CTX_MAX is a sufficient number of
+                 process contexts in use at any one time.
+               */
+               i = gsFTraceGPUData.ui16CtxWrite;
+
+               gsFTraceGPUData.asFTraceContext[i].ui32PID = ui32PID;
+               gsFTraceGPUData.asFTraceContext[i].ui16JobWrite = 0;
+               psContext = &(gsFTraceGPUData.asFTraceContext[i]);
+
+               /* Advance the write position of the context CB. */
+               gsFTraceGPUData.ui16CtxWrite = (i+1) & (PVRSRV_KM_FTRACE_CTX_MAX-1);
+       }
+
+       /*
+         This is just done during the first kick so it is assumed the job is not
+         in the CB of jobs yet so we create it. Clear flags.
+       */
+       psJob = &(psContext->asJobs[psContext->ui16JobWrite]);
+       PVRSRV_FTRACE_JOB_SET_ID_CLR_FLAGS(psJob, 1001+psContext->ui16JobWrite);
+       psJob->ui32ExtJobRef = ui32ExtJobRef;
+       psJob->ui32IntJobRef = ui32IntJobRef;
+
+       /*
+         Advance the write position of the job CB. Overwrite oldest job
+         when buffer overflows
+       */
+       psContext->ui16JobWrite = (psContext->ui16JobWrite + 1) & (PVRSRV_KM_FTRACE_JOB_MAX-1);
+}
+
+
+static PVRSRV_ERROR GetCtxAndJobID(IMG_UINT32 ui32PID,
+       IMG_UINT32 ui32ExtJobRef, IMG_UINT32 ui32IntJobRef,
+       IMG_UINT32 *pui32CtxID, PVRSRV_FTRACE_GPU_JOB** ppsJob)
+{
+       PVRSRV_FTRACE_GPU_CTX* psContext = IMG_NULL;
+       IMG_UINT32 i;
+
+       /* Search for the process context object in the CB */
+       for (i = 0; i < PVRSRV_KM_FTRACE_CTX_MAX; ++i)
+       {
+               if(gsFTraceGPUData.asFTraceContext[i].ui32PID == ui32PID)
+               {
+                       psContext = &(gsFTraceGPUData.asFTraceContext[i]);
+                       /* Derive context ID from CB index: 101..101+PVRSRV_KM_FTRACE_CTX_MAX */
+                       *pui32CtxID = 101+i;
+                       break;
+               }
+       }
+
+       /* If not found, return an error, let caller trace the error */
+       if (psContext == NULL)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE,"GetCtxAndJobID: Failed to find context ID for PID %d", ui32PID));
+               return PVRSRV_ERROR_PROCESS_NOT_FOUND;
+       }
+
+       /* Look for the JobID in the jobs CB */
+       for(i = 0; i < PVRSRV_KM_FTRACE_JOB_MAX; ++i)
+       {
+               if((psContext->asJobs[i].ui32ExtJobRef == ui32ExtJobRef) &&
+                       (psContext->asJobs[i].ui32IntJobRef == ui32IntJobRef))
+               {
+                       /* Derive job ID from CB index: 1001..1001+PVRSRV_KM_FTRACE_JOB_MAX */
+                       *ppsJob = &psContext->asJobs[i];
+                       return PVRSRV_OK;
+               }
+       }
+
+       PVR_DPF((PVR_DBG_MESSAGE,"GetCtxAndJobID: Failed to find job ID for extJobRef %d, intJobRef %x", ui32ExtJobRef, ui32IntJobRef));
+       return PVRSRV_ERROR_NOT_FOUND;
+}
+
+
+/* DebugFS entry for the feature's on/off file */
+static PVR_DEBUGFS_ENTRY_DATA *gpsPVRDebugFSGpuTracingOnEntry = NULL;
+
+
+/*
+  If SUPPORT_GPUTRACE_EVENTS is defined the drive is built with support
+  to route RGX HWPerf packets to the Linux FTrace mechanism. To allow
+  this routing feature to be switched on and off at run-time the following
+  debugfs entry is created:
+       /sys/kernel/debug/pvr/gpu_tracing_on
+  To enable GPU events in the FTrace log type the following on the target:
+       echo Y > /sys/kernel/debug/pvr/gpu_tracing_on
+  To disable, type:
+       echo N > /sys/kernel/debug/pvr/gpu_tracing_on
+
+  It is also possible to enable this feature at driver load by setting the
+  default application hint "EnableFTraceGPU=1" in /etc/powervr.ini.
+*/
+
+static void *GpuTracingSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
+{
+       if (*puiPosition == 0)
+       {
+               /* We want only one entry in the sequence, one call to show() */
+               return (void*)1;
+       }
+
+       return NULL;
+}
+
+
+static void GpuTracingSeqStop(struct seq_file *psSeqFile, void *pvData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+}
+
+
+static void *GpuTracingSeqNext(struct seq_file *psSeqFile, void *pvData, loff_t *puiPosition)
+{
+       PVR_UNREFERENCED_PARAMETER(psSeqFile);
+       return NULL;
+}
+
+
+static int GpuTracingSeqShow(struct seq_file *psSeqFile, void *pvData)
+{
+       IMG_BOOL bValue = PVRGpuTraceEnabled();
+
+       PVR_UNREFERENCED_PARAMETER(pvData);
+
+       seq_puts(psSeqFile, (bValue ? "Y\n" : "N\n"));
+       return 0;
+}
+
+
+static struct seq_operations gsGpuTracingReadOps =
+{
+       .start = GpuTracingSeqStart,
+       .stop  = GpuTracingSeqStop,
+       .next  = GpuTracingSeqNext,
+       .show  = GpuTracingSeqShow,
+};
+
+
+static IMG_INT GpuTracingSet(const IMG_CHAR *buffer, size_t count, loff_t uiPosition, void *data)
+{
+       IMG_CHAR cFirstChar;
+
+       PVR_UNREFERENCED_PARAMETER(uiPosition);
+       PVR_UNREFERENCED_PARAMETER(data);
+
+       if (!count)
+       {
+               return -EINVAL;
+       }
+
+       if (pvr_copy_from_user(&cFirstChar, buffer, 1))
+       {
+               return -EFAULT;
+       }
+
+       switch (cFirstChar)
+       {
+               case '0':
+               case 'n':
+               case 'N':
+               {
+                       PVRGpuTraceEnabledSet(IMG_FALSE);
+                       PVR_TRACE(("DISABLED GPU FTrace"));
+                       break;
+               }
+               case '1':
+               case 'y':
+               case 'Y':
+               {
+            if (PVRGpuTraceEnabledSet(IMG_TRUE) == PVRSRV_OK)
+            {
+                PVR_TRACE(("ENABLED GPU FTrace"));
+            }
+            else
+            {
+                PVR_TRACE(("FAILED to enable GPU FTrace"));
+            }
+                       break;
+               }
+       }
+
+       return count;
+}
+
+
+/******************************************************************************
+ Module In-bound API
+******************************************************************************/
+
+
+void PVRGpuTraceClientWork(
+               const IMG_UINT32 ui32Pid,
+               const IMG_UINT32 ui32ExtJobRef,
+               const IMG_UINT32 ui32IntJobRef,
+               const IMG_CHAR* pszKickType)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVRSRV_FTRACE_GPU_JOB* psJob;
+       IMG_UINT32   ui32CtxId = 0;
+
+       PVR_ASSERT(pszKickType);
+
+       PVR_DPF((PVR_DBG_VERBOSE, "PVRGpuTraceClientKick(%s): PID %u, extJobRef %u, intJobRef %u", pszKickType, ui32Pid, ui32ExtJobRef, ui32IntJobRef));
+
+       CreateJob(ui32Pid, ui32ExtJobRef, ui32IntJobRef);
+
+       /*
+         Always create jobs for client work above but only emit the enqueue
+         trace if the feature is enabled.
+         This keeps the lookup tables up to date when the gpu_tracing_on is
+         disabled so that when it is re-enabled the packets that might be in
+         the HWPerf buffer can be decoded in the switch event processing below.
+       */
+       if (PVRGpuTraceEnabled())
+       {
+               eError = GetCtxAndJobID(ui32Pid, ui32ExtJobRef, ui32IntJobRef, &ui32CtxId,  &psJob);
+               PVR_LOGRN_IF_ERROR(eError, "GetCtxAndJobID");
+
+               trace_gpu_job_enqueue(ui32CtxId, PVRSRV_FTRACE_JOB_GET_ID(psJob), pszKickType);
+
+               PVRSRV_FTRACE_JOB_SET_FLAGS(psJob, PVRSRV_FTRACE_JOB_FLAG_ENQUEUED);
+       }
+}
+
+
+void PVRGpuTraceWorkSwitch(
+               IMG_UINT64 ui64HWTimestampInOSTime,
+               const IMG_UINT32 ui32Pid,
+               const IMG_UINT32 ui32ExtJobRef,
+               const IMG_UINT32 ui32IntJobRef,
+               const IMG_CHAR* pszWorkType,
+               PVR_GPUTRACE_SWITCH_TYPE eSwType)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+    PVRSRV_FTRACE_GPU_JOB* psJob = IMG_NULL;
+       IMG_UINT32 ui32CtxId;
+
+       PVR_ASSERT(pszWorkType);
+
+       eError = GetCtxAndJobID(ui32Pid, ui32ExtJobRef, ui32IntJobRef,  &ui32CtxId,  &psJob);
+       PVR_LOGRN_IF_ERROR(eError, "GetCtxAndJobID");
+
+       PVR_ASSERT(psJob);
+
+    /*
+      Only trace switch event if the job's enqueue event was traced. Necessary
+         for when the GPU tracing is disabled, apps run and re-enabled to avoid
+         orphan switch events from appearing in the trace file.
+       */
+       if (PVRSRV_FTRACE_JOB_GET_FLAGS(psJob) & PVRSRV_FTRACE_JOB_FLAG_ENQUEUED)
+       {
+               if (eSwType == PVR_GPUTRACE_SWITCH_TYPE_END)
+               {
+                       /* When the GPU goes idle, we need to trace a switch with a context
+                        * ID of 0.
+                        */
+                       ui32CtxId = 0;
+               }
+
+               trace_gpu_sched_switch(pszWorkType, ui64HWTimestampInOSTime,
+                               ui32CtxId, KM_FTRACE_NO_PRIORITY, PVRSRV_FTRACE_JOB_GET_ID(psJob));
+       }
+}
+
+
+PVRSRV_ERROR PVRGpuTraceInit(void)
+{
+       return PVRDebugFSCreateEntry("gpu_tracing_on",
+                                     NULL,
+                                     &gsGpuTracingReadOps,
+                                     (PVRSRV_ENTRY_WRITE_FUNC *)GpuTracingSet,
+                                     NULL,
+                                     &gpsPVRDebugFSGpuTracingOnEntry);
+}
+
+
+void PVRGpuTraceDeInit(void)
+{
+       /* Can be NULL if driver startup failed */
+       if (gpsPVRDebugFSGpuTracingOnEntry)
+       {
+               PVRDebugFSRemoveEntry(gpsPVRDebugFSGpuTracingOnEntry);
+               gpsPVRDebugFSGpuTracingOnEntry = NULL;
+       }
+}
+
+
+/******************************************************************************
+ End of file (pvr_gputrace.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.h b/drivers/gpu/rogue_m/services/server/env/linux/pvr_gputrace.h
new file mode 100644 (file)
index 0000000..e4f21ee
--- /dev/null
@@ -0,0 +1,96 @@
+/*************************************************************************/ /*!
+@File           pvr_gputrace.h
+@Title          PVR GPU Trace module common environment interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_GPUTRACE_H_
+#define PVR_GPUTRACE_H_
+
+#include "img_types.h"
+
+
+/******************************************************************************
+ Module out-bound API
+******************************************************************************/
+
+/*
+  The device layer of the KM driver defines these two APIs to allow a
+  platform module to set and retrieve the feature's on/off state.
+*/
+extern PVRSRV_ERROR PVRGpuTraceEnabledSet(IMG_BOOL bNewValue);
+extern IMG_BOOL PVRGpuTraceEnabled(void);
+
+
+/******************************************************************************
+ Module In-bound API
+******************************************************************************/
+
+typedef enum {
+       PVR_GPUTRACE_SWITCH_TYPE_UNDEF = 0,
+
+       PVR_GPUTRACE_SWITCH_TYPE_BEGIN = 1,
+       PVR_GPUTRACE_SWITCH_TYPE_END = 2
+
+} PVR_GPUTRACE_SWITCH_TYPE;
+
+
+void PVRGpuTraceClientWork(
+               const IMG_UINT32 ui32Pid,
+               const IMG_UINT32 ui32ExtJobRef,
+               const IMG_UINT32 ui32IntJobRef,
+               const IMG_CHAR* pszKickType);
+
+
+void PVRGpuTraceWorkSwitch(
+               IMG_UINT64 ui64OSTimestamp,
+               const IMG_UINT32 ui32Pid,
+               const IMG_UINT32 ui32ExtJobRef,
+               const IMG_UINT32 ui32IntJobRef,
+               const IMG_CHAR* pszWorkType,
+               PVR_GPUTRACE_SWITCH_TYPE eSwType);
+
+
+PVRSRV_ERROR PVRGpuTraceInit(void);
+
+
+void PVRGpuTraceDeInit(void);
+
+
+#endif /* PVR_GPUTRACE_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/pvr_uaccess.h b/drivers/gpu/rogue_m/services/server/env/linux/pvr_uaccess.h
new file mode 100644 (file)
index 0000000..53c8f0a
--- /dev/null
@@ -0,0 +1,106 @@
+/*************************************************************************/ /*!
+@File
+@Title          Utility functions for user space access
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __PVR_UACCESS_H__
+#define __PVR_UACCESS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/uaccess.h>
+
+static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+    if (access_ok(VERIFY_WRITE, pvTo, ulBytes))
+    {
+       return __copy_to_user(pvTo, pvFrom, ulBytes);
+    }
+    return ulBytes;
+#else
+    return copy_to_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+
+
+#if defined(__KLOCWORK__)
+       /* this part is only to tell Klocwork not to report false positive because
+          it doesn't understand that pvr_copy_from_user will initialise the memory
+          pointed to by pvTo */
+#include <linux/string.h> /* get the memset prototype */
+static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes)
+{
+       if (pvTo != NULL)
+       {
+               memset(pvTo, 0xAA, ulBytes);
+               return 0;
+       }
+       return 1;
+}
+       
+#else /* real implementation */
+
+static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes)
+{
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+    /*
+     * The compile time correctness checking introduced for copy_from_user in
+     * Linux 2.6.33 isn't fully compatible with our usage of the function.
+     */
+    if (access_ok(VERIFY_READ, pvFrom, ulBytes))
+    {
+       return __copy_from_user(pvTo, pvFrom, ulBytes);
+    }
+    return ulBytes;
+#else
+    return copy_from_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+#endif /* klocworks */ 
+
+#endif /* __PVR_UACCESS_H__ */
+
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/rogue_trace_events.h b/drivers/gpu/rogue_m/services/server/env/linux/rogue_trace_events.h
new file mode 100644 (file)
index 0000000..be3a9fa
--- /dev/null
@@ -0,0 +1,158 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rogue
+
+#if !defined(_ROGUE_TRACE_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _ROGUE_TRACE_EVENTS_H
+
+#include <linux/tracepoint.h>
+#include <linux/time.h>
+
+TRACE_EVENT(rogue_fence_update,
+
+       TP_PROTO(const char *comm, const char *cmd, const char *dm, u32 fw_ctx, u32 offset,
+               u32 sync_fwaddr, u32 sync_value),
+
+       TP_ARGS(comm, cmd, dm, fw_ctx, offset, sync_fwaddr, sync_value),
+
+       TP_STRUCT__entry(
+               __string(       comm,           comm            )
+               __string(       cmd,            cmd             )
+               __string(       dm,             dm              )
+               __field(        u32,            fw_ctx          )
+               __field(        u32,            offset          )
+               __field(        u32,            sync_fwaddr     )
+               __field(        u32,            sync_value      )
+       ),
+
+       TP_fast_assign(
+               __assign_str(comm, comm);
+               __assign_str(cmd, cmd);
+               __assign_str(dm, dm);
+               __entry->fw_ctx = fw_ctx;
+               __entry->offset = offset;
+               __entry->sync_fwaddr = sync_fwaddr;
+               __entry->sync_value = sync_value;
+       ),
+
+       TP_printk("comm=%s cmd=%s dm=%s fw_ctx=%lx offset=%lu sync_fwaddr=%lx sync_value=%lx",
+               __get_str(comm),
+               __get_str(cmd),
+               __get_str(dm),
+               (unsigned long)__entry->fw_ctx,
+               (unsigned long)__entry->offset,
+               (unsigned long)__entry->sync_fwaddr,
+               (unsigned long)__entry->sync_value)
+);
+
+TRACE_EVENT(rogue_fence_check,
+
+       TP_PROTO(const char *comm, const char *cmd, const char *dm, u32 fw_ctx, u32 offset,
+               u32 sync_fwaddr, u32 sync_value),
+
+       TP_ARGS(comm, cmd, dm, fw_ctx, offset, sync_fwaddr, sync_value),
+
+       TP_STRUCT__entry(
+               __string(       comm,           comm            )
+               __string(       cmd,            cmd             )
+               __string(       dm,             dm              )
+               __field(        u32,            fw_ctx          )
+               __field(        u32,            offset          )
+               __field(        u32,            sync_fwaddr     )
+               __field(        u32,            sync_value      )
+       ),
+
+       TP_fast_assign(
+               __assign_str(comm, comm);
+               __assign_str(cmd, cmd);
+               __assign_str(dm, dm);
+               __entry->fw_ctx = fw_ctx;
+               __entry->offset = offset;
+               __entry->sync_fwaddr = sync_fwaddr;
+               __entry->sync_value = sync_value;
+       ),
+
+       TP_printk("comm=%s cmd=%s dm=%s fw_ctx=%lx offset=%lu sync_fwaddr=%lx sync_value=%lx",
+               __get_str(comm),
+               __get_str(cmd),
+               __get_str(dm),
+               (unsigned long)__entry->fw_ctx,
+               (unsigned long)__entry->offset,
+               (unsigned long)__entry->sync_fwaddr,
+               (unsigned long)__entry->sync_value)
+);
+
+TRACE_EVENT(rogue_create_fw_context,
+
+       TP_PROTO(const char *comm, const char *dm, u32 fw_ctx),
+
+       TP_ARGS(comm, dm, fw_ctx),
+
+       TP_STRUCT__entry(
+               __string(       comm,           comm            )
+               __string(       dm,             dm              )
+               __field(        u32,            fw_ctx          )
+       ),
+
+       TP_fast_assign(
+               __assign_str(comm, comm);
+               __assign_str(dm, dm);
+               __entry->fw_ctx = fw_ctx;
+       ),
+
+       TP_printk("comm=%s dm=%s fw_ctx=%lx",
+               __get_str(comm),
+               __get_str(dm),
+               (unsigned long)__entry->fw_ctx)
+);
+
+#endif /* _ROGUE_TRACE_EVENTS_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+
+/* This is needed because the name of this file doesn't match TRACE_SYSTEM. */
+#define TRACE_INCLUDE_FILE rogue_trace_events
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/trace_events.c b/drivers/gpu/rogue_m/services/server/env/linux/trace_events.c
new file mode 100644 (file)
index 0000000..ca4152b
--- /dev/null
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@Title          Linux trace event helper functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/sched.h>
+
+#include "img_types.h"
+#include "rgx_fwif_km.h"
+
+#define CREATE_TRACE_POINTS
+#include "trace_events.h"
+
+/* This is a helper that calls trace_rogue_fence_update for each fence in an
+ * array.
+ */
+void trace_rogue_fence_updates(const char *cmd, const char *dm, IMG_UINT32 ui32FWContext,
+                                                          IMG_UINT32 ui32Offset,
+                                                          IMG_UINT uCount,
+                                                          PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                          IMG_UINT32 *paui32Values)
+{
+       IMG_UINT i;
+       for (i = 0; i < uCount; i++)
+       {
+               trace_rogue_fence_update(current->comm, cmd, dm, ui32FWContext, ui32Offset,
+                                                                pauiAddresses[i].ui32Addr, paui32Values[i]);
+       }
+}
+
+void trace_rogue_fence_checks(const char *cmd, const char *dm, IMG_UINT32 ui32FWContext,
+                                                         IMG_UINT32 ui32Offset,
+                                                         IMG_UINT uCount,
+                                                         PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                         IMG_UINT32 *paui32Values)
+{
+       IMG_UINT i;
+       for (i = 0; i < uCount; i++)
+       {
+               trace_rogue_fence_check(current->comm, cmd, dm, ui32FWContext, ui32Offset,
+                                                         pauiAddresses[i].ui32Addr, paui32Values[i]);
+       }
+}
diff --git a/drivers/gpu/rogue_m/services/server/env/linux/trace_events.h b/drivers/gpu/rogue_m/services/server/env/linux/trace_events.h
new file mode 100644 (file)
index 0000000..7fe1a2b
--- /dev/null
@@ -0,0 +1,87 @@
+/*************************************************************************/ /*!
+@Title          Linux trace events and event helper functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(TRACE_EVENTS_H)
+#define TRACE_EVENTS_H
+
+#include "rogue_trace_events.h"
+
+/* We need to make these functions do nothing if CONFIG_EVENT_TRACING isn't
+ * enabled, just like the actual trace event functions that the kernel
+ * defines for us.
+ */
+#ifdef CONFIG_EVENT_TRACING
+void trace_rogue_fence_updates(const char *cmd, const char *dm,
+                                                          IMG_UINT32 ui32FWContext,
+                                                          IMG_UINT32 ui32Offset,
+                                                          IMG_UINT uCount,
+                                                          PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                          IMG_UINT32 *paui32Values);
+
+void trace_rogue_fence_checks(const char *cmd, const char *dm,
+                                                         IMG_UINT32 ui32FWContext,
+                                                         IMG_UINT32 ui32Offset,
+                                                         IMG_UINT uCount,
+                                                         PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                         IMG_UINT32 *paui32Values);
+#else  /* CONFIG_TRACE_EVENTS */
+static inline
+void trace_rogue_fence_updates(const char *cmd, const char *dm,
+                                                          IMG_UINT32 ui32FWContext,
+                                                          IMG_UINT32 ui32Offset,
+                                                          IMG_UINT uCount,
+                                                          PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                          IMG_UINT32 *paui32Values)
+{
+}
+
+static inline
+void trace_rogue_fence_checks(const char *cmd, const char *dm,
+                                                         IMG_UINT32 ui32FWContext,
+                                                         IMG_UINT32 ui32Offset,
+                                                         IMG_UINT uCount,
+                                                         PRGXFWIF_UFO_ADDR *pauiAddresses,
+                                                         IMG_UINT32 *paui32Values)
+{
+}
+#endif /* CONFIG_TRACE_EVENTS */
+
+#endif /* TRACE_EVENTS_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/cache_generic.h b/drivers/gpu/rogue_m/services/server/include/cache_generic.h
new file mode 100644 (file)
index 0000000..07ec973
--- /dev/null
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _CACHE_GENERIC_H_
+#define _CACHE_GENERIC_H_
+
+#include "img_types.h"
+#include "cache_external.h"
+#include "device.h"
+#include "pvrsrv_error.h"
+
+PVRSRV_ERROR CacheOpQueue(PVRSRV_CACHE_OP uiCacheOp);
+
+#endif /* _CACHE_GENERIC_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/connection_server.h b/drivers/gpu/rogue_m/services/server/include/connection_server.h
new file mode 100644 (file)
index 0000000..34dc5a3
--- /dev/null
@@ -0,0 +1,107 @@
+/**************************************************************************/ /*!
+@File
+@Title          Server side connection management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    API for server side connection management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(_CONNECTION_SERVER_H_)
+#define _CONNECTION_SERVER_H_
+
+
+#include "img_types.h"
+#include "handle.h"
+#include "pvrsrv_cleanup.h"
+
+/* Variable used to hold in memory the timeout for the current time slice*/
+extern IMG_UINT64 gui64TimesliceLimit;
+/* Counter number of handle data freed during the current time slice */
+extern IMG_UINT32 gui32HandleDataFreeCounter;
+/* Set the maximum time the freeing of the resources can keep the lock */
+#define CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS 3000 * 1000 /* 3ms */
+
+typedef struct _CONNECTION_DATA_
+{
+       PVRSRV_HANDLE_BASE              *psHandleBase;
+       struct _SYNC_CONNECTION_DATA_   *psSyncConnectionData;
+       struct _PDUMP_CONNECTION_DATA_  *psPDumpConnectionData;
+
+       /* Holds the client flags supplied at connection time */
+       IMG_UINT32                      ui32ClientFlags;
+
+       /*
+        * OS specific data can be stored via this handle.
+        * See osconnection_server.h for a generic mechanism
+        * for initialising this field.
+        */
+       IMG_HANDLE                      hOsPrivateData;
+
+       IMG_PID                         pid;
+
+       IMG_PVOID                       hSecureData;
+
+       IMG_HANDLE                      hProcessStats;
+
+       /* Structure which is hooked into the cleanup thread work list */
+       PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn;
+
+       /* List navigation for deferred freeing of connection data */
+       struct _CONNECTION_DATA_        **ppsThis;
+       struct _CONNECTION_DATA_        *psNext;
+} CONNECTION_DATA;
+
+PVRSRV_ERROR PVRSRVConnectionConnect(IMG_PVOID *ppvPrivData, IMG_PVOID pvOSData);
+void PVRSRVConnectionDisconnect(IMG_PVOID pvPrivData);
+
+PVRSRV_ERROR PVRSRVConnectionInit(void);
+PVRSRV_ERROR PVRSRVConnectionDeInit(void);
+
+IMG_PID PVRSRVGetPurgeConnectionPid(void);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVConnectionPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVConnectionPrivateData(CONNECTION_DATA *psConnection)
+{
+       return (psConnection != IMG_NULL) ? psConnection->hOsPrivateData : IMG_NULL;
+}
+
+
+#endif /* !defined(_CONNECTION_SERVER_H_) */
diff --git a/drivers/gpu/rogue_m/services/server/include/debug_request_ids.h b/drivers/gpu/rogue_m/services/server/include/debug_request_ids.h
new file mode 100644 (file)
index 0000000..6258c56
--- /dev/null
@@ -0,0 +1,55 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug requester ID's
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header contains the defines for the debug ID's for all the
+                               services components
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __DEBUG_REQUEST_IDS__
+#define __DEBUG_REQUEST_IDS__
+
+/* Services controlled devices should be 1st */
+#define DEBUG_REQUEST_RGX                      (0)
+#define DEBUG_REQUEST_DC                       (1)
+#define DEBUG_REQUEST_SERVERSYNC       (2)
+#define DEBUG_REQUEST_SYS           (3)
+#define DEBUG_REQUEST_ANDROIDSYNC   (4)
+
+#endif /* __DEBUG_REQUEST_IDS__ */
diff --git a/drivers/gpu/rogue_m/services/server/include/device.h b/drivers/gpu/rogue_m/services/server/include/device.h
new file mode 100644 (file)
index 0000000..cf437b3
--- /dev/null
@@ -0,0 +1,301 @@
+/**************************************************************************/ /*!
+@File
+@Title          Common Device header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device related function templates and defines
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+
+#include "devicemem_heapcfg.h"
+#include "mmu_common.h"        
+#include "ra.h"                /* RA_ARENA */
+#include "pvrsrv_device.h"
+#include "srvkm.h"
+#include "devicemem.h"
+#include "physheap.h"
+#include "sync.h"
+#include "dllist.h"
+#include "cache_external.h"
+
+#include "lock.h"
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "services.h"
+#endif
+
+/* BM context forward reference */
+typedef struct _BM_CONTEXT_ BM_CONTEXT;
+
+/*********************************************************************/ /*!
+ @Function      AllocUFOCallback
+ @Description   Device specific callback for allocation of an UFO block
+
+ @Input         psDeviceNode          Pointer to device node to allocate
+                                      the UFO for.
+ @Output        ppsMemDesc            Pointer to pointer for the memdesc of
+                                      the allocation
+ @Output        pui32SyncAddr         FW Base address of the UFO block
+ @Output        puiSyncPrimBlockSize  Size of the UFO block
+
+ @Return        PVRSRV_OK if allocation was successful
+ */
+/*********************************************************************/
+typedef PVRSRV_ERROR (*AllocUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+                                                                                                               DEVMEM_MEMDESC **ppsMemDesc,
+                                                                                                               IMG_UINT32 *pui32SyncAddr,
+                                                                                                               IMG_UINT32 *puiSyncPrimBlockSize);
+
+/*********************************************************************/ /*!
+ @Function      FreeUFOCallback
+ @Description   Device specific callback for freeing of an UFO
+
+ @Input         psDeviceNode    Pointer to device node that the UFO block was
+                                allocated from.
+ @Input         psMemDesc       Pointer to pointer for the memdesc of
+                                the UFO block to free.
+ */
+/*********************************************************************/
+typedef IMG_VOID (*FreeUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+                                                                                DEVMEM_MEMDESC *psMemDesc);
+
+
+typedef struct _DEVICE_MEMORY_INFO_
+{
+       /* size of address space, as log2 */
+       IMG_UINT32                              ui32AddressSpaceSizeLog2;
+
+       /* 
+               flags, includes physical memory resource types available to the system.  
+               Allows for validation at heap creation, define PVRSRV_BACKINGSTORE_XXX 
+       */
+       IMG_UINT32                              ui32Flags;
+
+       /* heap count.  Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */
+       IMG_UINT32                              ui32HeapCount;
+
+       /* BM kernel context for the device */
+    BM_CONTEXT                         *pBMKernelContext;
+
+       /* BM context list for the device*/
+    BM_CONTEXT                         *pBMContext;
+
+    /* Blueprints for creating new device memory contexts */
+    IMG_UINT32              uiNumHeapConfigs;
+    DEVMEM_HEAP_CONFIG      *psDeviceMemoryHeapConfigArray;
+    DEVMEM_HEAP_BLUEPRINT   *psDeviceMemoryHeap;
+} DEVICE_MEMORY_INFO;
+
+
+typedef struct _Px_HANDLE_
+{
+       union
+       {
+               IMG_VOID *pvHandle;
+               IMG_UINT64 ui64Handle;
+       }u;
+} Px_HANDLE;
+
+typedef enum _PVRSRV_DEVICE_STATE_
+{
+       PVRSRV_DEVICE_STATE_UNDEFINED = 0,
+       PVRSRV_DEVICE_STATE_INIT,
+       PVRSRV_DEVICE_STATE_ACTIVE,
+       PVRSRV_DEVICE_STATE_DEINIT,
+} PVRSRV_DEVICE_STATE;
+
+typedef enum _PVRSRV_DEVICE_HEALTH_STATUS_
+{
+       PVRSRV_DEVICE_HEALTH_STATUS_OK = 0,
+       PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING,
+       PVRSRV_DEVICE_HEALTH_STATUS_DEAD
+} PVRSRV_DEVICE_HEALTH_STATUS;
+
+typedef enum _PVRSRV_DEVICE_HEALTH_REASON_
+{
+       PVRSRV_DEVICE_HEALTH_REASON_NONE = 0,
+       PVRSRV_DEVICE_HEALTH_REASON_ASSERTED,
+       PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING,
+       PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS,
+       PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT,
+       PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED
+} PVRSRV_DEVICE_HEALTH_REASON;
+
+typedef PVRSRV_ERROR (*FN_CREATERAMBACKEDPMR)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                                               IMG_DEVMEM_SIZE_T uiSize,
+                                                                               IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                                               IMG_UINT32 ui32NumPhysChunks,
+                                                                               IMG_UINT32 ui32NumVirtChunks,
+                                                                               IMG_BOOL *pabMappingTable,
+                                                                               IMG_UINT32 uiLog2PageSize,
+                                                                               PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                                               PMR **ppsPMRPtr);
+typedef struct _PVRSRV_DEVICE_NODE_
+{
+       PVRSRV_DEVICE_IDENTIFIER        sDevId;
+
+       PVRSRV_DEVICE_STATE                     eDevState;
+       PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus;
+       PVRSRV_DEVICE_HEALTH_REASON eHealthReason;
+
+       /* device specific MMU attributes */
+    MMU_DEVICEATTRIBS      *psMMUDevAttrs;
+
+       /*
+               callbacks the device must support:
+       */
+
+    FN_CREATERAMBACKEDPMR pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_LAST];
+
+    PVRSRV_ERROR (*pfnMMUPxAlloc)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_SIZE_T uiSize,
+                                                                       Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr);
+
+    IMG_VOID (*pfnMMUPxFree)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, Px_HANDLE *psMemHandle);
+
+       PVRSRV_ERROR (*pfnMMUPxMap)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, Px_HANDLE *pshMemHandle,
+                                                               IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+                                                               IMG_VOID **pvPtr);
+
+       IMG_VOID (*pfnMMUPxUnmap)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                               Px_HANDLE *psMemHandle, IMG_VOID *pvPtr);
+
+       IMG_UINT32 uiMMUPxLog2AllocGran;
+       IMG_CHAR                                *pszMMUPxPDumpMemSpaceName;
+
+       IMG_VOID (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                                               IMG_HANDLE hDeviceData,
+                                                                               MMU_LEVEL eLevel,
+                                                                               IMG_BOOL bUnmap);
+
+       PVRSRV_ERROR (*pfnSLCCacheInvalidateRequest)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                                               PMR *psPmr);
+
+       IMG_VOID (*pfnDumpDebugInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+       PVRSRV_ERROR (*pfnUpdateHealthStatus)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                             IMG_BOOL bIsTimerPoll);
+
+       PVRSRV_ERROR (*pfnResetHWRLogs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+       /* Method to drain device HWPerf packets from firmware buffer to host buffer */
+       PVRSRV_ERROR (*pfnServiceHWPerf)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+       PVRSRV_ERROR (*pfnDeviceVersionString)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_CHAR **ppszVersionString);
+
+       PVRSRV_ERROR (*pfnDeviceClockSpeed)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_PUINT32 pui32RGXClockSpeed);
+
+       PVRSRV_ERROR (*pfnSoftReset)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64ResetValue1, IMG_UINT64 ui64ResetValue2);
+
+       PVRSRV_DEVICE_CONFIG    *psDevConfig;
+
+       /* device post-finalise compatibility check */
+       PVRSRV_ERROR                    (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*,IMG_UINT32 ui32ClientBuildOptions);
+
+       /* information about the device's address space and heaps */
+       DEVICE_MEMORY_INFO              sDevMemoryInfo;
+
+       /* private device information */
+       IMG_VOID                                *pvDevice;
+
+       IMG_CHAR                                szRAName[50];
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+       RA_ARENA                *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS];
+#endif
+
+       RA_ARENA                                *psLocalDevMemArena;
+
+       /*
+        * Pointers to the device's physical memory heap(s)
+        * The first entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) will be used for allocations
+        *  where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is not set. Normally this will be an LMA heap
+        *  (but the device configuration could specify a UMA heap here, if desired)
+        * The second entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) will be used for allocations
+        *  where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is set. Normally this will be a UMA heap
+        *  (but the configuration could specify an LMA heap here, if desired)
+        * The device configuration will always specify two physical heap IDs - in the event of the device
+        *  only using one physical heap, both of these IDs will be the same, and hence both pointers below
+        *  will also be the same
+        */
+       PHYS_HEAP                               *apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_LAST];
+
+       struct _PVRSRV_DEVICE_NODE_     *psNext;
+       struct _PVRSRV_DEVICE_NODE_     **ppsThis;
+       
+       /* Functions for notification about memory contexts */
+       PVRSRV_ERROR                    (*pfnRegisterMemoryContext)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+                                                                                                               MMU_CONTEXT                                     *psMMUContext,
+                                                                                                               IMG_HANDLE                                      *hPrivData);
+       IMG_VOID                                (*pfnUnregisterMemoryContext)(IMG_HANDLE hPrivData);
+
+       /* Funtions for allocation/freeing of UFOs */
+       AllocUFOBlockCallback   pfnAllocUFOBlock;       /*!< Callback for allocation of a block of UFO memory */
+       FreeUFOBlockCallback    pfnFreeUFOBlock;        /*!< Callback for freeing of a block of UFO memory */
+
+       PSYNC_PRIM_CONTEXT              hSyncPrimContext;
+
+       PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim;
+
+       IMG_HANDLE                              hCmdCompNotify;
+       IMG_HANDLE                              hDbgReqNotify;
+
+#if defined(PDUMP)
+       /*      device-level callback which is called when pdump.exe starts.
+        *      Should be implemented in device-specific init code, e.g. rgxinit.c
+        */
+       PVRSRV_ERROR                    (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+       /* device-level callback to return pdump ID associated to a memory context */
+       IMG_UINT32                              (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
+#endif
+} PVRSRV_DEVICE_NODE;
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful,
+                                                                                                               IMG_UINT32 ui32ClientBuildOptions);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                                               IMG_UINT32 ui32ClientBuildOptions);
+
+       
+#endif /* __DEVICE_H__ */
+
+/******************************************************************************
+ End of file (device.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/include/devicemem_heapcfg.h b/drivers/gpu/rogue_m/services/server/include/devicemem_heapcfg.h
new file mode 100644 (file)
index 0000000..0dbd40a
--- /dev/null
@@ -0,0 +1,150 @@
+/**************************************************************************/ /*!
+@File
+@Title          Temporary Device Memory 2 stuff
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device memory management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef __DEVICEMEMHEAPCFG_H__
+#define __DEVICEMEMHEAPCFG_H__
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/* FIXME: Find a better way of defining _PVRSRV_DEVICE_NODE_ */
+struct _PVRSRV_DEVICE_NODE_;
+
+/*
+  A "heap config" is a blueprint to be used for initial setting up of
+  heaps when a device memory context is created.
+
+  We define a data structure to define this, but it's really down to
+  the caller to populate it.  This is all expected to be in-kernel.
+  We provide an API that client code can use to enquire about the
+  blueprint, such that it may do the heap setup during the context
+  creation call on behalf of the user */
+
+/* blueprint for a single heap */
+typedef struct _DEVMEM_HEAP_BLUEPRINT_
+{
+    /* Name of this heap - for debug purposes, and perhaps for lookup
+       by name? */
+    const IMG_CHAR *pszName;
+
+    /* Virtual address of the beginning of the heap.  This _must_ be a
+       multiple of the data page size for the heap.  It is
+       _recommended_ that it be coarser than that - especially, it
+       should begin on a boundary appropriate to the MMU for the
+       device.  For Rogue, this is a Page Directory boundary, or 1GB
+       (virtual address a multiple of 0x0040000000). */
+    IMG_DEV_VIRTADDR sHeapBaseAddr;
+
+    /* Length of the heap.  Given that the END address of the heap has
+       a similar restriction to that of the _beginning_ of the heap.
+       That is the heap length _must_ be a whole number of data pages.
+       Again, the recommendation is that it ends on a 1GB boundary.
+       Again, this is not essential, but we do know that (at the time
+       of writing) the current implementation of mmu_common.c is such
+       that no two heaps may share a page directory, thus the
+       remaining virtual space would be wasted if the length were not
+       a multiple of 1GB */
+    IMG_DEVMEM_SIZE_T uiHeapLength;
+
+    /* Data page size.  This is the page size that is going to get
+       programmed into the MMU, so it needs to be a valid one for the
+       device.  Importantly, the start address and length _must_ be
+       multiples of this page size.  Note that the page size is
+       specified as the log 2 relative to 1 byte (e.g. 12 indicates
+       4kB) */
+    IMG_UINT32 uiLog2DataPageSize;
+
+    /* Import alignment.  Force imports to this heap to be
+       aligned to at least this value */
+    IMG_UINT32 uiLog2ImportAlignment;
+} DEVMEM_HEAP_BLUEPRINT;
+
+/* entire named heap config */
+typedef struct _DEVMEM_HEAP_CONFIG_
+{
+    /* Name of this heap config - for debug and maybe lookup */
+    const IMG_CHAR *pszName;
+
+    /* Number of heaps in this config */
+    IMG_UINT32 uiNumHeaps;
+
+    /* Array of individual heap blueprints as defined above */
+    DEVMEM_HEAP_BLUEPRINT *psHeapBlueprintArray;
+} DEVMEM_HEAP_CONFIG;
+
+
+extern PVRSRV_ERROR
+HeapCfgHeapConfigCount(
+    const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+    IMG_UINT32 *puiNumHeapConfigsOut
+);
+
+extern PVRSRV_ERROR
+HeapCfgHeapCount(
+    const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 *puiNumHeapsOut
+);
+
+extern PVRSRV_ERROR
+HeapCfgHeapConfigName(
+    const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 uiHeapConfigNameBufSz,
+    IMG_CHAR *pszHeapConfigNameOut
+);
+
+extern PVRSRV_ERROR
+HeapCfgHeapDetails(
+    const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+    IMG_UINT32 uiHeapConfigIndex,
+    IMG_UINT32 uiHeapIndex,
+    IMG_UINT32 uiHeapNameBufSz,
+    IMG_CHAR *pszHeapNameOut,
+    IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+    IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+    IMG_UINT32 *puiLog2DataPageSizeOut,
+    IMG_UINT32 *puiLog2ImportAlignmentOut
+);
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/server/include/devicemem_history_server.h b/drivers/gpu/rogue_m/services/server/include/devicemem_history_server.h
new file mode 100644 (file)
index 0000000..bd90516
--- /dev/null
@@ -0,0 +1,95 @@
+/*************************************************************************/ /*!
+@File                  devicemem_history_server.h
+@Title          Resource Information abstraction
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Devicemem History functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DEVICEMEM_HISTORY_SERVER_H_
+#define _DEVICEMEM_HISTORY_SERVER_H_
+
+#include "img_defs.h"
+#include "mm_common.h"
+#include "pvrsrv_error.h"
+
+extern PVRSRV_ERROR
+DevicememHistoryInitKM(IMG_VOID);
+
+extern IMG_VOID
+DevicememHistoryDeInitKM(IMG_VOID);
+
+extern PVRSRV_ERROR
+DevicememHistoryMapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]);
+
+extern PVRSRV_ERROR
+DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]);
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_IN_
+{
+       IMG_PID uiPID;
+       IMG_DEV_VIRTADDR sDevVAddr;
+} DEVICEMEM_HISTORY_QUERY_IN;
+
+/* store up to 2 results for a lookup. in the case of the faulting page being
+ * re-mapped between the page fault occurring on HW and the page fault analysis
+ * being done, the second result entry will show the allocation being unmapped
+ */
+#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 2
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_RESULT_
+{
+       IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ];
+       IMG_DEV_VIRTADDR sBaseDevVAddr;
+       IMG_SIZE_T uiSize;
+       IMG_BOOL bAllocated;
+       IMG_UINT64 ui64When;
+       IMG_UINT64 ui64Age;
+} DEVICEMEM_HISTORY_QUERY_OUT_RESULT;
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_
+{
+       IMG_UINT32 ui32NumResults;
+       /* result 0 is the newest */
+       DEVICEMEM_HISTORY_QUERY_OUT_RESULT sResults[DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS];
+} DEVICEMEM_HISTORY_QUERY_OUT;
+
+extern IMG_BOOL
+DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut);
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/server/include/devicemem_server.h b/drivers/gpu/rogue_m/services/server/include/devicemem_server.h
new file mode 100644 (file)
index 0000000..4fa596a
--- /dev/null
@@ -0,0 +1,362 @@
+/**************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header file for server side component of device memory management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef __DEVICEMEM_SERVER_H__
+#define __DEVICEMEM_SERVER_H__
+
+#include "device.h" /* For device node */
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "pmr.h"
+
+typedef struct _DEVMEMINT_CTX_ DEVMEMINT_CTX;
+typedef struct _DEVMEMINT_CTX_EXPORT_ DEVMEMINT_CTX_EXPORT;
+typedef struct _DEVMEMINT_HEAP_ DEVMEMINT_HEAP;
+/* FIXME: can we unify RESERVATION and MAPPING to save data structures? */
+typedef struct _DEVMEMINT_RESERVATION_ DEVMEMINT_RESERVATION;
+typedef struct _DEVMEMINT_MAPPING_ DEVMEMINT_MAPPING;
+
+/*
+ * DevmemServerGetImportHandle()
+ *
+ * For given exportable memory descriptor returns PMR handle
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+                                                  IMG_HANDLE *phImport);
+
+/*
+ * DevmemServerGetHeapHandle()
+ *
+ * For given reservation returns the Heap handle
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION *psReservation,
+                                                  IMG_HANDLE *phHeap);
+
+/*
+ * DevmemIntCtxCreate()
+ *
+ * Create a Server-side Device Memory Context.  This is usually the
+ * counterpart of the client side memory context, and indeed is
+ * usually created at the same time.
+ *
+ * You must have one of these before creating any heaps.
+ *
+ * All heaps must have been destroyed before calling
+ * DevmemIntCtxDestroy()
+ *
+ * If you call DevmemIntCtxCreate() (and it succeeds) you are promising
+ * to later call DevmemIntCtxDestroy()
+ *
+ * Note that this call will cause the device MMU code to do some work
+ * for creating the device memory context, but it does not guarantee
+ * that a page catalogue will have been created, as this may be
+ * deferred until first allocation.
+ *
+ * Caller to provide storage for a pointer to the DEVMEM_CTX object
+ * that will be created by this call.
+ */
+extern PVRSRV_ERROR
+DevmemIntCtxCreate(
+                 PVRSRV_DEVICE_NODE *psDeviceNode,
+                 /* devnode / perproc etc */
+
+                 DEVMEMINT_CTX **ppsDevmemCtxPtr,
+                 IMG_HANDLE *hPrivData
+                 );
+/*
+ * DevmemIntCtxDestroy()
+ *
+ * Undoes a prior DevmemIntCtxCreate or DevmemIntCtxImport.
+ */
+extern PVRSRV_ERROR
+DevmemIntCtxDestroy(
+                  DEVMEMINT_CTX *psDevmemCtx
+                  );
+
+/*
+ * DevmemIntCtxExport()
+ *
+ * Export a device memory context created with DevmemIntCtxCreate to another
+ * process
+ */
+extern PVRSRV_ERROR
+DevmemIntCtxExport(DEVMEMINT_CTX *psDevmemCtx,
+                   DEVMEMINT_CTX_EXPORT **ppsExport);
+
+/*
+ * DevmemIntCtxUnexport
+ *
+ * Unexport an exported a device memory context.
+ */
+extern PVRSRV_ERROR
+DevmemIntCtxUnexport(DEVMEMINT_CTX_EXPORT *psExport);
+
+/*
+ * DevmemIntCtxImport
+ *
+ * Import an exported a device memory context.
+ */
+extern PVRSRV_ERROR
+DevmemIntCtxImport(DEVMEMINT_CTX_EXPORT *psExport,
+                                  DEVMEMINT_CTX **ppsDevmemCtxPtr,
+                                  IMG_HANDLE *hPrivData);
+
+/*
+ * DevmemIntHeapCreate()
+ *
+ * Creates a new heap in this device memory context.  This will cause
+ * a call into the MMU code to allocate various data structures for
+ * managing this heap.  It will not necessarily cause any page tables
+ * to be set up, as this can be deferred until first allocation.
+ * (i.e. we shouldn't care - it's up to the MMU code)
+ *
+ * Note that the data page size must be specified (as log 2).  The
+ * data page size as specified here will be communicated to the mmu
+ * module, and thus may determine the page size configured in page
+ * directory entries for subsequent allocations from this heap.  It is
+ * essential that the page size here is less than or equal to the
+ * "minimum contiguity guarantee" of any PMR that you subsequently
+ * attempt to map to this heap.
+ *
+ * If you call DevmemIntHeapCreate() (and the call succeeds) you are
+ * promising that you shall subsequently call DevmemIntHeapDestroy()
+ *
+ * Caller to provide storage for a pointer to the DEVMEM_HEAP object
+ * that will be created by this call.
+ */
+extern PVRSRV_ERROR
+DevmemIntHeapCreate(
+                   DEVMEMINT_CTX *psDevmemCtx,
+                   IMG_DEV_VIRTADDR sHeapBaseAddr,
+                   IMG_DEVMEM_SIZE_T uiHeapLength,
+                   IMG_UINT32 uiLog2DataPageSize,
+                   DEVMEMINT_HEAP **ppsDevmemHeapPtr
+                   );
+/*
+ * DevmemIntHeapDestroy()
+ *
+ * Destroys a heap previously created with DevmemIntHeapCreate()
+ *
+ * All allocations from his heap must have been freed before this
+ * call.
+ */
+extern PVRSRV_ERROR
+DevmemIntHeapDestroy(
+                     DEVMEMINT_HEAP *psDevmemHeap
+                    );
+
+/*
+ * DevmemIntMapPMR()
+ *
+ * Maps the given PMR to the virtual range previously allocated with
+ * DevmemIntReserveRange()
+ *
+ * If appropriate, the PMR must have had its physical backing
+ * committed, as this call will call into the MMU code to set up the
+ * page tables for this allocation, which shall in turn request the
+ * physical addresses from the PMR.  Alternatively, the PMR
+ * implementation can choose to do so off the back of the "lock"
+ * callback, which it will receive as a result (indirectly) of this
+ * call.
+ *
+ * This function makes no promise w.r.t. the circumstances that it can
+ * be called, and these would be "inherited" from the implementation
+ * of the PMR.  For example if the PMR "lock" callback causes pages to
+ * be pinned at that time (which may cause scheduling or disk I/O
+ * etc.) then it would not be legal to "Map" the PMR in a context
+ * where scheduling events are disallowed.
+ *
+ * If you call DevmemIntMapPMR() (and the call succeeds) then you are
+ * promising that you shall later call DevmemIntUnmapPMR()
+ */
+extern PVRSRV_ERROR
+DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap,
+                DEVMEMINT_RESERVATION *psReservation,
+                PMR *psPMR,
+                PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+                DEVMEMINT_MAPPING **ppsMappingPtr);
+/*
+ * DevmemIntUnmapPMR()
+ *
+ * Reverses the mapping caused by DevmemIntMapPMR()
+ */
+extern PVRSRV_ERROR
+DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping);
+
+/*
+ * DevmemIntReserveRange()
+ *
+ * Indicates that the specified range should be reserved from the
+ * given heap.
+ *
+ * In turn causes the page tables to be allocated to cover the
+ * specified range.
+ *
+ * If you call DevmemIntReserveRange() (and the call succeeds) then you
+ * are promising that you shall later call DevmemIntUnreserveRange()
+ */
+extern PVRSRV_ERROR
+DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap,
+                      IMG_DEV_VIRTADDR sAllocationDevVAddr,
+                      IMG_DEVMEM_SIZE_T uiAllocationSize,
+                      DEVMEMINT_RESERVATION **ppsReservationPtr);
+/*
+ * DevmemIntUnreserveRange()
+ *
+ * Undoes the state change caused by DevmemIntReserveRage()
+ */
+extern PVRSRV_ERROR
+DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psDevmemReservation);
+
+/*
+ * SLCFlushInvalRequest()
+ *
+ * Schedules an SLC Flush & Invalidate on the firmware if required.
+ * If the request is performed depends on the caching attributes
+ * of the allocation and hence depends on the underlying PMR
+ */
+extern PVRSRV_ERROR
+DevmemSLCFlushInvalRequest(PVRSRV_DEVICE_NODE *psDeviceNode, PMR *psPmr);
+
+extern PVRSRV_ERROR
+DevmemIntIsVDevAddrValid(DEVMEMINT_CTX *psDevMemContext,
+                         IMG_DEV_VIRTADDR sDevAddr);
+
+#if defined(PDUMP)
+/*
+ * DevmemIntPDumpSaveToFileVirtual()
+ *
+ * Writes out PDump "SAB" commands with the data found in memory at
+ * the given virtual address.
+ */
+/* FIXME: uiArraySize shouldn't be here, and is an
+   artefact of the bridging */
+extern PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+                                IMG_DEV_VIRTADDR sDevAddrStart,
+                                IMG_DEVMEM_SIZE_T uiSize,
+                                IMG_UINT32 uiArraySize,
+                                const IMG_CHAR *pszFilename,
+                                                               IMG_UINT32 ui32FileOffset,
+                                                               IMG_UINT32 ui32PDumpFlags);
+
+extern IMG_UINT32
+DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext);
+
+extern PVRSRV_ERROR
+DevmemIntPDumpBitmap(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                               IMG_CHAR *pszFileName,
+                                               IMG_UINT32 ui32FileOffset,
+                                               IMG_UINT32 ui32Width,
+                                               IMG_UINT32 ui32Height,
+                                               IMG_UINT32 ui32StrideInBytes,
+                                               IMG_DEV_VIRTADDR sDevBaseAddr,
+                                               DEVMEMINT_CTX *psDevMemContext,
+                                               IMG_UINT32 ui32Size,
+                                               PDUMP_PIXEL_FORMAT ePixelFormat,
+                                               IMG_UINT32 ui32AddrMode,
+                                               IMG_UINT32 ui32PDumpFlags);
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+                                IMG_DEV_VIRTADDR sDevAddrStart,
+                                IMG_DEVMEM_SIZE_T uiSize,
+                                IMG_UINT32 uiArraySize,
+                                const IMG_CHAR *pszFilename,
+                                                               IMG_UINT32 ui32FileOffset,
+                                                               IMG_UINT32 ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psDevmemCtx);
+       PVR_UNREFERENCED_PARAMETER(sDevAddrStart);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(uiArraySize);
+       PVR_UNREFERENCED_PARAMETER(pszFilename);
+       PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpBitmap(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                               IMG_CHAR *pszFileName,
+                                               IMG_UINT32 ui32FileOffset,
+                                               IMG_UINT32 ui32Width,
+                                               IMG_UINT32 ui32Height,
+                                               IMG_UINT32 ui32StrideInBytes,
+                                               IMG_DEV_VIRTADDR sDevBaseAddr,
+                                               DEVMEMINT_CTX *psDevMemContext,
+                                               IMG_UINT32 ui32Size,
+                                               PDUMP_PIXEL_FORMAT ePixelFormat,
+                                               IMG_UINT32 ui32AddrMode,
+                                               IMG_UINT32 ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+       PVR_UNREFERENCED_PARAMETER(pszFileName);
+       PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Width);
+       PVR_UNREFERENCED_PARAMETER(ui32Height);
+       PVR_UNREFERENCED_PARAMETER(ui32StrideInBytes);
+       PVR_UNREFERENCED_PARAMETER(sDevBaseAddr);
+       PVR_UNREFERENCED_PARAMETER(psDevMemContext);
+       PVR_UNREFERENCED_PARAMETER(ui32Size);
+       PVR_UNREFERENCED_PARAMETER(ePixelFormat);
+       PVR_UNREFERENCED_PARAMETER(ui32AddrMode);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+#endif /* ifndef __DEVICEMEM_SERVER_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/include/devicemem_server_utils.h b/drivers/gpu/rogue_m/services/server/include/devicemem_server_utils.h
new file mode 100644 (file)
index 0000000..f492040
--- /dev/null
@@ -0,0 +1,191 @@
+/**************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header file utilities that are specific to device memory functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_memallocflags.h"
+#include "pvrsrv.h"
+
+static INLINE IMG_UINT32 DevmemCPUCacheMode(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+       IMG_UINT32 ui32CPUCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK;
+       IMG_UINT32 ui32Ret;
+
+       PVR_ASSERT(ui32CPUCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK));
+
+       switch (ui32CPUCacheMode)
+       {
+               case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT:
+                       /* Fall through */
+               case PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT:
+                       /*
+                               If the allocation needs to be coherent what we end up doing
+                               depends on the snooping features of the system
+                       */
+                       if (PVRSRVSystemSnoopingOfCPUCache())
+                       {
+                               /*
+                                       If the system has CPU cache snooping (tested above)
+                                       then the allocation should be cached ...
+                               */
+                               ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
+                       }
+                       else
+                       {
+                               /* ... otherwise it should be uncached */
+                               ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+                       }
+                       break;
+
+               default:
+                       PVR_LOG(("DevmemCPUCacheMode: Unknown CPU cache mode 0x%08x", ui32CPUCacheMode));
+                       PVR_ASSERT(0);
+                       /*
+                               We should never get here, but if we do then setting the mode
+                               to uncached is the safest thing to do.
+                       */
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+                       break;
+       }
+
+       return ui32Ret;
+}
+
+static INLINE IMG_UINT32 DevmemDeviceCacheMode(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+       IMG_UINT32 ui32DeviceCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK;
+       IMG_UINT32 ui32Ret;
+
+       PVR_ASSERT(ui32DeviceCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK));
+
+       switch (ui32DeviceCacheMode)
+       {
+               case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT:
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
+                       break;
+
+               case PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT:
+                       /* Fall through */
+               case PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT:
+                       /*
+                               If the allocation needs to be coherent what we end up doing
+                               depends on the snooping features of the system
+                       */
+                       if (PVRSRVSystemSnoopingOfDeviceCache())
+                       {
+                               /*
+                                       If the system has GPU cache snooping (tested above)
+                                       then the allocation should be cached ...
+                               */
+                               ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
+                       }
+                       else
+                       {
+                               /* ... otherwise it should be uncached */
+                               ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+                       }
+                       break;
+
+               default:
+                       PVR_LOG(("DevmemDeviceCacheMode: Unknown device cache mode 0x%08x", ui32DeviceCacheMode));
+                       PVR_ASSERT(0);
+                       /*
+                               We should never get here, but if we do then setting the mode
+                               to uncached is the safest thing to do.
+                       */
+                       ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+                       break;
+       }
+
+       return ui32Ret;
+}
+
+static INLINE IMG_BOOL DevmemCPUCacheCoherency(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+       IMG_UINT32 ui32CPUCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK;
+       IMG_BOOL bRet = IMG_FALSE;
+
+       PVR_ASSERT(ui32CPUCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK));
+
+       if ((ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) ||
+               (ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT))
+       {
+               bRet = PVRSRVSystemSnoopingOfDeviceCache();
+       }
+       return bRet;
+}
+
+static INLINE IMG_BOOL DevmemDeviceCacheCoherency(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+       IMG_UINT32 ui32DeviceCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK;
+       IMG_BOOL bRet = IMG_FALSE;
+
+       PVR_ASSERT(ui32DeviceCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK));
+
+       if ((ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) ||
+               (ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT))
+       {
+               bRet = PVRSRVSystemSnoopingOfCPUCache();
+       }
+       return bRet;
+}
diff --git a/drivers/gpu/rogue_m/services/server/include/handle.h b/drivers/gpu/rogue_m/services/server/include/handle.h
new file mode 100644 (file)
index 0000000..2714c6d
--- /dev/null
@@ -0,0 +1,220 @@
+/**************************************************************************/ /*!
+@File
+@Title          Handle Manager API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Provide handle management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(__HANDLE_H__)
+#define __HANDLE_H__
+
+/*
+ * Handle API
+ * ----------
+ * The handle API is intended to provide handles for kernel resources,
+ * which can then be passed back to user space processes.
+ *
+ * The following functions comprise the API.  Each function takes a
+ * pointer to a PVRSRV_HANDLE_BASE strcture, one of which is allocated
+ * for each process, and stored in the per-process data area.  Use
+ * KERNEL_HANDLE_BASE for handles not allocated for a particular process,
+ * or for handles that need to be allocated before the PVRSRV_HANDLE_BASE
+ * structure for the process is available.
+ *
+ * PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType,
+ *     PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+ *
+ * Allocate a handle phHandle, for the resource of type eType pointed to by
+ * pvData.
+ *
+ * For handles that have a definite lifetime, where the corresponding
+ * resource is explicitly created and destroyed, eFlag should be zero.
+ *
+ * If the resource is not explicitly created and destroyed, eFlag should be
+ * set to PVRSRV_HANDLE_ALLOC_FLAG_SHARED.  For a given process, the same
+ * handle will be returned each time a handle for the resource is allocated
+ * with the PVRSRV_HANDLE_ALLOC_FLAG_SHARED flag.
+ *
+ * If a particular resource may be referenced multiple times by a
+ * given process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+ * will allow multiple handles to be allocated for the resource.
+ * Such handles cannot be found with PVRSRVFindHandle.
+ *
+ * PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType,
+ *     PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+ *
+ * This function is similar to PVRSRVAllocHandle, except that the allocated
+ * handles are associated with a parent handle, hParent, that has been
+ * allocated previously.  Subhandles are automatically deallocated when their
+ * parent handle is deallocated.
+ * Subhandles can be treated as ordinary handles.  For example, they may
+ * have subhandles of their own, and may be explicity deallocated using
+ * PVRSRVReleaseHandle (see below).
+ *
+ * PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Find the handle previously allocated for the resource pointed to by
+ * pvData, of type eType.  Handles allocated with the flag
+ * PVRSRV_HANDLE_ALLOC_FLAG_MULTI cannot be found using this
+ * function.
+ *
+ * PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Given a handle for a resource of type eType, return the pointer to the
+ * resource.
+ *
+ * PVRSRV_ERROR PVRSRVLookuSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType,
+ *     IMH_HANDLE hAncestor);
+ *
+ * Similar to PVRSRVLookupHandle, but checks the handle is a descendant
+ * of hAncestor.
+ *
+ * PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Deallocate a handle of given type.
+ *
+ * PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase,
+ *     IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Return the parent of a handle in *phParent, or IMG_NULL if the handle has
+ * no parent.
+ */
+
+#include "img_types.h"
+#include "hash.h"
+
+typedef enum
+{
+       PVRSRV_HANDLE_TYPE_NONE = 0,
+       PVRSRV_HANDLE_TYPE_DEV_NODE,
+       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+       PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+       PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+       PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
+       PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+       PVRSRV_HANDLE_TYPE_RGX_RPM_CONTEXT_CLEANUP,
+       PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
+       PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+       PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+       PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
+       PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+       PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+       PVRSRV_HANDLE_TYPE_SERVER_SYNC_EXPORT,
+       PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+       PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
+       PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET,
+       PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+       PVRSRV_HANDLE_TYPE_RGX_POPULATION,
+       PVRSRV_HANDLE_TYPE_DC_DEVICE,
+       PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+       PVRSRV_HANDLE_TYPE_DC_BUFFER,
+       PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE,
+       PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
+       PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_PAGELIST,
+       PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+       PVRSRV_HANDLE_TYPE_RI_HANDLE,
+       PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+       PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP
+} PVRSRV_HANDLE_TYPE;
+
+typedef enum
+{
+       /* No flags */
+       PVRSRV_HANDLE_ALLOC_FLAG_NONE =                 0,
+       /* Share a handle that already exists for a given data pointer */
+       PVRSRV_HANDLE_ALLOC_FLAG_SHARED =               0x01,
+       /* Muliple handles can point at the given data pointer */
+       PVRSRV_HANDLE_ALLOC_FLAG_MULTI =                0x02,
+       /* Subhandles are allocated in a private handle space */
+       PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE =              0x04
+} PVRSRV_HANDLE_ALLOC_FLAG;
+
+typedef struct _HANDLE_BASE_ PVRSRV_HANDLE_BASE;
+
+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
+#define        KERNEL_HANDLE_BASE (gpsKernelHandleBase)
+
+typedef PVRSRV_ERROR (*PFN_HANDLE_RELEASE)(void *pvData);
+
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+
+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_HANDLE *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime);
+
+PVRSRV_ERROR PVRSRVHandleInit(void);
+
+PVRSRV_ERROR PVRSRVHandleDeInit(void);
+
+void LockHandle(void);
+void UnlockHandle(void);
+
+
+#endif /* !defined(__HANDLE_H__) */
diff --git a/drivers/gpu/rogue_m/services/server/include/handle_impl.h b/drivers/gpu/rogue_m/services/server/include/handle_impl.h
new file mode 100644 (file)
index 0000000..95043d7
--- /dev/null
@@ -0,0 +1,89 @@
+/**************************************************************************/ /*!
+@File
+@Title          Implementation Callbacks for Handle Manager API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the handle manager API. This file is for declarations 
+                and definitions that are private/internal to the handle manager 
+                API but need to be shared between the generic handle manager 
+                code and the various handle manager backends, i.e. the code that 
+                implements the various callbacks.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(__HANDLE_IMPL_H__)
+#define __HANDLE_IMPL_H__
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+typedef struct _HANDLE_IMPL_BASE_ HANDLE_IMPL_BASE;
+
+typedef PVRSRV_ERROR (*PFN_HANDLE_ITER)(IMG_HANDLE hHandle, void *pvData);
+
+typedef struct _HANDLE_IMPL_FUNCTAB_
+{
+       /* Acquire a new handle which is associated with the given data */
+       PVRSRV_ERROR (*pfnAcquireHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE *phHandle, void *pvData);
+
+       /* Release the given handle (optionally returning the data associated with it) */
+       PVRSRV_ERROR (*pfnReleaseHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData);
+
+       /* Get the data associated with the given handle */
+       PVRSRV_ERROR (*pfnGetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData);
+
+       /* Set the data associated with the given handle */
+       PVRSRV_ERROR (*pfnSetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void *pvData);
+
+       PVRSRV_ERROR (*pfnIterateOverHandles)(HANDLE_IMPL_BASE *psHandleBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData);
+
+       /* Enable handle purging on the given handle base */
+       PVRSRV_ERROR (*pfnEnableHandlePurging)(HANDLE_IMPL_BASE *psHandleBase);
+
+       /* Purge handles on the given handle base */
+       PVRSRV_ERROR (*pfnPurgeHandles)(HANDLE_IMPL_BASE *psHandleBase);
+
+       /* Create handle base */
+       PVRSRV_ERROR (*pfnCreateHandleBase)(HANDLE_IMPL_BASE **psHandleBase);
+
+       /* Destroy handle base */
+       PVRSRV_ERROR (*pfnDestroyHandleBase)(HANDLE_IMPL_BASE *psHandleBase);
+} HANDLE_IMPL_FUNCTAB;
+
+PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs);
+
+#endif /* !defined(__HANDLE_IMPL_H__) */
diff --git a/drivers/gpu/rogue_m/services/server/include/lists.h b/drivers/gpu/rogue_m/services/server/include/lists.h
new file mode 100644 (file)
index 0000000..a0e7cc4
--- /dev/null
@@ -0,0 +1,336 @@
+/*************************************************************************/ /*!
+@File
+@Title          Linked list shared functions templates.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Definition of the linked list function templates.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __LISTS_UTILS__
+#define __LISTS_UTILS__
+
+/* instruct QAC to ignore warnings about the following custom formatted macros */
+/* PRQA S 0881,3410 ++ */
+#include <stdarg.h>
+#include "img_types.h"
+#include "device.h"
+#include "power.h"
+
+/*
+ - USAGE -
+
+ The list functions work with any structure that provides the fields psNext and
+ ppsThis. In order to make a function available for a given type, it is required
+ to use the funcion template macro that creates the actual code.
+
+ There are 4 main types of functions:
+ - INSERT      : given a pointer to the head pointer of the list and a pointer to
+                         the node, inserts it as the new head.
+ - REMOVE      : given a pointer to a node, removes it from its list.
+ - FOR EACH    : apply a function over all the elements of a list.
+ - ANY         : apply a function over the elements of a list, until one of them
+                         return a non null value, and then returns it.
+
+ The two last functions can have a variable argument form, with allows to pass
+ additional parameters to the callback function. In order to do this, the
+ callback function must take two arguments, the first is the current node and
+ the second is a list of variable arguments (va_list).
+
+ The ANY functions have also another for wich specifies the return type of the
+ callback function and the default value returned by the callback function.
+
+*/
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_ForEach
+@Description    Apply a callback function to all the elements of a list.
+@Input          psHead        The head of the list to be processed.
+@Input          pfnCallBack   The function to be applied to each element of the list.
+*/ /**************************************************************************/
+#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;\
+       }\
+}
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_ForEachSafe
+@Description    Apply a callback function to all the elements of a list. Do it
+                in a safe way that handles the fact that a node might remove itself
+                from the list during the iteration.
+@Input          psHead        The head of the list to be processed.
+@Input          pfnCallBack   The function to be applied to each element of the list.
+*/ /**************************************************************************/
+#define DECLARE_LIST_FOR_EACH_SAFE(TYPE) \
+IMG_VOID List_##TYPE##_ForEachSafe(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_FOR_EACH_SAFE(TYPE) \
+IMG_VOID List_##TYPE##_ForEachSafe(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
+{\
+       TYPE *psNext;\
+\
+       while(psHead)\
+       {\
+               psNext = psHead->psNext; \
+               pfnCallBack(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);\
+       }\
+}
+
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_Any
+@Description    Applies a callback function to the elements of a list until the function
+                returns a non null value, then returns it.
+@Input          psHead        The head of the list to be processed.
+@Input          pfnCallBack   The function to be applied to each element of the list.
+@Return         The first non null value returned by the callback function.
+*/ /**************************************************************************/
+#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;\
+}
+
+
+/*with variable arguments, that will be passed as a va_list to the callback function*/
+
+#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;\
+}
+
+/*those ones are for extra type safety, so there's no need to use castings for the results*/
+
+#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;\
+}
+
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_Remove
+@Description    Removes a given node from the list.
+@Input          psNode      The pointer to the node to be removed.
+*/ /**************************************************************************/
+#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;\
+       }\
+}
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_Insert
+@Description    Inserts a given node at the beginnning of the list.
+@Input          psHead   The pointer to the pointer to the head node.
+@Input          psNode   The pointer to the node to be inserted.
+*/ /**************************************************************************/
+#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);\
+       }\
+}
+
+/*************************************************************************/ /*!
+@Function       List_##TYPE##_Reverse
+@Description    Reverse a list in place
+@Input          ppsHead    The pointer to the pointer to the head node.
+*/ /**************************************************************************/
+#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)
+
+
+DECLARE_LIST_ANY(PVRSRV_DEVICE_NODE);
+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
+
+/* re-enable warnings */
+/* PRQA S 0881,3410 -- */
diff --git a/drivers/gpu/rogue_m/services/server/include/mmu_common.h b/drivers/gpu/rogue_m/services/server/include/mmu_common.h
new file mode 100644 (file)
index 0000000..e382eaf
--- /dev/null
@@ -0,0 +1,587 @@
+/**************************************************************************/ /*!
+@File
+@Title          Common MMU Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements basic low level control of MMU.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef MMU_COMMON_H
+#define MMU_COMMON_H
+
+/*
+       The Memory Management Unit (MMU) performs device virtual to physical translation.
+
+       Terminology:
+        - page catalogue, PC   (optional, 3 tier MMU)
+        - page directory, PD
+        - page table, PT (can be variable sized)
+        - data page, DP (can be variable sized)
+    Note: PD and PC are fixed size and can't be larger than 
+           the native physical (CPU) page size
+       Shifts and AlignShift variables:
+        - 'xxxShift' represent the number of bits a bitfield is shifted left from bit0 
+        - 'xxxAlignShift' is used to convert a bitfield (based at bit0) into byte units 
+               by applying a bit shift left by 'xxxAlignShift' bits
+*/
+
+/*
+       Device Virtual Address Config:
+
+       Incoming Device Virtual Address is deconstructed into up to 4
+       fields, where the virtual address is up to 64bits:
+       MSB-----------------------------------------------LSB
+       | PC Index:   | PD Index:  | PT Index: | DP offset: |
+       | d bits      | c bits     | b-v bits  |  a+v bits  |
+       -----------------------------------------------------
+       where v is the variable page table modifier, e.g.
+                       v == 0 -> 4KB DP
+                       v == 2 -> 16KB DP
+                       v == 4 -> 64KB DP
+                       v == 6 -> 256KB DP
+                       v == 8 -> 1MB DP
+                       v == 10 -> 4MB DP
+*/
+
+/* services/server/include/ */
+#include "pmr.h"
+
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "servicesext.h"
+
+/*!
+       The level of the MMU
+*/
+typedef enum
+{
+       MMU_LEVEL_0 = 0,        /* Level 0 = Page */
+
+       MMU_LEVEL_1,
+       MMU_LEVEL_2,
+       MMU_LEVEL_3,
+       MMU_LEVEL_LAST
+} MMU_LEVEL;
+
+/* moved after declaration of MMU_LEVEL, as pdump_mmu.h references it */
+#include "pdump_mmu.h"
+
+#define MMU_MAX_LEVEL 3
+
+struct _MMU_DEVVADDR_CONFIG_;
+
+/*!
+       MMU device attributes. This structure is the interface between the generic
+       MMU code and the device specific MMU code.
+*/
+typedef struct _MMU_DEVICEATTRIBS_
+{
+       PDUMP_MMU_TYPE eMMUType;
+
+       /*! The type of the top level object */
+       MMU_LEVEL eTopLevel;
+
+       /*! Alignment requirement of the base object */
+       IMG_UINT32 ui32BaseAlign;
+
+       /*! HW config of the base object */
+       struct _MMU_PxE_CONFIG_ *psBaseConfig;
+
+       /*! Address split for the base object */
+       const struct _MMU_DEVVADDR_CONFIG_ *psTopLevelDevVAddrConfig;
+
+       /*! Callback for creating protection bits for the page catalogue entry with 8 byte entry */
+       IMG_UINT64 (*pfnDerivePCEProt8)(IMG_UINT32, IMG_UINT8);
+       /*! Callback for creating protection bits for the page catalogue entry with 4 byte entry */
+       IMG_UINT32 (*pfnDerivePCEProt4)(IMG_UINT32);
+       /*! Callback for creating protection bits for the page directory entry with 8 byte entry */
+       IMG_UINT64 (*pfnDerivePDEProt8)(IMG_UINT32, IMG_UINT8);
+       /*! Callback for creating protection bits for the page directory entry with 4 byte entry */
+       IMG_UINT32 (*pfnDerivePDEProt4)(IMG_UINT32);
+       /*! Callback for creating protection bits for the page table entry with 8 byte entry */
+       IMG_UINT64 (*pfnDerivePTEProt8)(IMG_UINT32, IMG_UINT8);
+       /*! Callback for creating protection bits for the page table entry with 4 byte entry */
+       IMG_UINT32 (*pfnDerivePTEProt4)(IMG_UINT32);
+
+       /*! Callback for getting the MMU configuration based on the specified page size */
+       PVRSRV_ERROR (*pfnGetPageSizeConfiguration)(IMG_UINT32 ui32DataPageSize,
+                                                                                               const struct _MMU_PxE_CONFIG_ **ppsMMUPDEConfig,
+                                                                                               const struct _MMU_PxE_CONFIG_ **ppsMMUPTEConfig,
+                                                                                               const struct _MMU_DEVVADDR_CONFIG_ **ppsMMUDevVAddrConfig,
+                                                                                               IMG_HANDLE *phPriv2);
+       /*! Callback for putting the MMU configuration obtained from pfnGetPageSizeConfiguration */
+       PVRSRV_ERROR (*pfnPutPageSizeConfiguration)(IMG_HANDLE hPriv);
+
+       /*! Callback for getting the page size from the PDE for the page table entry with 4 byte entry */
+       PVRSRV_ERROR (*pfnGetPageSizeFromPDE4)(IMG_UINT32, IMG_UINT32 *);
+       /*! Callback for getting the page size from the PDE for the page table entry with 8 byte entry */
+       PVRSRV_ERROR (*pfnGetPageSizeFromPDE8)(IMG_UINT64, IMG_UINT32 *);
+
+       /*! Private data handle */
+       IMG_HANDLE hGetPageSizeFnPriv;
+} MMU_DEVICEATTRIBS;
+
+/*!
+       MMU virtual address split
+*/
+typedef struct _MMU_DEVVADDR_CONFIG_
+{
+       /*! Page catalogue index mask */
+       IMG_UINT64      uiPCIndexMask;
+       /*! Page catalogue index shift */
+       IMG_UINT8       uiPCIndexShift;
+       /*! Page directory mask */
+       IMG_UINT64      uiPDIndexMask;
+       /*! Page directory shift */
+       IMG_UINT8       uiPDIndexShift;
+       /*! Page table mask */
+       IMG_UINT64      uiPTIndexMask;
+       /*! Page index shift */
+       IMG_UINT8       uiPTIndexShift;
+       /*! Page offset mask */
+       IMG_UINT64      uiPageOffsetMask;
+       /*! Page offset shift */
+       IMG_UINT8       uiPageOffsetShift;
+} MMU_DEVVADDR_CONFIG;
+
+/*
+       P(C/D/T) Entry Config:
+
+       MSB-----------------------------------------------LSB
+       | PT Addr:   | variable PT ctrl | protection flags: |
+       | bits c+v   | b bits           | a bits            |
+       -----------------------------------------------------
+       where v is the variable page table modifier and is optional
+*/
+/*!
+       Generic MMU page * entry description. This is used to describe PC, PD and PT
+*/
+typedef struct _MMU_PxE_CONFIG_
+{
+       /*! Size of an entry in bytes */
+       IMG_UINT8       uiBytesPerEntry;
+
+       /*! Physical address mask */
+       IMG_UINT64       uiAddrMask;
+       /*! Physical address shift */
+       IMG_UINT8        uiAddrShift;
+       /*! Log 2 alignment */
+       IMG_UINT8        uiLog2Align;
+
+       /*! Variable control mask */
+       IMG_UINT64       uiVarCtrlMask;
+       /*! Variable control shift */
+       IMG_UINT8        uiVarCtrlShift;
+
+       /*! Protection flags mask */
+       IMG_UINT64       uiProtMask;
+       /*! Protection flags shift */
+       IMG_UINT8        uiProtShift;
+
+       /*! Entry valid bit mask */
+       IMG_UINT64   uiValidEnMask;
+       /*! Entry valid bit shift */
+       IMG_UINT8    uiValidEnShift;
+} MMU_PxE_CONFIG;
+
+/* MMU Protection flags */
+
+
+/* These are specified generically and in a h/w independent way, and
+   are interpreted at each level (PC/PD/PT) separately. */
+
+/* The following flags are for internal use only, and should not
+   traverse the API */
+#define MMU_PROTFLAGS_INVALID 0x80000000U
+
+typedef IMG_UINT32 MMU_PROTFLAGS_T;
+
+/* The following flags should be supplied by the caller: */
+#define MMU_PROTFLAGS_READABLE                                 (1U<<0)
+#define MMU_PROTFLAGS_WRITEABLE                                    (1U<<1)
+#define MMU_PROTFLAGS_CACHE_COHERENT                   (1U<<2)
+#define MMU_PROTFLAGS_CACHED                                   (1U<<3)
+
+/* Device specific flags*/
+#define MMU_PROTFLAGS_DEVICE_OFFSET            16
+#define MMU_PROTFLAGS_DEVICE_MASK              0x000f0000UL
+#define MMU_PROTFLAGS_DEVICE(n)        \
+                       (((n) << MMU_PROTFLAGS_DEVICE_OFFSET) & \
+                       MMU_PROTFLAGS_DEVICE_MASK)
+
+typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
+
+struct _PVRSRV_DEVICE_NODE_; 
+
+/*************************************************************************/ /*!
+@Function       MMU_ContextCreate
+
+@Description    Create a new MMU context
+
+@Input          psDevNode               Device node of the device to create the
+                                        MMU context for
+
+@Output         ppsMMUContext           The created MMU context
+
+@Return         PVRSRV_OK if the MMU context was successfully created
+*/
+/*****************************************************************************/
+extern PVRSRV_ERROR
+MMU_ContextCreate (struct _PVRSRV_DEVICE_NODE_ *psDevNode, MMU_CONTEXT **ppsMMUContext);
+
+
+/*************************************************************************/ /*!
+@Function       MMU_ContextDestroy
+
+@Description    Destroy a MMU context
+
+@Input          ppsMMUContext           MMU context to destroy
+
+@Return         None
+*/
+/*****************************************************************************/
+extern IMG_VOID
+MMU_ContextDestroy (MMU_CONTEXT *psMMUContext);
+
+/*************************************************************************/ /*!
+@Function       MMU_Alloc
+
+@Description    Allocate the page tables required for the specified virtual range
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          uSize                   The size of the allocation
+
+@Output         puActualSize            Actual size of allocation
+
+@Input          uiProtFlags             Generic MMU protection flags
+
+@Input          uDevVAddrAlignment      Alignment requirement of the virtual
+                                        allocation
+
+@Input          psDevVAddr              Virtual address to start the allocation
+                                        from
+
+@Return         PVRSRV_OK if the allocation of the page tables was successful
+*/
+/*****************************************************************************/
+extern PVRSRV_ERROR
+MMU_Alloc (MMU_CONTEXT *psMMUContext,
+           IMG_DEVMEM_SIZE_T uSize,
+           IMG_DEVMEM_SIZE_T *puActualSize,
+           IMG_UINT32 uiProtFlags,
+           IMG_DEVMEM_SIZE_T uDevVAddrAlignment,
+           IMG_DEV_VIRTADDR *psDevVAddr,
+           IMG_UINT8 uiLog2PageSize);
+
+
+/*************************************************************************/ /*!
+@Function       MMU_Free
+
+@Description    Free the page tables of the specified virtual range
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          psDevVAddr              Virtual address to start the free
+                                        from
+
+@Input          uSize                   The size of the allocation
+
+@Return         None
+*/
+/*****************************************************************************/
+extern IMG_VOID
+MMU_Free (MMU_CONTEXT *psMMUContext,
+          IMG_DEV_VIRTADDR sDevVAddr,
+          IMG_DEVMEM_SIZE_T uiSize,
+          IMG_UINT8 uiLog2PageSize);
+
+/*************************************************************************/ /*!
+@Function       MMU_UnmapPages
+
+@Description    Unmap pages from the MMU.
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          psDevVAddr              Device virtual address of the 1st page
+
+@Input          ui32PageCount           Number of pages to unmap
+
+@Return         None
+*/
+/*****************************************************************************/
+extern IMG_VOID
+MMU_UnmapPages (MMU_CONTEXT *psMMUContext,
+                IMG_DEV_VIRTADDR sDevVAddr,
+                IMG_UINT32 ui32PageCount,
+                IMG_UINT8 uiLog2PageSize);
+
+/*************************************************************************/ /*!
+@Function       MMU_MapPMR
+
+@Description    Map a PMR into the MMU.
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          sDevVAddr               Device virtual address to map the PMR
+                                        into
+
+@Input          psPMR                   PMR to map
+
+@Input          uiSizeBytes             Size in bytes to map
+
+@Input          uiMappingFlags          Memalloc flags for the mapping
+
+@Return         PVRSRV_OK if the PMR was successfully mapped
+*/
+/*****************************************************************************/
+extern PVRSRV_ERROR
+MMU_MapPMR (MMU_CONTEXT *psMMUContext,
+            IMG_DEV_VIRTADDR sDevVAddr,
+            const PMR *psPMR,
+            IMG_DEVMEM_SIZE_T uiSizeBytes,
+            PVRSRV_MEMALLOCFLAGS_T uiMappingFlags,
+            IMG_UINT8 uiLog2PageSize);
+
+/*************************************************************************/ /*!
+@Function       MMU_AcquireBaseAddr
+
+@Description    Acquire the device physical address of the base level MMU object
+
+@Input          psMMUContext            MMU context to operate on
+
+@Output         psPhysAddr              Device physical address of the base level
+                                        MMU object
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+PVRSRV_ERROR
+MMU_AcquireBaseAddr(MMU_CONTEXT *psMMUContext, IMG_DEV_PHYADDR *psPhysAddr);
+
+/*************************************************************************/ /*!
+@Function       MMU_ReleaseBaseAddr
+
+@Description    Release the device physical address of the base level MMU object
+
+@Input          psMMUContext            MMU context to operate on
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+IMG_VOID
+MMU_ReleaseBaseAddr(MMU_CONTEXT *psMMUContext);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+/***********************************************************************************/ /*!
+@Function       MMU_SetOSid
+
+@Description    Set the OSid associated with the application (and the MMU Context)
+
+@Input          psMMUContext            MMU context to store the OSid on
+
+@Input          ui32OSid                the OSid in question
+
+@Input                 ui32OSidReg                             The value that the firmware will assign to the
+                                                                               registers.
+@Return None
+*/
+/***********************************************************************************/
+
+IMG_VOID MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg);
+
+/***********************************************************************************/ /*!
+@Function       MMU_GetOSid
+
+@Description    Retrieve the OSid associated with the MMU context.
+
+@Input          psMMUContext            MMU context to store the OSid on
+
+@Output                        ui32OSid                the OSid in question
+
+@Output                        ui32OSidReg                             The OSid that the firmware will assign to the
+                                                                               registers
+@Return None
+*/
+/***********************************************************************************/
+
+IMG_VOID MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 * pui32OSid, IMG_UINT32 * pui32OSidReg);
+#endif
+
+/*************************************************************************/ /*!
+@Function       MMU_SetDeviceData
+
+@Description    Set the device specific callback data
+
+@Input          psMMUContext            MMU context to store the data on
+
+@Input          hDevData                Device data
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID MMU_SetDeviceData(MMU_CONTEXT *psMMUContext, IMG_HANDLE hDevData);
+
+/*************************************************************************/ /*!
+@Function       MMU_CheckFaultAddress
+
+@Description    Check the specified MMU context to see if the provided address
+                should be valid
+
+@Input          psMMUContext            MMU context to store the data on
+
+@Input          psDevVAddr              Address to check
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, IMG_DEV_VIRTADDR *psDevVAddr);
+
+/*************************************************************************/ /*!
+@Function       MMUI_IsVDevAddrValid
+@Description    Checks if given address is valid.
+@Input          psMMUContext MMU context to store the data on
+@Input          uiLog2PageSize page size
+@Input          psDevVAddr Address to check
+@Return         IMG_TRUE of address is valid
+*/ /**************************************************************************/
+IMG_BOOL MMU_IsVDevAddrValid(MMU_CONTEXT *psMMUContext,
+                             IMG_UINT32 uiLog2PageSize,
+                             IMG_DEV_VIRTADDR sDevVAddr);
+
+#if defined(PDUMP)
+/*************************************************************************/ /*!
+@Function       MMU_ContextDerivePCPDumpSymAddr
+
+@Description    Derives a PDump Symbolic address for the top level MMU object
+
+@Input          psMMUContext                    MMU context to operate on
+
+@Input          pszPDumpSymbolicNameBuffer      Buffer to write the PDump symbolic
+                                                address to
+
+@Input          uiPDumpSymbolicNameBufferSize   Size of the buffer
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+extern PVRSRV_ERROR MMU_ContextDerivePCPDumpSymAddr(MMU_CONTEXT *psMMUContext,
+                                                    IMG_CHAR *pszPDumpSymbolicNameBuffer,
+                                                    IMG_SIZE_T uiPDumpSymbolicNameBufferSize);
+
+/*************************************************************************/ /*!
+@Function       MMU_PDumpWritePageCatBase
+
+@Description    PDump write of the top level MMU object to a device register
+
+@Input          psMMUContext        MMU context to operate on
+
+@Input          pszSpaceName           PDump name of the mem/reg space
+
+@Input          uiOffset                       Offset to write the address to
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+PVRSRV_ERROR MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext,
+                                                                       const IMG_CHAR *pszSpaceName,
+                                                                       IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                       IMG_UINT32 ui32WordSize,
+                                                                       IMG_UINT32 ui32AlignShift,
+                                                                       IMG_UINT32 ui32Shift,
+                                                                       PDUMP_FLAGS_T uiPdumpFlags);
+
+/*************************************************************************/ /*!
+@Function       MMU_AcquirePDumpMMUContext
+
+@Description    Acquire a reference to the PDump MMU context for this MMU
+                context
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          pszRegSpaceName         PDump name of the register space
+
+@Output         pui32PDumpMMUContextID  PDump MMU context ID
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+PVRSRV_ERROR MMU_AcquirePDumpMMUContext(MMU_CONTEXT *psMMUContext, IMG_UINT32 *pui32PDumpMMUContextID);
+
+/*************************************************************************/ /*!
+@Function       MMU_ReleasePDumpMMUContext
+
+@Description    Release a reference to the PDump MMU context for this MMU context
+
+@Input          psMMUContext            MMU context to operate on
+
+@Input          pszRegSpaceName         PDump name of the register space
+
+@Output         pui32PDumpMMUContextID  PDump MMU context ID
+
+@Return         PVRSRV_OK if successful
+*/
+/*****************************************************************************/
+PVRSRV_ERROR MMU_ReleasePDumpMMUContext(MMU_CONTEXT *psMMUContext);
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(MMU_PDumpWritePageCatBase)
+#endif
+static INLINE IMG_VOID
+MMU_PDumpWritePageCatBase(MMU_CONTEXT *psMMUContext,
+                                                       const IMG_CHAR *pszSpaceName,
+                                                       IMG_DEVMEM_OFFSET_T uiOffset,
+                                                       IMG_UINT32 ui32WordSize,
+                                                       IMG_UINT32 ui32AlignShift,
+                                                       IMG_UINT32 ui32Shift,
+                                                       PDUMP_FLAGS_T uiPdumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMMUContext);
+       PVR_UNREFERENCED_PARAMETER(pszSpaceName);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32WordSize);
+       PVR_UNREFERENCED_PARAMETER(ui32AlignShift);
+       PVR_UNREFERENCED_PARAMETER(ui32Shift);
+       PVR_UNREFERENCED_PARAMETER(uiPdumpFlags);
+}
+#endif /* PDUMP */
+
+
+#endif /* #ifdef MMU_COMMON_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/osconnection_server.h b/drivers/gpu/rogue_m/services/server/include/osconnection_server.h
new file mode 100644 (file)
index 0000000..dbd2f66
--- /dev/null
@@ -0,0 +1,89 @@
+/**************************************************************************/ /*!
+@File
+@Title          Server side connection management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    API for OS specific callbacks from server side connection
+                management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+#ifndef _OSCONNECTION_SERVER_H_
+#define _OSCONNECTION_SERVER_H_
+
+#include "handle.h"
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, IMG_PVOID pvOSData);
+PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
+
+PVRSRV_ERROR OSConnectionSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+#else  /* defined(__linux__) */
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSConnectionPrivateDataInit)
+#endif
+static INLINE PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, IMG_PVOID pvOSData)
+{
+       PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
+       PVR_UNREFERENCED_PARAMETER(pvOSData);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSConnectionPrivateDataDeInit)
+#endif
+static INLINE PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
+{
+       PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSPerProcessSetHandleOptions)
+#endif
+static INLINE PVRSRV_ERROR OSConnectionSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+       PVR_UNREFERENCED_PARAMETER(psHandleBase);
+
+       return PVRSRV_OK;
+}
+#endif /* defined(__linux__) */
+
+
+#endif /* _OSCONNECTION_SERVER_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/osfunc.h b/drivers/gpu/rogue_m/services/server/include/osfunc.h
new file mode 100644 (file)
index 0000000..77e95b4
--- /dev/null
@@ -0,0 +1,467 @@
+/**************************************************************************/ /*!
+@File
+@Title          OS functions header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS specific API definitions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifdef DEBUG_RELEASE_BUILD
+#pragma optimize( "", off )
+#define DEBUG          1
+#endif
+
+#ifndef __OSFUNC_H__
+#define __OSFUNC_H__
+
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+#if defined(__QNXNTO__)
+#include <string.h>
+#endif
+
+#include "img_types.h"
+#include "pvrsrv_device.h"
+#include "device.h"
+
+/******************************************************************************
+ * Static defines
+ *****************************************************************************/
+#define KERNEL_ID                      0xffffffffL
+#define ISR_ID                         0xfffffffdL
+
+IMG_UINT64 OSClockns64(IMG_VOID);
+IMG_UINT64 OSClockus64(IMG_VOID);
+IMG_UINT32 OSClockus(IMG_VOID);
+IMG_UINT32 OSClockms(IMG_VOID);
+
+IMG_SIZE_T OSGetPageSize(IMG_VOID);
+IMG_SIZE_T OSGetPageShift(IMG_VOID);
+IMG_SIZE_T OSGetPageMask(IMG_VOID);
+
+typedef IMG_VOID (*PFN_THREAD)(IMG_PVOID pvData);
+
+PVRSRV_ERROR OSInstallDeviceLISR(PVRSRV_DEVICE_CONFIG *psDevConfig,
+                                                                IMG_HANDLE *hLISRData,
+                                                                PFN_LISR pfnLISR,
+                                                                IMG_VOID *hData);
+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_HANDLE hLISRData);
+
+PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData,
+                                                  PFN_MISR pfnMISR,
+                                                  IMG_VOID *hData);
+PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData);
+PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData);
+
+
+
+
+/*************************************************************************/ /*!
+@Function       OSThreadCreate
+@Description    Creates a kernel thread and starts it running. The caller
+                is responsible for informing the thread that it must finish
+                and return from the pfnThread function. It is not possible
+                to kill or terminate it.The new thread runs with the default
+                priority provided by the Operating System.
+@Output         phThread       Returned handle to the thread.
+@Input          pszThreadName  Name to assign to the thread.
+@Input          pfnThread      Thread entry point function.
+@Input          hData          Thread specific data pointer for pfnThread().
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+
+PVRSRV_ERROR OSThreadCreate(IMG_HANDLE *phThread,
+                                                       IMG_CHAR *pszThreadName,
+                                                       PFN_THREAD pfnThread,
+                                                       IMG_VOID *hData);
+
+/*! Available priority levels for the creation of a new Kernel Thread. */
+typedef enum priority_levels
+{
+       HIGHEST_PRIORITY = 0,
+       HIGH_PRIRIOTY,
+       NORMAL_PRIORITY,
+       LOW_PRIORITY,
+       LOWEST_PRIORITY,
+       NOSET_PRIORITY,   /* With this option the priority level is is the default for the given OS */
+       LAST_PRIORITY     /* This must be always the last entry */
+} OS_THREAD_LEVEL;
+
+/*************************************************************************/ /*!
+@Function       OSThreadCreatePriority
+@Description    As OSThreadCreate, this function creates a kernel thread and
+                starts it running. The difference is that with this function
+                is possible to specify the priority used to schedule the new
+                thread.
+
+@Output         phThread        Returned handle to the thread.
+@Input          pszThreadName   Name to assign to the thread.
+@Input          pfnThread       Thread entry point function.
+@Input          hData           Thread specific data pointer for pfnThread().
+@Input          eThreadPriority Priority level to assign to the new thread.
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSThreadCreatePriority(IMG_HANDLE *phThread,
+                                    IMG_CHAR *pszThreadName,
+                                    PFN_THREAD pfnThread,
+                                    IMG_VOID *hData,
+                                    OS_THREAD_LEVEL eThreadPriority);
+
+/*************************************************************************/ /*!
+@Function       OSThreadDestroy
+@Description    Waits for the thread to end and then destroys the thread
+                handle memory. This function will block and wait for the
+                thread to finish successfully, thereby providing a sync point
+                for the thread completing its work. No attempt is made to kill
+                or otherwise terminate the thread.
+@Input          phThread  The thread handle returned by OSThreadCreate().
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSThreadDestroy(IMG_HANDLE hThread);
+
+void PVRSRVDeviceMemSet(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size);
+void PVRSRVDeviceMemCopy(void *pvDst, const void *pvSrc, size_t ui32Size);
+
+#if defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_SAFE_MEMSETCPY)
+#define OSDeviceMemSet(a,b,c) PVRSRVDeviceMemSet((a), (b), (c))
+#define OSDeviceMemCopy(a,b,c) PVRSRVDeviceMemCopy((a), (b), (c))
+#define OSMemSet(a,b,c)  PVRSRVDeviceMemSet((a), (b), (c))
+#define OSMemCopy(a,b,c)  PVRSRVDeviceMemCopy((a), (b), (c))
+#else
+#define OSDeviceMemSet(a,b,c) memset((a), (b), (c))
+#define OSDeviceMemCopy(a,b,c) memcpy((a), (b), (c))
+#define OSMemSet(a,b,c)  memset((a), (b), (c))
+#define OSMemCopy(a,b,c)  memcpy((a), (b), (c))
+#endif
+
+#define OSCachedMemSet(a,b,c) memset((a), (b), (c))
+#define OSCachedMemCopy(a,b,c) memcpy((a), (b), (c))
+
+IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
+IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
+
+
+IMG_VOID OSCPUOperation(PVRSRV_CACHE_OP eCacheOp);
+
+IMG_VOID OSFlushCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                               IMG_PVOID pvVirtEnd,
+                                                               IMG_CPU_PHYADDR sCPUPhysStart,
+                                                               IMG_CPU_PHYADDR sCPUPhysEnd);
+
+
+IMG_VOID OSCleanCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                               IMG_PVOID pvVirtEnd,
+                                                               IMG_CPU_PHYADDR sCPUPhysStart,
+                                                               IMG_CPU_PHYADDR sCPUPhysEnd);
+
+IMG_VOID OSInvalidateCPUCacheRangeKM(IMG_PVOID pvVirtStart,
+                                                                        IMG_PVOID pvVirtEnd,
+                                                                        IMG_CPU_PHYADDR sCPUPhysStart,
+                                                                        IMG_CPU_PHYADDR sCPUPhysEnd);
+
+
+IMG_PID OSGetCurrentProcessID(IMG_VOID);
+IMG_CHAR *OSGetCurrentProcessName(IMG_VOID);
+IMG_UINTPTR_T OSGetCurrentThreadID(IMG_VOID);
+
+IMG_INT OSMemCmp(IMG_VOID *pvBufA, IMG_VOID *pvBufB, IMG_SIZE_T uiLen);
+
+PVRSRV_ERROR OSMMUPxAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize,
+                                                       Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_VOID OSMMUPxFree(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle);
+
+PVRSRV_ERROR OSMMUPxMap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                               IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+                                               IMG_VOID **pvPtr);
+
+IMG_VOID OSMMUPxUnmap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle, IMG_VOID *pvPtr);
+
+
+PVRSRV_ERROR OSInitEnvData(IMG_VOID);
+IMG_VOID OSDeInitEnvData(IMG_VOID);
+
+IMG_CHAR* OSStringNCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, IMG_SIZE_T uSize);
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+IMG_SIZE_T OSStringLength(const IMG_CHAR *pStr);
+IMG_SIZE_T OSStringNLength(const IMG_CHAR *pStr, IMG_SIZE_T uiCount);
+IMG_INT32 OSStringCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2);
+
+PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName,
+                                                                IMG_HANDLE *EventObject);
+PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject);
+PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject);
+PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs);
+PVRSRV_ERROR OSEventObjectWaitAndHoldBridgeLock(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs);
+PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject,
+                                                                                       IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM);
+
+/* Avoid macros so we don't evaluate pszSrc twice */
+static INLINE IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
+{
+       IMG_CHAR  *result; /* Helps with klocwork, will be optimised away */
+
+       result = OSStringNCopy(pszDest, pszSrc, OSStringLength(pszSrc)+1);
+#if defined(__KLOCWORK__)
+       pszDest[OSStringLength(pszSrc)] = '\0';
+#endif
+       return result;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSWaitus
+ @Description 
+    This function implements a busy wait of the specified microseconds
+    This function does NOT release thread quanta
+ @Input ui32Timeus - (us)
+
+ @Return IMG_VOID
+
+******************************************************************************/ 
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
+
+
+/*!
+******************************************************************************
+
+ @Function OSSleepms
+ @Description 
+    This function implements a sleep of the specified milliseconds
+    This function may allow pre-emption if implemented
+ @Input ui32Timems - (ms)
+
+ @Return IMG_VOID
+
+******************************************************************************/ 
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems);
+
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID);
+
+IMG_UINT8 OSReadHWReg8(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+IMG_UINT16 OSReadHWReg16(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+IMG_UINT32 OSReadHWReg32(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+IMG_UINT64 OSReadHWReg64(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+IMG_UINT64 OSReadHWRegBank(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8DstBuf, IMG_UINT64 ui64DstBufLen);
+
+IMG_VOID OSWriteHWReg8(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 ui32Value);
+IMG_VOID OSWriteHWReg16(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT16 ui32Value);
+IMG_VOID OSWriteHWReg32(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+IMG_VOID OSWriteHWReg64(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value);
+IMG_UINT64 OSWriteHWRegBank(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8SrcBuf, IMG_UINT64 ui64rcBufLen);
+
+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);
+
+
+/******************************************************************************
+
+ @Function             OSPanic
+
+ @Description  Take action in response to an unrecoverable driver error
+
+ @Input    IMG_VOID
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+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, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+
+#if defined (__linux__)
+#define OSBridgeCopyFromUser OSCopyFromUser
+#define OSBridgeCopyToUser OSCopyToUser
+#else
+PVRSRV_ERROR OSBridgeCopyFromUser (IMG_PVOID pvProcess,
+                                               IMG_PVOID pvDest,
+                                               const IMG_PVOID pvSrc,
+                                               IMG_SIZE_T ui32Bytes);
+PVRSRV_ERROR OSBridgeCopyToUser (IMG_PVOID pvProcess,
+                                               IMG_VOID *pvDest,
+                                               const IMG_VOID *pvSrc,
+                                               IMG_SIZE_T ui32Bytes);
+#endif
+
+/* Fairly arbitrary sizes - hopefully enough for all bridge calls */
+#define PVRSRV_MAX_BRIDGE_IN_SIZE      0x2000
+#define PVRSRV_MAX_BRIDGE_OUT_SIZE     0x1000
+
+PVRSRV_ERROR OSGetGlobalBridgeBuffers (IMG_VOID **ppvBridgeInBuffer,
+                                                       IMG_UINT32 *pui32BridgeInBufferSize,
+                                                       IMG_VOID **ppvBridgeOutBuffer,
+                                                       IMG_UINT32 *pui32BridgeOutBufferSize);
+
+IMG_BOOL OSSetDriverSuspended(void);
+IMG_BOOL OSClearDriverSuspended(void);
+IMG_BOOL OSGetDriverSuspended(void);
+
+IMG_VOID OSWriteMemoryBarrier(IMG_VOID);
+IMG_VOID OSMemoryBarrier(IMG_VOID);
+
+#if defined(LINUX) && defined(__KERNEL__)
+
+/* Provide LockDep friendly definitions for Services RW locks */
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include "allocmem.h"
+
+typedef struct rw_semaphore *POSWR_LOCK;
+
+#define OSWRLockCreate(ppsLock) ({ \
+       PVRSRV_ERROR e = PVRSRV_ERROR_OUT_OF_MEMORY; \
+       *(ppsLock) = OSAllocMem(sizeof(struct rw_semaphore)); \
+       if (*(ppsLock)) { init_rwsem(*(ppsLock)); e = PVRSRV_OK; }; \
+       e;})
+#define OSWRLockDestroy(psLock) ({OSFreeMem(psLock); PVRSRV_OK;})
+
+#define OSWRLockAcquireRead(psLock) ({down_read(psLock); PVRSRV_OK;})
+#define OSWRLockReleaseRead(psLock) ({up_read(psLock); PVRSRV_OK;})
+#define OSWRLockAcquireWrite(psLock) ({down_write(psLock); PVRSRV_OK;})
+#define OSWRLockReleaseWrite(psLock) ({up_write(psLock); PVRSRV_OK;})
+
+#elif defined(LINUX) || defined(__QNXNTO__)
+/* User-mode unit tests use these definitions on Linux */
+
+typedef struct _OSWR_LOCK_ *POSWR_LOCK;
+
+PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock);
+IMG_VOID OSWRLockDestroy(POSWR_LOCK psLock);
+IMG_VOID OSWRLockAcquireRead(POSWR_LOCK psLock);
+IMG_VOID OSWRLockReleaseRead(POSWR_LOCK psLock);
+IMG_VOID OSWRLockAcquireWrite(POSWR_LOCK psLock);
+IMG_VOID OSWRLockReleaseWrite(POSWR_LOCK psLock);
+
+#else
+struct _OSWR_LOCK_ {
+       IMG_UINT32 ui32Dummy;
+};
+static INLINE PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock)
+{
+       PVR_UNREFERENCED_PARAMETER(ppsLock);
+       return PVRSRV_OK;
+}
+
+static INLINE IMG_VOID OSWRLockDestroy(POSWR_LOCK psLock)
+{
+       PVR_UNREFERENCED_PARAMETER(psLock);
+}
+
+static INLINE IMG_VOID OSWRLockAcquireRead(POSWR_LOCK psLock)
+{
+       PVR_UNREFERENCED_PARAMETER(psLock);
+}
+
+static INLINE IMG_VOID OSWRLockReleaseRead(POSWR_LOCK psLock)
+{
+       PVR_UNREFERENCED_PARAMETER(psLock);
+}
+
+static INLINE IMG_VOID OSWRLockAcquireWrite(POSWR_LOCK psLock)
+{
+       PVR_UNREFERENCED_PARAMETER(psLock);
+}
+
+static INLINE IMG_VOID OSWRLockReleaseWrite(POSWR_LOCK psLock)
+{
+       PVR_UNREFERENCED_PARAMETER(psLock);
+}
+#endif
+
+IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder);
+IMG_UINT32 OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder);
+
+IMG_VOID OSDumpStack(IMG_VOID);
+
+IMG_VOID OSAcquireBridgeLock(IMG_VOID);
+IMG_VOID OSReleaseBridgeLock(IMG_VOID);
+
+
+/*
+ *  Functions for providing support for PID statistics.
+ */
+typedef void (OS_STATS_PRINTF_FUNC)(IMG_PVOID pvFilePtr, const IMG_CHAR *pszFormat, ...);
+typedef void (OS_STATS_PRINT_FUNC)(IMG_PVOID pvFilePtr,
+                                                                  IMG_PVOID pvStatPtr,
+                                   OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
+
+typedef IMG_UINT32 (OS_INC_STATS_MEM_REFCOUNT_FUNC)(IMG_PVOID pvStatPtr);
+typedef IMG_UINT32 (OS_DEC_STATS_MEM_REFCOUNT_FUNC)(IMG_PVOID pvStatPtr);
+IMG_PVOID OSCreateStatisticEntry(IMG_CHAR* pszName, IMG_PVOID pvFolder,
+                                 OS_STATS_PRINT_FUNC* pfnStatsPrint,
+                                                                OS_INC_STATS_MEM_REFCOUNT_FUNC* pfnIncMemRefCt,
+                                                                OS_DEC_STATS_MEM_REFCOUNT_FUNC* pfnDecMemRefCt,
+                                 IMG_PVOID pvData);
+IMG_VOID OSRemoveStatisticEntry(IMG_PVOID pvEntry);
+IMG_PVOID OSCreateStatisticFolder(IMG_CHAR *pszName, IMG_PVOID pvFolder);
+IMG_VOID OSRemoveStatisticFolder(IMG_PVOID pvFolder);
+
+
+#endif /* __OSFUNC_H__ */
+
+/******************************************************************************
+ End of file (osfunc.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/server/include/ossecure_export.h b/drivers/gpu/rogue_m/services/server/include/ossecure_export.h
new file mode 100644 (file)
index 0000000..c1c43e1
--- /dev/null
@@ -0,0 +1,52 @@
+/**************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "connection_server.h"
+
+PVRSRV_ERROR OSSecureExport(CONNECTION_DATA *psConnection,
+                                                       IMG_PVOID pvData,
+                                                       IMG_SECURE_TYPE *phSecure,
+                                                       CONNECTION_DATA **ppsSecureConnection);
+                                                       
+PVRSRV_ERROR OSSecureImport(IMG_SECURE_TYPE hSecure, IMG_PVOID *ppvData);
+
diff --git a/drivers/gpu/rogue_m/services/server/include/pdump_km.h b/drivers/gpu/rogue_m/services/server/include/pdump_km.h
new file mode 100644 (file)
index 0000000..4e49c01
--- /dev/null
@@ -0,0 +1,731 @@
+/*************************************************************************/ /*!
+@File
+@Title          pdump functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main APIs for pdump functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PDUMP_KM_H_
+#define _PDUMP_KM_H_
+
+/* services/srvkm/include/ */
+#include "device.h"
+
+/* include/ */
+#include "pvrsrv_error.h"
+#include "services.h"
+
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+#include "connection_server.h"
+#include "sync_server.h"
+/*
+ *     Pull in pdump flags from services include
+ */
+#include "pdump.h"
+#include "pdumpdefs.h"
+
+/* Define this to enable the PDUMP_HERE trace in the server */
+#undef PDUMP_TRACE
+
+#if defined(PDUMP_TRACE)
+#define PDUMP_HERE(a)  if (ui32Flags & PDUMP_FLAGS_DEBUG) PVR_DPF((PVR_DBG_WARNING, "HERE %d", (a)))
+#define PDUMP_HEREA(a) PVR_DPF((PVR_DBG_WARNING, "HERE ALWAYS %d", (a)))
+#else
+#define PDUMP_HERE(a)  (void)(a);
+#define PDUMP_HEREA(a) (void)(a);
+#endif
+
+#define PDUMP_PD_UNIQUETAG     (IMG_HANDLE)0
+#define PDUMP_PT_UNIQUETAG     (IMG_HANDLE)0
+
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+/* counter increments each time debug write is called */
+extern IMG_UINT32 g_ui32EveryLineCounter;
+#endif
+
+typedef struct _PDUMP_CONNECTION_DATA_ PDUMP_CONNECTION_DATA;
+typedef PVRSRV_ERROR (*PFN_PDUMP_TRANSITION)(IMG_PVOID *pvData, IMG_BOOL bInto, IMG_BOOL bContinuous);
+
+/*! Macro used to record a panic in the PDump script stream */
+#define PDUMP_PANIC(_type, _id, _msg) do \
+               { PVRSRV_ERROR _eE;\
+                       _eE = PDumpPanic((PVRSRV_DEVICE_TYPE_ ## _type)<<16 | ((_type ## _PDUMP_PANIC_ ## _id)&0xFFFF), _msg, __FUNCTION__, __LINE__);\
+                       PVR_LOG_IF_ERROR(_eE, "PDumpPanic");\
+               MSC_SUPPRESS_4127\
+               } while (0)
+
+#ifdef PDUMP
+       /* Shared across pdump_x files */
+       PVRSRV_ERROR PDumpInitCommon(IMG_VOID);
+       IMG_VOID PDumpDeInitCommon(IMG_VOID);
+       IMG_BOOL PDumpReady(IMG_VOID);
+       IMG_VOID PDumpGetParameterZeroPageInfo(PDUMP_FILEOFFSET_T *puiZeroPageOffset,
+                                                                       IMG_SIZE_T *puiZeroPageSize,
+                                                                       const IMG_CHAR **ppszZeroPageFilename);
+
+       IMG_VOID PDumpConnectionNotify(IMG_VOID);
+       void PDumpDisconnectionNotify(void);
+
+       PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID);
+       PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_MODULE_ID eModuleID);
+       PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32 ui32Frame);
+       PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32* pui32Frame);
+       PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags);
+
+       PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(IMG_UINT32 ui32Mode,
+                                                  IMG_UINT32 ui32Start,
+                                                  IMG_UINT32 ui32End,
+                                                  IMG_UINT32 ui32Interval,
+                                                  IMG_UINT32 ui32MaxParamFileSize);
+
+
+       PVRSRV_ERROR PDumpReg32(IMG_CHAR        *pszPDumpRegName,
+                                                       IMG_UINT32      ui32RegAddr,
+                                                       IMG_UINT32      ui32RegValue,
+                                                       IMG_UINT32      ui32Flags);
+
+       PVRSRV_ERROR PDumpReg64(IMG_CHAR        *pszPDumpRegName,
+                                                       IMG_UINT32      ui32RegAddr,
+                                                       IMG_UINT64      ui64RegValue,
+                                                       IMG_UINT32      ui32Flags);
+
+       PVRSRV_ERROR PDumpLDW(IMG_CHAR      *pcBuffer,
+                             IMG_CHAR      *pszDevSpaceName,
+                             IMG_UINT32    ui32OffsetBytes,
+                             IMG_UINT32    ui32NumLoadBytes,
+                             PDUMP_FLAGS_T uiPDumpFlags);
+
+       PVRSRV_ERROR PDumpSAW(IMG_CHAR      *pszDevSpaceName,
+                             IMG_UINT32    ui32HPOffsetBytes,
+                             IMG_UINT32    ui32NumSaveBytes,
+                             IMG_CHAR      *pszOutfileName,
+                             IMG_UINT32    ui32OutfileOffsetByte,
+                             PDUMP_FLAGS_T uiPDumpFlags);
+
+       PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR                             *pszPDumpRegName,
+                                                          IMG_UINT32                   ui32RegAddr,
+                                                          IMG_UINT32                   ui32RegValue,
+                                                          IMG_UINT32                   ui32Mask,
+                                                          IMG_UINT32                   ui32Flags,
+                                                          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_UINT32 ui32MMUContextID,
+                                                                                 IMG_UINT32 ui32Size,
+                                                                                 PDUMP_PIXEL_FORMAT ePixelFormat,
+                                                                                 IMG_UINT32 ui32AddrMode,
+                                                                                 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 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 PDumpPanic(IMG_UINT32      ui32PanicNo,
+                                                       IMG_CHAR*       pszPanicMsg,
+                                                       const IMG_CHAR* pszPPFunc,
+                                                       IMG_UINT32      ui32PPline);
+
+       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);
+
+       PVRSRV_ERROR PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing);
+
+       IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER  *psDevID,
+                                                                 IMG_UINT64                    ui64DevVAddr,
+                                                                 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 PDumpRegRead32(IMG_CHAR *pszPDumpRegName,
+                                                               const IMG_UINT32 dwRegOffset,
+                                                               IMG_UINT32      ui32Flags);
+       PVRSRV_ERROR PDumpRegRead64(IMG_CHAR *pszPDumpRegName,
+                                                               const IMG_UINT32 dwRegOffset,
+                                                               IMG_UINT32      ui32Flags);
+
+       PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
+       PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
+
+       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 PDumpRegBasedCBP(IMG_CHAR          *pszPDumpRegName,
+                                                                 IMG_UINT32    ui32RegOffset,
+                                                                 IMG_UINT32    ui32WPosVal,
+                                                                 IMG_UINT32    ui32PacketSize,
+                                                                 IMG_UINT32    ui32BufferSize,
+                                                                 IMG_UINT32    ui32Flags);
+
+       PVRSRV_ERROR PDumpTRG(IMG_CHAR *pszMemSpace,
+                             IMG_UINT32 ui32MMUCtxID,
+                             IMG_UINT32 ui32RegionID,
+                             IMG_BOOL bEnable,
+                             IMG_UINT64 ui64VAddr,
+                             IMG_UINT64 ui64LenBytes,
+                             IMG_UINT32 ui32XStride,
+                             IMG_UINT32 ui32Flags);
+
+       PVRSRV_ERROR PDumpCreateLockKM(IMG_VOID);
+       IMG_VOID PDumpDestroyLockKM(IMG_VOID);
+       IMG_VOID PDumpLockKM(IMG_VOID);
+       IMG_VOID PDumpUnlockKM(IMG_VOID);
+
+       /*
+           Process persistence common API for use by common
+           clients e.g. mmu and physmem.
+        */
+       IMG_BOOL PDumpIsPersistent(IMG_VOID);
+       PVRSRV_ERROR PDumpAddPersistantProcess(IMG_VOID);
+
+       PVRSRV_ERROR PDumpIfKM(IMG_CHAR         *pszPDumpCond);
+       PVRSRV_ERROR PDumpElseKM(IMG_CHAR       *pszPDumpCond);
+       PVRSRV_ERROR PDumpFiKM(IMG_CHAR         *pszPDumpCond);
+
+       IMG_VOID PDumpPowerTransitionStart(IMG_VOID);
+       IMG_VOID PDumpPowerTransitionEnd(IMG_VOID);
+       IMG_BOOL PDumpInPowerTransition(IMG_VOID);
+       IMG_BOOL PDumpIsDumpSuspended(IMG_VOID);
+
+       /*!
+        * @name        PDumpWriteParameter
+        * @brief       General function for writing to PDump stream. Used
+        *          mainly for memory dumps to parameter stream.
+        *                      Usually more convenient to use PDumpWriteScript below
+        *                      for the script stream.
+        * @param       psui8Data - data to write
+        * @param       ui32Size - size of write
+        * @param       ui32Flags - PDump flags
+        * @param   pui32FileOffset - on return contains the file offset to
+        *                            the start of the parameter data
+        * @param   aszFilenameStr - pointer to at least a 20 char buffer to
+        *                           return the parameter filename
+        * @return      error
+        */
+       PVRSRV_ERROR PDumpWriteParameter(IMG_UINT8 *psui8Data, IMG_UINT32 ui32Size,
+                       IMG_UINT32 ui32Flags, IMG_UINT32* pui32FileOffset,
+                       IMG_CHAR* aszFilenameStr);
+
+       /*!
+        * @name        PDumpWriteScript
+        * @brief       Write an PDumpOS created string to the "script" output stream
+        * @param       hString - PDump OS layer handle of string buffer to write
+        * @param       ui32Flags - PDump flags
+        * @return      IMG_TRUE on success.
+        */
+       IMG_BOOL PDumpWriteScript(IMG_HANDLE hString, IMG_UINT32 ui32Flags);
+
+    /*
+      PDumpWriteShiftedMaskedValue():
+
+      loads the "reference" address into an internal PDump register,
+      optionally shifts it right,
+      optionally shifts it left,
+      optionally masks it
+      then finally writes the computed value to the given destination address
+
+      i.e. it emits pdump language equivalent to this expression:
+
+      dest = ((&ref) >> SHRamount << SHLamount) & MASK
+    */
+extern PVRSRV_ERROR
+PDumpWriteShiftedMaskedValue(const IMG_CHAR *pszDestRegspaceName,
+                             const IMG_CHAR *pszDestSymbolicName,
+                             IMG_DEVMEM_OFFSET_T uiDestOffset,
+                             const IMG_CHAR *pszRefRegspaceName,
+                             const IMG_CHAR *pszRefSymbolicName,
+                             IMG_DEVMEM_OFFSET_T uiRefOffset,
+                             IMG_UINT32 uiSHRAmount,
+                             IMG_UINT32 uiSHLAmount,
+                             IMG_UINT32 uiMask,
+                             IMG_DEVMEM_SIZE_T uiWordSize,
+                             IMG_UINT32 uiPDumpFlags);
+
+    /*
+      PDumpWriteSymbAddress():
+
+      writes the address of the "reference" to the offset given
+    */
+extern PVRSRV_ERROR
+PDumpWriteSymbAddress(const IMG_CHAR *pszDestSpaceName,
+                      IMG_DEVMEM_OFFSET_T uiDestOffset,
+                      const IMG_CHAR *pszRefSymbolicName,
+                      IMG_DEVMEM_OFFSET_T uiRefOffset,
+                      const IMG_CHAR *pszPDumpDevName,
+                      IMG_UINT32 ui32WordSize,
+                      IMG_UINT32 ui32AlignShift,
+                      IMG_UINT32 ui32Shift,
+                      IMG_UINT32 uiPDumpFlags);
+
+/* Register the connection with the PDump subsystem */
+extern PVRSRV_ERROR PDumpRegisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData,
+                                                                                       PDUMP_CONNECTION_DATA **ppsPDumpConnectionData);
+
+/* Unregister the connection with the PDump subsystem */
+extern IMG_VOID PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData);
+
+/* Register for notification of PDump Transition into/out of capture range */
+extern PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData,
+                                                                                                        PFN_PDUMP_TRANSITION pfnCallback,
+                                                                                                        IMG_PVOID hPrivData,
+                                                                                                        IMG_PVOID *ppvHandle);
+
+/* Unregister notification of PDump Transition */
+extern IMG_VOID PDumpUnregisterTransitionCallback(IMG_PVOID pvHandle);
+
+/* Notify PDump of a Transition into/out of capture range */
+extern PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous);
+   
+       #define PDUMP_LOCK                              PDumpLockKM
+       #define PDUMP_UNLOCK                    PDumpUnlockKM
+
+       #define PDUMPINIT                               PDumpInitCommon
+       #define PDUMPDEINIT                             PDumpDeInitCommon
+       #define PDUMPREG32                              PDumpReg32
+       #define PDUMPREG64                              PDumpReg64
+       #define PDUMPREGREAD32                  PDumpRegRead32
+       #define PDUMPREGREAD64                  PDumpRegRead64
+       #define PDUMPCOMMENT                    PDumpComment
+       #define PDUMPCOMMENTWITHFLAGS   PDumpCommentWithFlags
+       #define PDUMPREGPOL                             PDumpRegPolKM
+       #define PDUMPSETMMUCONTEXT              PDumpSetMMUContext
+       #define PDUMPCLEARMMUCONTEXT    PDumpClearMMUContext
+       #define PDUMPPDREG                              PDumpPDReg
+       #define PDUMPPDREGWITHFLAGS             PDumpPDRegWithFlags
+       #define PDUMPREGBASEDCBP                PDumpRegBasedCBP
+       #define PDUMPENDINITPHASE               PDumpStopInitPhaseKM
+       #define PDUMPIDLWITHFLAGS               PDumpIDLWithFlags
+       #define PDUMPIDL                                PDumpIDL
+       #define PDUMPPOWCMDSTART                PDumpPowerTransitionStart
+       #define PDUMPPOWCMDEND                  PDumpPowerTransitionEnd
+       #define PDUMPPOWCMDINTRANS              PDumpInPowerTransition
+       #define PDUMPIF                                 PDumpIfKM
+       #define PDUMPELSE                               PDumpElseKM
+       #define PDUMPFI                                 PDumpFiKM
+#else
+       /*
+               We should be clearer about which functions can be called
+               across the bridge as this looks rather unblanced
+       */
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpInitCommon)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpInitCommon(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpConnectionNotify)
+#endif
+static INLINE IMG_VOID
+PDumpConnectionNotify(IMG_VOID)
+{
+       return;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpDisconnectionNotify)
+#endif
+static INLINE void
+PDumpDisconnectionNotify(void)
+{
+       return;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpCreateLockKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpCreateLockKM(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpDestroyLockKM)
+#endif
+static INLINE IMG_VOID
+PDumpDestroyLockKM(IMG_VOID)
+{
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpLockKM)
+#endif
+static INLINE IMG_VOID
+PDumpLockKM(IMG_VOID)
+{
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpUnlockKM)
+#endif
+static INLINE IMG_VOID
+PDumpUnlockKM(IMG_VOID)
+{
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpAddPersistantProcess)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpAddPersistantProcess(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpStartInitPhaseKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpStartInitPhaseKM(IMG_VOID)
+{
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpStopInitPhaseKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpStopInitPhaseKM(IMG_MODULE_ID eModuleID)
+{
+       PVR_UNREFERENCED_PARAMETER(eModuleID);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpSetFrameKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpSetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32 ui32Frame)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(ui32Frame);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpGetFrameKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpGetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32* pui32Frame)
+{
+       PVR_UNREFERENCED_PARAMETER(psConnection);
+       PVR_UNREFERENCED_PARAMETER(pui32Frame);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpCommentKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
+{
+       PVR_UNREFERENCED_PARAMETER(pszComment);
+       PVR_UNREFERENCED_PARAMETER(ui32Flags);
+       return PVRSRV_OK;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpCommentKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpSetDefaultCaptureParamsKM(IMG_UINT32 ui32Mode,
+                              IMG_UINT32 ui32Start,
+                              IMG_UINT32 ui32End,
+                              IMG_UINT32 ui32Interval,
+                              IMG_UINT32 ui32MaxParamFileSize)
+{
+       PVR_UNREFERENCED_PARAMETER(ui32Mode);
+       PVR_UNREFERENCED_PARAMETER(ui32Start);
+       PVR_UNREFERENCED_PARAMETER(ui32End);
+       PVR_UNREFERENCED_PARAMETER(ui32Interval);
+       PVR_UNREFERENCED_PARAMETER(ui32MaxParamFileSize);
+
+       return PVRSRV_OK;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpPanic)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpPanic(IMG_UINT32      ui32PanicNo,
+                  IMG_CHAR*       pszPanicMsg,
+                  const IMG_CHAR* pszPPFunc,
+                  IMG_UINT32      ui32PPline)
+{
+       PVR_UNREFERENCED_PARAMETER(ui32PanicNo);
+       PVR_UNREFERENCED_PARAMETER(pszPanicMsg);
+       PVR_UNREFERENCED_PARAMETER(pszPPFunc);
+       PVR_UNREFERENCED_PARAMETER(ui32PPline);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpIsLastCaptureFrameKM)
+#endif
+static INLINE IMG_BOOL
+PDumpIsLastCaptureFrameKM(IMG_VOID)
+{
+       return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpIsCaptureFrameKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing)
+{
+       *bIsCapturing = IMG_FALSE;
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpBitmapKM)
+#endif
+static INLINE 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_UINT32 ui32MMUContextID,
+                                                                                 IMG_UINT32 ui32Size,
+                                                                                 PDUMP_PIXEL_FORMAT ePixelFormat,
+                                                                                 IMG_UINT32 ui32AddrMode,
+                                                                                 IMG_UINT32 ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+       PVR_UNREFERENCED_PARAMETER(pszFileName);
+       PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Width);
+       PVR_UNREFERENCED_PARAMETER(ui32Height);
+       PVR_UNREFERENCED_PARAMETER(ui32StrideInBytes);
+       PVR_UNREFERENCED_PARAMETER(sDevBaseAddr);
+       PVR_UNREFERENCED_PARAMETER(ui32MMUContextID);
+       PVR_UNREFERENCED_PARAMETER(ui32Size);
+       PVR_UNREFERENCED_PARAMETER(ePixelFormat);
+       PVR_UNREFERENCED_PARAMETER(ui32AddrMode);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpRegisterConnection)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpRegisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData,
+                                               PDUMP_CONNECTION_DATA **ppsPDumpConnectionData)
+{
+       PVR_UNREFERENCED_PARAMETER(psSyncConnectionData);
+       PVR_UNREFERENCED_PARAMETER(ppsPDumpConnectionData);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpUnregisterConnection)
+#endif
+static INLINE
+IMG_VOID PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
+{
+       PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpRegisterTransitionCallback)
+#endif
+static INLINE
+PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData,
+                                                                                         PFN_PDUMP_TRANSITION pfnCallback,
+                                                                                         IMG_PVOID hPrivData,
+                                                                                         IMG_PVOID *ppvHandle)
+{
+       PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData);
+       PVR_UNREFERENCED_PARAMETER(pfnCallback);
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+       PVR_UNREFERENCED_PARAMETER(ppvHandle);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpUnregisterTransitionCallback)
+#endif
+static INLINE
+IMG_VOID PDumpUnregisterTransitionCallback(IMG_PVOID pvHandle)
+{
+       PVR_UNREFERENCED_PARAMETER(pvHandle);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PDumpTransition)
+#endif
+static INLINE
+PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous)
+{
+       PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData);
+       PVR_UNREFERENCED_PARAMETER(bInto);
+       PVR_UNREFERENCED_PARAMETER(bContinuous);
+       return PVRSRV_OK;
+}
+
+       #if defined WIN32
+               #define PDUMPINIT                       PDumpInitCommon
+               #define PDUMPDEINIT(...)                / ## * PDUMPDEINIT(__VA_ARGS__) * ## /
+               #define PDUMPREG32(...)                 / ## * PDUMPREG32(__VA_ARGS__) * ## /
+               #define PDUMPREG64(...)                 / ## * PDUMPREG64(__VA_ARGS__) * ## /
+               #define PDUMPREGREAD32(...)                     / ## * PDUMPREGREAD32(__VA_ARGS__) * ## /
+               #define PDUMPREGREAD64(...)                     / ## * PDUMPREGREAD64(__VA_ARGS__) * ## /
+               #define PDUMPCOMMENT(...)               / ## * PDUMPCOMMENT(__VA_ARGS__) * ## /
+               #define PDUMPREGPOL(...)                / ## * PDUMPREGPOL(__VA_ARGS__) * ## /
+               #define PDUMPSETMMUCONTEXT(...)         / ## * PDUMPSETMMUCONTEXT(__VA_ARGS__) * ## /
+               #define PDUMPCLEARMMUCONTEXT(...)       / ## * PDUMPCLEARMMUCONTEXT(__VA_ARGS__) * ## /
+               #define PDUMPPDREG(...)                 / ## * PDUMPPDREG(__VA_ARGS__) * ## /
+               #define PDUMPPDREGWITHFLAGS(...)        / ## * PDUMPPDREGWITHFLAGS(__VA_ARGS__) * ## /
+               #define PDUMPSYNC(...)                  / ## * PDUMPSYNC(__VA_ARGS__) * ## /
+               #define PDUMPCOPYTOMEM(...)             / ## * PDUMPCOPYTOMEM(__VA_ARGS__) * ## /
+               #define PDUMPWRITE(...)                 / ## * PDUMPWRITE(__VA_ARGS__) * ## /
+               #define PDUMPCBP(...)                   / ## * PDUMPCBP(__VA_ARGS__) * ## /
+               #define PDUMPREGBASEDCBP(...)           / ## * PDUMPREGBASEDCBP(__VA_ARGS__) * ## /
+               #define PDUMPCOMMENTWITHFLAGS(...)      / ## * PDUMPCOMMENTWITHFLAGS(__VA_ARGS__) * ## /
+               #define PDUMPMALLOCPAGESPHYS(...)       / ## * PDUMPMALLOCPAGESPHYS(__VA_ARGS__) * ## /
+               #define PDUMPENDINITPHASE(...)          / ## * PDUMPENDINITPHASE(__VA_ARGS__) * ## /
+               #define PDUMPMSVDXREG(...)              / ## * PDUMPMSVDXREG(__VA_ARGS__) * ## /
+               #define PDUMPMSVDXREGWRITE(...)         / ## * PDUMPMSVDXREGWRITE(__VA_ARGS__) * ## /
+               #define PDUMPMSVDXREGREAD(...)          / ## * PDUMPMSVDXREGREAD(__VA_ARGS__) * ## /
+               #define PDUMPMSVDXPOLEQ(...)            / ## * PDUMPMSVDXPOLEQ(__VA_ARGS__) * ## /
+               #define PDUMPMSVDXPOL(...)              / ## * PDUMPMSVDXPOL(__VA_ARGS__) * ## /
+               #define PDUMPIDLWITHFLAGS(...)          / ## * PDUMPIDLWITHFLAGS(__VA_ARGS__) * ## /
+               #define PDUMPIDL(...)                   / ## * PDUMPIDL(__VA_ARGS__) * ## /
+               #define PDUMPPOWCMDSTART(...)           / ## * PDUMPPOWCMDSTART(__VA_ARGS__) * ## /
+               #define PDUMPPOWCMDEND(...)             / ## * PDUMPPOWCMDEND(__VA_ARGS__) * ## /
+               #define PDUMP_LOCK                      / ## * PDUMP_LOCK(__VA_ARGS__) * ## /
+               #define PDUMP_UNLOCK                    / ## * PDUMP_UNLOCK(__VA_ARGS__) * ## /
+       #else
+               #if defined LINUX || defined GCC_IA32 || defined GCC_ARM || defined __QNXNTO__
+                       #define PDUMPINIT       PDumpInitCommon
+                       #define PDUMPDEINIT(args...)
+                       #define PDUMPREG32(args...)
+                       #define PDUMPREG64(args...)
+                       #define PDUMPREGREAD32(args...)
+                       #define PDUMPREGREAD64(args...)
+                       #define PDUMPCOMMENT(args...)
+                       #define PDUMPREGPOL(args...)
+                       #define PDUMPSETMMUCONTEXT(args...)
+                       #define PDUMPCLEARMMUCONTEXT(args...)
+                       #define PDUMPPDREG(args...)
+                       #define PDUMPPDREGWITHFLAGS(args...)
+                       #define PDUMPSYNC(args...)
+                       #define PDUMPCOPYTOMEM(args...)
+                       #define PDUMPWRITE(args...)
+                       #define PDUMPREGBASEDCBP(args...)
+                       #define PDUMPCOMMENTWITHFLAGS(args...)
+                       #define PDUMPENDINITPHASE(args...)
+                       #define PDUMPIDLWITHFLAGS(args...)
+                       #define PDUMPIDL(args...)
+                       #define PDUMPPOWCMDSTART(args...)
+                       #define PDUMPPOWCMDEND(args...)
+                       #define PDUMP_LOCK(args...)
+                       #define PDUMP_UNLOCK(args...)
+
+               #else
+                       #error Compiler not specified
+               #endif
+       #endif
+#endif
+
+
+#endif /* _PDUMP_KM_H_ */
+
+/******************************************************************************
+ End of file (pdump_km.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/include/pdump_mmu.h b/drivers/gpu/rogue_m/services/server/include/pdump_mmu.h
new file mode 100644 (file)
index 0000000..477c27f
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************/ /*!
+@File
+@Title          Common MMU Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements basic low level control of MMU.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef SRVKM_PDUMP_MMU_H
+#define SRVKM_PDUMP_MMU_H
+
+/* services/server/include/ */
+#include "pdump_symbolicaddr.h"
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "mmu_common.h"
+
+/*
+       PDUMP MMU attributes
+*/
+typedef struct _PDUMP_MMU_ATTRIB_DEVICE_
+{
+    /* Per-Device Pdump attribs */
+
+       /*!< Pdump memory bank name */
+       IMG_CHAR                                *pszPDumpMemDevName;
+
+       /*!< Pdump register bank name */
+       IMG_CHAR                                *pszPDumpRegDevName;
+
+} PDUMP_MMU_ATTRIB_DEVICE;
+
+typedef struct _PDUMP_MMU_ATTRIB_CONTEXT_
+{
+       IMG_UINT32 ui32Dummy;
+} PDUMP_MMU_ATTRIB_CONTEXT;
+
+typedef struct _PDUMP_MMU_ATTRIB_HEAP_
+{
+       /* data page info */
+       IMG_UINT32 ui32DataPageMask;
+} PDUMP_MMU_ATTRIB_HEAP;
+
+typedef struct _PDUMP_MMU_ATTRIB_
+{
+    /* FIXME: would these be better as pointers rather than copies? */
+    struct _PDUMP_MMU_ATTRIB_DEVICE_ sDevice;
+    struct _PDUMP_MMU_ATTRIB_CONTEXT_ sContext;
+    struct _PDUMP_MMU_ATTRIB_HEAP_ sHeap;
+} PDUMP_MMU_ATTRIB;
+
+#if defined(PDUMP)
+    extern PVRSRV_ERROR PDumpMMUMalloc(const IMG_CHAR                  *pszPDumpDevName,
+                                       MMU_LEVEL                               eMMULevel,
+                                       IMG_DEV_PHYADDR                 *psDevPAddr,
+                                       IMG_UINT32                              ui32Size,
+                                       IMG_UINT32                              ui32Align);
+
+    extern PVRSRV_ERROR PDumpMMUFree(const IMG_CHAR                            *pszPDumpDevName,
+                                     MMU_LEVEL                                 eMMULevel,
+                                     IMG_DEV_PHYADDR                   *psDevPAddr);
+
+    extern PVRSRV_ERROR PDumpMMUMalloc2(const IMG_CHAR                 *pszPDumpDevName,
+                                        const IMG_CHAR                 *pszTableType,/* PAGE_CATALOGUE, PAGE_DIRECTORY, PAGE_TABLE */
+                                        const IMG_CHAR                         *pszSymbolicAddr,
+                                        IMG_UINT32                             ui32Size,
+                                        IMG_UINT32                             ui32Align);
+
+    extern PVRSRV_ERROR PDumpMMUFree2(const IMG_CHAR                   *pszPDumpDevName,
+                                      const IMG_CHAR                   *pszTableType,/* PAGE_CATALOGUE, PAGE_DIRECTORY, PAGE_TABLE */
+                                      const IMG_CHAR                   *pszSymbolicAddr);
+
+    extern PVRSRV_ERROR PDumpMMUDumpPxEntries(MMU_LEVEL eMMULevel,
+                                                                  const IMG_CHAR *pszPDumpDevName,
+                                       IMG_VOID *pvPxMem,
+                                       IMG_DEV_PHYADDR sPxDevPAddr,
+                                       IMG_UINT32 uiFirstEntry,
+                                       IMG_UINT32 uiNumEntries,
+                                       const IMG_CHAR *pszMemspaceName,
+                                       const IMG_CHAR *pszSymbolicAddr,
+                                       IMG_UINT64 uiSymbolicAddrOffset,
+                                       IMG_UINT32 uiBytesPerEntry,
+                                       IMG_UINT32 uiLog2Align,
+                                       IMG_UINT32 uiAddrShift,
+                                       IMG_UINT64 uiAddrMask,
+                                       IMG_UINT64 uiPxEProtMask,
+                                       IMG_UINT32 ui32Flags);
+
+    extern PVRSRV_ERROR PDumpMMUAllocMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
+                                                IMG_DEV_PHYADDR sPCDevPAddr,
+                                                PDUMP_MMU_TYPE eMMUType,
+                                                IMG_UINT32 *pui32MMUContextID);
+
+    extern PVRSRV_ERROR PDumpMMUFreeMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
+                                               IMG_UINT32 ui32MMUContextID);
+
+       extern PVRSRV_ERROR PDumpMMUActivateCatalog(const IMG_CHAR *pszPDumpRegSpaceName,
+                                                                                               const IMG_CHAR *pszPDumpRegName,
+                                                                                               IMG_UINT32 uiRegAddr,
+                                                                                               const IMG_CHAR *pszPDumpPCSymbolicName);
+
+       /* FIXME: split to separate file... (debatable whether this is anything to do with MMU) */
+extern PVRSRV_ERROR
+PDumpMMUSAB(const IMG_CHAR *pszPDumpMemNamespace,
+               IMG_UINT32 uiPDumpMMUCtx,
+               IMG_DEV_VIRTADDR sDevAddrStart,
+               IMG_DEVMEM_SIZE_T uiSize,
+               const IMG_CHAR *pszFilename,
+               IMG_UINT32 uiFileOffset,
+                          IMG_UINT32 ui32PDumpFlags);
+
+       #define PDUMP_MMU_MALLOC_DP(pszPDumpMemDevName, aszSymbolicAddr, ui32Size, ui32Align) \
+        PDumpMMUMalloc2(pszPDumpMemDevName, "DATA_PAGE", aszSymbolicAddr, ui32Size, ui32Align)
+    #define PDUMP_MMU_FREE_DP(pszPDumpMemDevName, aszSymbolicAddr) \
+        PDumpMMUFree2(pszPDumpMemDevName, "DATA_PAGE", aszSymbolicAddr)
+
+    #define PDUMP_MMU_ALLOC_MMUCONTEXT(pszPDumpMemDevName, sPCDevPAddr, eMMUType, puiPDumpCtxID) \
+        PDumpMMUAllocMMUContext(pszPDumpMemDevName,                     \
+                                sPCDevPAddr,                            \
+                                eMMUType,                                                              \
+                                puiPDumpCtxID)
+
+    #define PDUMP_MMU_FREE_MMUCONTEXT(pszPDumpMemDevName, uiPDumpCtxID) \
+        PDumpMMUFreeMMUContext(pszPDumpMemDevName, uiPDumpCtxID)
+#else
+
+       #define PDUMP_MMU_MALLOC_DP(pszPDumpMemDevName, pszDevPAddr, ui32Size, ui32Align) \
+        ((IMG_VOID)0)
+    #define PDUMP_MMU_FREE_DP(pszPDumpMemDevName, psDevPAddr) \
+        ((IMG_VOID)0)
+    #define PDUMP_MMU_ALLOC_MMUCONTEXT(pszPDumpMemDevName, sPCDevPAddr, puiPDumpCtxID) \
+        ((IMG_VOID)0)
+    #define PDUMP_MMU_FREE_MMUCONTEXT(pszPDumpMemDevName, uiPDumpCtxID) \
+        ((IMG_VOID)0)
+
+#endif // defined(PDUMP)
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/server/include/pdump_osfunc.h b/drivers/gpu/rogue_m/services/server/include/pdump_osfunc.h
new file mode 100644 (file)
index 0000000..bd99121
--- /dev/null
@@ -0,0 +1,352 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   OS-independent interface to helper functions for pdump
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stdarg.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_device_types.h"
+
+
+/* FIXME
+ * Some OSes (WinXP,CE) allocate the string on the stack, but some
+ * (Linux) use a global variable/lock instead.
+ * Would be good to use the same across all OSes.
+ *
+ * A handle is returned which represents IMG_CHAR* type on all OSes.
+ *
+ * The allocated buffer length is also returned on OSes where it's
+ * supported (e.g. Linux).
+ */
+#define MAX_PDUMP_STRING_LENGTH (256)
+#if defined(WIN32)
+#define PDUMP_GET_SCRIPT_STRING()      \
+       IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH];            \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; \
+       IMG_HANDLE      hScript = (IMG_HANDLE)pszScript;
+
+#define PDUMP_GET_MSG_STRING()         \
+       IMG_CHAR pszMsg[MAX_PDUMP_STRING_LENGTH];                       \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_FILE_STRING()                \
+       IMG_CHAR        pszFileName[MAX_PDUMP_STRING_LENGTH];   \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING()             \
+       IMG_CHAR        pszScript[MAX_PDUMP_STRING_LENGTH];             \
+       IMG_CHAR        pszFileName[MAX_PDUMP_STRING_LENGTH];   \
+       IMG_UINT32      ui32MaxLenScript = MAX_PDUMP_STRING_LENGTH-1;   \
+       IMG_UINT32      ui32MaxLenFileName = MAX_PDUMP_STRING_LENGTH-1; \
+       IMG_HANDLE      hScript = (IMG_HANDLE)pszScript;
+
+#else  /* WIN32 */
+
+#if defined(__QNXNTO__)
+
+#define PDUMP_GET_SCRIPT_STRING()      \
+       IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH];            \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; \
+       IMG_HANDLE      hScript = (IMG_HANDLE)pszScript;
+
+#define PDUMP_GET_MSG_STRING()         \
+       IMG_CHAR pszMsg[MAX_PDUMP_STRING_LENGTH];                       \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_FILE_STRING()                \
+       IMG_CHAR        pszFileName[MAX_PDUMP_STRING_LENGTH];   \
+       IMG_UINT32      ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING()             \
+       IMG_CHAR        pszScript[MAX_PDUMP_STRING_LENGTH];             \
+       IMG_CHAR        pszFileName[MAX_PDUMP_STRING_LENGTH];   \
+       IMG_UINT32      ui32MaxLenScript = MAX_PDUMP_STRING_LENGTH-1;   \
+       IMG_UINT32      ui32MaxLenFileName = MAX_PDUMP_STRING_LENGTH-1; \
+       IMG_HANDLE      hScript = (IMG_HANDLE)pszScript;
+
+#else  /* __QNXNTO__ */
+
+       /*
+        * Linux
+        */
+#define PDUMP_GET_SCRIPT_STRING()                              \
+       IMG_HANDLE hScript;                                                     \
+       IMG_UINT32      ui32MaxLen;                                             \
+       PVRSRV_ERROR eErrorPDump;                                               \
+       eErrorPDump = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
+       PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetScriptString");
+
+#define PDUMP_GET_MSG_STRING()                                 \
+       IMG_CHAR *pszMsg;                                                       \
+       IMG_UINT32      ui32MaxLen;                                             \
+       PVRSRV_ERROR eErrorPDump;                                               \
+       eErrorPDump = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\
+       PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetMessageString");
+
+#define PDUMP_GET_FILE_STRING()                                \
+       IMG_CHAR *pszFileName;                                  \
+       IMG_UINT32      ui32MaxLen;                                     \
+       PVRSRV_ERROR eErrorPDump;                               \
+       eErrorPDump = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
+       PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetFilenameString");
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING()             \
+       IMG_HANDLE hScript;                                                     \
+       IMG_CHAR *pszFileName;                                          \
+       IMG_UINT32      ui32MaxLenScript;                               \
+       IMG_UINT32      ui32MaxLenFileName;                             \
+       PVRSRV_ERROR eErrorPDump;                                               \
+       eErrorPDump = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
+       PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetScriptString");\
+       eErrorPDump = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
+       PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetFilenameString");
+
+       /*!
+        * @name        PDumpOSGetScriptString
+        * @brief       Get the "script" buffer
+        * @param       phScript - buffer handle for pdump script
+        * @param       pui32MaxLen - max length of the script buffer
+        *                      FIXME: the max length should be internal to the OS-specific code
+        * @return      error (always PVRSRV_OK on some OSes)
+        */
+       PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
+
+       /*!
+        * @name        PDumpOSGetMessageString
+        * @brief       Get the "message" buffer
+        * @param       pszMsg - buffer pointer for pdump messages
+        * @param       pui32MaxLen - max length of the message buffer
+        *                      FIXME: the max length should be internal to the OS-specific code
+        * @return      error (always PVRSRV_OK on some OSes)
+        */
+       PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
+
+       /*!
+        * @name        PDumpOSGetFilenameString
+        * @brief       Get the "filename" buffer
+        * @param       ppszFile - buffer pointer for filename
+        * @param       pui32MaxLen - max length of the filename buffer
+        *                      FIXME: the max length should be internal to the OS-specific code
+        * @return      error (always PVRSRV_OK on some OSes)
+        */
+       PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
+
+#endif /* __QNXNTO__ */
+#endif /* WIN32 */
+
+
+/*
+ * PDump streams, channels, init and deinit routines (common to all OSes)
+ */
+
+typedef struct
+{
+       IMG_HANDLE hInit;        /*!< Driver initialisation PDump stream */
+       IMG_HANDLE hMain;        /*!< App framed PDump stream */
+       IMG_HANDLE hDeinit;      /*!< Driver/HW de-initialisation PDump stream */
+} PDUMP_CHANNEL;
+
+PVRSRV_ERROR PDumpOSInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript,
+               IMG_UINT32* pui32InitCapMode, IMG_CHAR** ppszEnvComment);
+
+IMG_VOID PDumpOSDeInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript);
+
+/*!
+ * @name       PDumpOSSetSplitMarker
+ * @brief      Inform the PDump client to start a new file at the given marker.
+ * @param      hStream - stream
+ * @param   ui32Marker - byte file position
+ */
+IMG_BOOL PDumpOSSetSplitMarker(IMG_HANDLE hStream, IMG_UINT32 ui32Marker);
+
+/*
+       PDumpOSDebugDriverWrite - ENV layer write entry point from COMMON layer
+                                 A call back down the PDump software layer
+ */
+IMG_UINT32 PDumpOSDebugDriverWrite(IMG_HANDLE psStream,
+                                   IMG_UINT8 *pui8Data,
+                                   IMG_UINT32 ui32BCount);
+
+/*
+ * Define macro for processing variable args list in OS-independent
+ * manner. See e.g. PDumpComment().
+ */
+#define PDUMP_va_list  va_list
+#define PDUMP_va_start va_start
+#define PDUMP_va_end   va_end
+
+
+/*!
+ * @name       PDumpOSBufprintf
+ * @brief      Printf to OS-specific pdump state buffer
+ * @param      hBuf - buffer handle to write into
+ * @param      ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
+ * @param      pszFormat - format string
+ */
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+/*!
+ * @name       PDumpOSDebugPrintf
+ * @brief      Debug message during pdumping
+ * @param      pszFormat - format string
+ */
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+/*
+ * Write into a IMG_CHAR* on all OSes. Can be allocated on the stack or heap.
+ */
+/*!
+ * @name       PDumpOSSprintf
+ * @brief      Printf to IMG char array
+ * @param      pszComment - char array to print into
+ * @param      pszFormat - format string
+ */
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+/*!
+ * @name       PDumpOSVSprintf
+ * @brief      Printf to IMG string using variable args (see stdarg.h). This is necessary
+ *                     because the ... notation does not support nested function calls.
+ * @param      pszMsg - char array to print into
+ * @param      ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
+ * @param      pszFormat - format string
+ * @param      vaArgs - variable args structure (from stdarg.h)
+ */
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
+
+/*!
+ * @name       PDumpOSBuflen
+ * @param      hBuffer - handle to buffer
+ * @param      ui32BuffeRSizeMax - max size of buffer (chars)
+ * @return     length of buffer, will always be <= ui32BufferSizeMax
+ */
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+/*!
+ * @name       PDumpOSVerifyLineEnding
+ * @brief      Put line ending sequence at the end if it isn't already there
+ * @param      hBuffer - handle to buffer
+ * @param      ui32BufferSizeMax - max size of buffer (chars)
+ */
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+/*!
+ * @name       PDumpOSCPUVAddrToDevPAddr
+ * @brief      OS function to convert CPU virtual to device physical for dumping pages
+ * @param      hOSMemHandle    mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
+ * @param      ui32Offset              dword offset into allocation (for use with mem handle, e.g. linux)
+ * @param      pui8LinAddr             CPU linear addr (usually a kernel virtual address)
+ * @param      ui32PageSize    page size, used for assertion check
+ * @return     psDevPAddr              device physical addr
+ */
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+        IMG_HANDLE hOSMemHandle,
+               IMG_UINT32 ui32Offset,
+               IMG_UINT8 *pui8LinAddr,
+               IMG_UINT32 ui32PageSize,
+               IMG_DEV_PHYADDR *psDevPAddr);
+
+/*!
+ * @name       PDumpOSCPUVAddrToPhysPages
+ * @brief      OS function to convert CPU virtual to backing physical pages
+ * @param      hOSMemHandle    mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
+ * @param      ui32Offset              offset within mem allocation block
+ * @param      pui8LinAddr             CPU linear addr
+ * @param      ui32DataPageMask        mask for data page (= data page size -1)
+ * @return     pui32PageOffset CPU page offset (same as device page offset if page sizes equal)
+ */
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+               IMG_UINT32 ui32Offset,
+               IMG_PUINT8 pui8LinAddr,
+               IMG_UINT32 ui32DataPageMask,
+               IMG_UINT32 *pui32PageOffset);
+
+/*!
+ * @name       PDumpOSReleaseExecution
+ * @brief      OS function to switch to another process, to clear pdump buffers
+ */
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID);
+
+/*!
+ * @name       PDumpOSCreateLock
+ * @brief      Create the global pdump lock
+ */
+PVRSRV_ERROR PDumpOSCreateLock(IMG_VOID);
+
+/*!
+ * @name       PDumpOSDestroyLock
+ * @brief      Destroy the global pdump lock
+ */
+IMG_VOID PDumpOSDestroyLock(IMG_VOID);
+
+/*!
+ * @name       PDumpOSLock
+ * @brief      Acquire the global pdump lock
+ */
+IMG_VOID PDumpOSLock(IMG_VOID);
+
+/*!
+ * @name       PDumpOSUnlock
+ * @brief      Release the global pdump lock
+ */
+IMG_VOID PDumpOSUnlock(IMG_VOID);
+
+/*!
+ * @name       PDumpOSGetCtrlState
+ * @brief      Retrieve some state from the debug driver or debug driver stream
+ */
+IMG_UINT32 PDumpOSGetCtrlState(IMG_HANDLE hDbgStream, IMG_UINT32 ui32StateID);
+
+/*!
+ * @name       PDumpOSSetFrame
+ * @brief      Set the current frame value mirrored in the debug driver
+ */
+IMG_VOID PDumpOSSetFrame(IMG_UINT32 ui32Frame);
+
+/*!
+ * @name       PDumpOSAllowInitPhaseToComplete
+ * @brief      Some platforms wish to control when the init phase is marked as
+ *          complete depending on who is instructing it so.
+ */
+IMG_BOOL PDumpOSAllowInitPhaseToComplete(IMG_UINT32 eModuleID);
+
+
diff --git a/drivers/gpu/rogue_m/services/server/include/pdump_physmem.h b/drivers/gpu/rogue_m/services/server/include/pdump_physmem.h
new file mode 100644 (file)
index 0000000..c75202b
--- /dev/null
@@ -0,0 +1,212 @@
+/**************************************************************************/ /*!
+@File
+@Title          pdump functions to assist with physmem allocations
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements basic low level control of MMU.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef SRVSRV_PDUMP_PHYSMEM_H
+#define SRVSRV_PDUMP_PHYSMEM_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pmr.h"
+
+
+typedef struct _PDUMP_PHYSMEM_INFO_T_ PDUMP_PHYSMEM_INFO_T;
+
+#if defined(PDUMP)
+extern PVRSRV_ERROR
+PDumpPMRMalloc(const IMG_CHAR *pszDevSpace,
+               const IMG_CHAR *pszSymbolicAddress,
+               IMG_UINT64 ui64Size,
+               /* alignment is alignment of start of buffer _and_
+                  minimum contiguity - i.e. smallest allowable
+                  page-size. */
+               IMG_DEVMEM_ALIGN_T uiAlign,
+               IMG_BOOL bForcePersistent,
+               IMG_HANDLE *phHandlePtr);
+
+IMG_INTERNAL IMG_VOID
+PDumpPMRMallocPMR(const PMR *psPMR,
+                  IMG_DEVMEM_SIZE_T uiSize,
+                  IMG_DEVMEM_ALIGN_T uiBlockSize,
+                  IMG_BOOL bForcePersistent,
+                  IMG_HANDLE *phPDumpAllocInfoPtr);
+
+extern
+PVRSRV_ERROR PDumpPMRFree(IMG_HANDLE hPDumpAllocationInfoHandle);
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpPMRMalloc(const IMG_CHAR *pszDevSpace,
+               const IMG_CHAR *pszSymbolicAddress,
+               IMG_UINT64 ui64Size,
+               IMG_DEVMEM_ALIGN_T uiAlign,
+               IMG_BOOL bForcePersistent,
+               IMG_HANDLE *phHandlePtr)
+{
+       PVR_UNREFERENCED_PARAMETER(pszDevSpace);
+       PVR_UNREFERENCED_PARAMETER(pszSymbolicAddress);
+       PVR_UNREFERENCED_PARAMETER(ui64Size);
+       PVR_UNREFERENCED_PARAMETER(uiAlign);
+       PVR_UNREFERENCED_PARAMETER(bForcePersistent);
+       PVR_UNREFERENCED_PARAMETER(phHandlePtr);
+       PVR_UNREFERENCED_PARAMETER(bForcePersistent);
+       return PVRSRV_OK;
+}
+
+static INLINE IMG_VOID
+PDumpPMRMallocPMR(const PMR *psPMR,
+                  IMG_DEVMEM_SIZE_T uiSize,
+                  IMG_DEVMEM_ALIGN_T uiBlockSize,
+                  IMG_BOOL bForcePersistent,
+                  IMG_HANDLE *phPDumpAllocInfoPtr)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(uiBlockSize);
+       PVR_UNREFERENCED_PARAMETER(bForcePersistent);
+       PVR_UNREFERENCED_PARAMETER(phPDumpAllocInfoPtr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+PDumpPMRFree(IMG_HANDLE hPDumpAllocationInfoHandle)
+{
+       PVR_UNREFERENCED_PARAMETER(hPDumpAllocationInfoHandle);
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+
+#define PMR_DEFAULT_PREFIX "PMR"
+#define PMR_SYMBOLICADDR_FMTSPEC "%s%llu"
+
+#if defined(PDUMP)
+#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, phHandlePtr) \
+    PDumpPMRMalloc(pszPDumpMemDevName, PMR_OSALLOCPAGES_PREFIX, ui32SerialNum, ui32Size, ui32Align, phHandlePtr)
+#define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \
+    PDumpPMRFree(hHandle)
+#else
+#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, phHandlePtr) \
+    ((IMG_VOID)(*phHandlePtr=IMG_NULL))
+#define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \
+    ((IMG_VOID)(0))
+#endif // defined(PDUMP)
+
+extern PVRSRV_ERROR
+PDumpPMRWRW32(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT32 ui32Value,
+            PDUMP_FLAGS_T uiPDumpFlags);
+
+extern PVRSRV_ERROR
+PDumpPMRWRW64(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT64 ui64Value,
+            PDUMP_FLAGS_T uiPDumpFlags);
+
+extern PVRSRV_ERROR
+PDumpPMRLDB(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_DEVMEM_SIZE_T uiSize,
+            const IMG_CHAR *pszFilename,
+            IMG_UINT32 uiFileOffset,
+            PDUMP_FLAGS_T uiPDumpFlags);
+
+extern PVRSRV_ERROR
+PDumpPMRSAB(const IMG_CHAR *pszDevSpace,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_DEVMEM_SIZE_T uiSize,
+            const IMG_CHAR *pszFileName,
+            IMG_UINT32 uiFileOffset);
+
+/*
+  PDumpPMRPOL()
+
+  emits a POL to the PDUMP.
+*/
+extern PVRSRV_ERROR
+PDumpPMRPOL(const IMG_CHAR *pszMempaceName,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiOffset,
+            IMG_UINT32 ui32Value,
+            IMG_UINT32 ui32Mask,
+            PDUMP_POLL_OPERATOR eOperator,
+            IMG_UINT32 uiCount,
+            IMG_UINT32 uiDelay,
+            PDUMP_FLAGS_T uiPDumpFlags);
+
+extern PVRSRV_ERROR
+PDumpPMRCBP(const IMG_CHAR *pszMemspaceName,
+            const IMG_CHAR *pszSymbolicName,
+            IMG_DEVMEM_OFFSET_T uiReadOffset,
+            IMG_DEVMEM_OFFSET_T uiWriteOffset,
+            IMG_DEVMEM_SIZE_T uiPacketSize,
+            IMG_DEVMEM_SIZE_T uiBufferSize);
+
+/*
+ * PDumpWriteBuffer()
+ *
+ * writes a binary blob to the pdump param stream containing the
+ * current contents of the memory, and returns the filename and offset
+ * of where that blob is located (for use in a subsequent LDB, for
+ * example)
+ *
+ * Caller to provide buffer to receive filename, and declare the size
+ * of that buffer
+ */
+extern PVRSRV_ERROR
+PDumpWriteBuffer(IMG_UINT8 *pcBuffer,
+                 IMG_SIZE_T uiNumBytes,
+                 PDUMP_FLAGS_T uiPDumpFlags,
+                 IMG_CHAR *pszFilenameOut,
+                 IMG_SIZE_T uiFilenameBufSz,
+                 PDUMP_FILEOFFSET_T *puiOffsetOut);
+
+#endif /* #ifndef SRVSRV_PDUMP_PHYSMEM_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/pdump_symbolicaddr.h b/drivers/gpu/rogue_m/services/server/include/pdump_symbolicaddr.h
new file mode 100644 (file)
index 0000000..ed912a5
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************/ /*!
+@File
+@Title          Abstraction of PDUMP symbolic address derivation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Allows pdump functions to derive symbolic addresses on-the-fly
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef SRVKM_PDUMP_SYMBOLICADDR_H
+#define SRVKM_PDUMP_SYMBOLICADDR_H
+
+#include "img_types.h"
+
+#include "pvrsrv_error.h"
+
+/* pdump symbolic addresses are generated on-the-fly with a callback */
+
+typedef PVRSRV_ERROR (*PVRSRV_SYMADDRFUNCPTR)(IMG_HANDLE hPriv, IMG_UINT32 uiOffset, IMG_CHAR *pszSymbolicAddr, IMG_UINT32 ui32SymbolicAddrLen, IMG_UINT32 *pui32NewOffset);
+
+#endif /* #ifndef SRVKM_PDUMP_SYMBOLICADDR_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/physmem.h b/drivers/gpu/rogue_m/services/server/include/physmem.h
new file mode 100644 (file)
index 0000000..c7389c9
--- /dev/null
@@ -0,0 +1,102 @@
+/*************************************************************************/ /*!
+@File
+@Title          Physmem header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for common entry point for creation of RAM backed PMR's
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SRVSRV_PHYSMEM_H_
+#define _SRVSRV_PHYSMEM_H_
+
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "pmr.h"
+#include "pmr_impl.h"
+
+/*
+ * PhysmemNewRamBackedPMR
+ *
+ * This function will create a RAM backed PMR using the device specific
+ * callback, this allows control at a per-devicenode level to select the
+ * memory source thus supporting mixed UMA/LMA systems.
+ *
+ * The size must be a multiple of page size.  The page size is
+ * specified in log2.  It should be regarded as a minimum contiguity
+ * of which the that the resulting memory must be a multiple.  It may
+ * be that this should be a fixed number.  It may be that the
+ * allocation size needs to be a multiple of some coarser "page size"
+ * than that specified in the page size argument.  For example, take
+ * an OS whose page granularity is a fixed 16kB, but the caller
+ * requests memory in page sizes of 4kB.  The request can be satisfied
+ * if and only if the SIZE requested is a multiple of 16kB.  If the
+ * arguments supplied are such that this OS cannot grant the request,
+ * PVRSRV_ERROR_INVALID_PARAMS will be returned.
+ *
+ * The caller should supply storage of a pointer.  Upon successful
+ * return a PMR object will have been created and a pointer to it
+ * returned in the PMROut argument.
+ *
+ * A PMR thusly created should be destroyed with PhysmemUnrefPMR.
+ *
+ * Note that this function may cause memory allocations and on some
+ * OSes this may cause scheduling events, so it is important that this
+ * function be called with interrupts enabled and in a context where
+ * scheduling events and memory allocations are permitted.
+ *
+ * The flags may be used by the implementation to change its behaviour
+ * if required.  The flags will also be stored in the PMR as immutable
+ * metadata and returned to mmu_common when it asks for it.
+ *
+ */
+extern PVRSRV_ERROR
+PhysmemNewRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                       IMG_DEVMEM_SIZE_T uiSize,
+                       IMG_DEVMEM_SIZE_T uiChunkSize,
+                       IMG_UINT32 ui32NumPhysChunks,
+                       IMG_UINT32 ui32NumVirtChunks,
+                       IMG_BOOL *pabMappingTable,
+                       IMG_UINT32 uiLog2PageSize,
+                       PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                       PMR **ppsPMROut);
+
+#endif /* _SRVSRV_PHYSMEM_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/physmem_dmabuf.h b/drivers/gpu/rogue_m/services/server/include/physmem_dmabuf.h
new file mode 100644 (file)
index 0000000..a22fe4d
--- /dev/null
@@ -0,0 +1,77 @@
+/**************************************************************************/ /*!
+@File           physmem_dmabuf.h
+@Title          Header for dmabuf PMR factory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management. This module is responsible for
+                implementing the function callbacks importing Ion allocations
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(_PHYSMEM_DMABUF_H_)
+#define _PHYSMEM_DMABUF_H_
+
+#include <linux/dma-buf.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+#include "connection_server.h"
+
+#include "pmr.h"
+
+typedef PVRSRV_ERROR (*PFN_DESTROY_DMABUF_PMR)(PHYS_HEAP *psHeap,
+                                              struct dma_buf_attachment *psAttachment);
+
+PVRSRV_ERROR
+PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap,
+                               struct dma_buf_attachment *psAttachment,
+                               PFN_DESTROY_DMABUF_PMR pfnDestroy,
+                               PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                               PMR **ppsPMRPtr);
+
+#if defined(SUPPORT_ION)
+PVRSRV_ERROR
+PhysmemImportDmaBuf(CONNECTION_DATA *psConnection,
+                                       IMG_INT fd,
+                                       PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                       PMR **ppsPMRPtr,
+                                       IMG_DEVMEM_SIZE_T *puiSize,
+                                       IMG_DEVMEM_ALIGN_T *puiAlign);
+#endif
+
+#endif /* !defined(_PHYSMEM_DMABUF_H_) */
diff --git a/drivers/gpu/rogue_m/services/server/include/physmem_lma.h b/drivers/gpu/rogue_m/services/server/include/physmem_lma.h
new file mode 100644 (file)
index 0000000..552c1e0
--- /dev/null
@@ -0,0 +1,84 @@
+/**************************************************************************/ /*!
+@File
+@Title          Header for local card memory allocator
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Part of the memory management. This module is responsible for
+                implementing the function callbacks for local card memory.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef _SRVSRV_PHYSMEM_LMA_H_
+#define _SRVSRV_PHYSMEM_LMA_H_
+
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "pmr.h"
+#include "pmr_impl.h"
+
+/*
+ * PhysmemNewLocalRamBackedPMR
+ *
+ * This function will create a PMR using the local card memory and is OS
+ * agnostic.
+ */
+PVRSRV_ERROR
+PhysmemNewLocalRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                                                       IMG_DEVMEM_SIZE_T uiSize,
+                                                       IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                       IMG_UINT32 ui32NumPhysChunks,
+                                                       IMG_UINT32 ui32NumVirtChunks,
+                                                       IMG_BOOL *pabMappingTable,
+                                                       IMG_UINT32 uiLog2PageSize,
+                                                       PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                                       PMR **ppsPMRPtr);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+/*
+ * Define some helper list functions for the virtualization validation code
+ */
+
+IMG_VOID       InsertPidOSidsCoupling(IMG_PID pId, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg);
+IMG_VOID       RetrieveOSidsfromPidList(IMG_PID pId, IMG_UINT32 *pui32OSid, IMG_UINT32 *pui32OSidReg);
+IMG_VOID       RemovePidOSidCoupling(IMG_PID pId);
+#endif
+
+#endif /* #ifndef _SRVSRV_PHYSMEM_LMA_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/physmem_osmem.h b/drivers/gpu/rogue_m/services/server/include/physmem_osmem.h
new file mode 100644 (file)
index 0000000..706c859
--- /dev/null
@@ -0,0 +1,114 @@
+/**************************************************************************/ /*!
+@File
+@Title         PMR implementation of OS derived physical memory
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Part of the memory management.  This module is
+                responsible for the an implementation of the "PMR"
+                abstraction.  This interface is for the
+                PhysmemNewOSRamBackedPMR() "PMR Factory" which is
+                responsible for claiming chunks of memory (in
+                particular physically contiguous quanta) from the
+                Operating System.
+
+                As such, this interface will be implemented on a
+                Per-OS basis, in the "env" directory for that system.
+                A dummy implementation is available in
+                physmem_osmem_dummy.c for operating systems that
+                cannot, or do not wish to, offer this functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+#ifndef _SRVSRV_PHYSMEM_OSMEM_H_
+#define _SRVSRV_PHYSMEM_OSMEM_H_
+
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+/* services/server/include/ */
+#include "pmr.h"
+#include "pmr_impl.h"
+
+/*
+ * PhysmemNewOSRamBackedPMR
+ *
+ * To be overridden on a per-OS basis.
+ *
+ * This function will create a PMR using the default "OS supplied" physical pages
+ * method, assuming such is available on a particular operating system.  (If not,
+ * PVRSRV_ERROR_NOT_SUPPORTED should be returned)
+ */
+extern PVRSRV_ERROR
+PhysmemNewOSRamBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                         IMG_DEVMEM_SIZE_T uiSize,
+                                                IMG_DEVMEM_SIZE_T uiChunkSize,
+                                                IMG_UINT32 ui32NumPhysChunks,
+                                                IMG_UINT32 ui32NumVirtChunks,
+                                                IMG_BOOL *pabMappingTable,
+                         IMG_UINT32 uiLog2PageSize,
+                         PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                         PMR **ppsPMROut);
+
+/*
+ * PhysmemNewTDMetaCodePMR
+ *
+ * This function is used as part of the facility to provide secure META firmware
+ * memory. A default implementation is provided which must be replaced by the SoC
+ * implementor.
+ *
+ * Calling this function will return a PMR for a memory allocation made in "secure
+ * META code memory". It will only be writable by a hypervisor, and when the feature
+ * is enabled on the SoC, the META will only be able to perform instruction reads from
+ * memory that is secured that way.
+ */
+PVRSRV_ERROR
+PhysmemNewTDMetaCodePMR(PVRSRV_DEVICE_NODE *psDevNode,
+                        IMG_DEVMEM_SIZE_T uiSize,
+                        IMG_UINT32 uiLog2PageSize,
+                        PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                        PMR **ppsPMRPtr);
+
+PVRSRV_ERROR
+PhysmemNewTDSecureBufPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                         IMG_DEVMEM_SIZE_T uiSize,
+                         IMG_UINT32 uiLog2PageSize,
+                         PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                         PMR **ppsPMRPtr);
+
+
+#endif /* #ifndef _SRVSRV_PHYSMEM_OSMEM_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/pmr.h b/drivers/gpu/rogue_m/services/server/include/pmr.h
new file mode 100644 (file)
index 0000000..26bda9b
--- /dev/null
@@ -0,0 +1,823 @@
+/**************************************************************************/ /*!
+@File
+@Title         Physmem (PMR) abstraction
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Part of the memory management.  This module is responsible for
+                the "PMR" abstraction.  A PMR (Physical Memory Resource)
+                represents some unit of physical memory which is
+                allocated/freed/mapped/unmapped as an indivisible unit
+                (higher software levels provide an abstraction above that
+                to deal with dividing this down into smaller manageable units).
+                Importantly, this module knows nothing of virtual memory, or
+                of MMUs etc., with one excuseable exception.  We have the
+                concept of a "page size", which really means nothing in
+                physical memory, but represents a "contiguity quantum" such
+                that the higher level modules which map this memory are able
+                to verify that it matches the needs of the page size for the
+                virtual realm into which it is being mapped.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef _SRVSRV_PMR_H_
+#define _SRVSRV_PMR_H_
+
+/* include/ */
+#include "img_types.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+#include "devicemem_typedefs.h"                        /* Required for export DEVMEM_EXPORTCOOKIE */
+
+/* services/include */
+#include "pdump.h"
+
+/* services/server/include/ */
+#include "pmr_impl.h"
+#include "physheap.h"
+/* A typical symbolic address for physical memory may look like:
+   :MEMORYSPACE:SUBSYS_NNNNNN_0X1234567890_XYZ.  That example is quite
+   extreme, they are likely shorter than that.  We'll make the define
+   here plentiful, however, note that this is _advisory_ not
+   _mandatory_ - in other words, it's the allocator's responsibility
+   to choose the amount of memory to set aside, and it's up to us to
+   honour the size passed in by the caller.  i.e. this define is for
+   GUIDANCE ONLY.
+*/
+#define PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT                (60)
+#define PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT           (20)
+#define PMR_MAX_MEMSPNAME_SYMB_ADDR_LENGTH_DEFAULT     (PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT + PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT)
+#define PMR_MAX_PARAMSTREAM_FILENAME_LENGTH_DEFAULT (100)
+#define PMR_MAX_TRANSLATION_STACK_ALLOC                                (32)
+
+typedef IMG_UINT64 PMR_BASE_T;
+typedef IMG_UINT64 PMR_SIZE_T;
+#define PMR_SIZE_FMTSPEC "0x%010llX"
+#define PMR_VALUE32_FMTSPEC "0x%08X"
+#define PMR_VALUE64_FMTSPEC "0x%016llX"
+typedef IMG_UINT32 PMR_LOG2ALIGN_T;
+typedef IMG_UINT64 PMR_PASSWORD_T;
+
+typedef struct _PMR_ PMR;
+typedef struct _PMR_EXPORT_ PMR_EXPORT;
+
+typedef struct _PMR_PAGELIST_ PMR_PAGELIST;
+
+struct _PVRSRV_DEVICE_NODE_;
+
+/*
+ * PMRCreatePMR
+ *
+ * Not to be called directly, only via implementations of PMR
+ * factories, e.g. in physmem_osmem.c, deviceclass.c, etc.
+ *
+ * Creates a PMR object, with callbacks and private data as per the
+ * FuncTab/PrivData args.
+ *
+ * Note that at creation time the PMR must set in stone the "logical
+ * size" and the "contiguity guarantee"
+ *
+ * Flags are also set at this time.  (T.B.D.  flags also immutable for
+ * the life of the PMR?)
+ *
+ * Logical size is the amount of Virtual space this allocation would
+ * take up when mapped.  Note that this does not have to be the same
+ * as the actual physical size of the memory.  For example, consider
+ * the sparsely allocated non-power-of-2 texture case.  In this
+ * instance, the "logical size" would be the virtual size of the
+ * rounded-up power-of-2 texture.  That some pages of physical memory
+ * may not exist does not affect the logical size calculation.
+ *
+ * The PMR must also supply the "contiguity guarantee" which is the
+ * finest granularity of alignment and size of physical pages that the
+ * PMR will provide after LockSysPhysAddresses is called.  Note that
+ * the calling code may choose to call PMRSysPhysAddr with a finer
+ * granularity than this, for example if it were to map into a device
+ * MMU with a smaller page size, and it's also OK for the PMR to
+ * supply physical memory in larger chunks than this.  But
+ * importantly, never the other way around.
+ *
+ * More precisely, the following inequality must be maintained
+ * whenever mappings and/or physical addresses exist:
+ *
+ *       (device MMU page size) <= 2**(uiLog2ContiguityGuarantee) <= (actual contiguity of physical memory)
+ *
+ *
+ * Note also that the implementation may supply pszPDumpFlavour and
+ * pszPDumpDefaultMemspaceName, which are irrelevant where the PMR
+ * implementation overrides the default symbolic name construction
+ * routine.  Where the function pointer for PDump symbolic name
+ * derivation is not overridden (i.e. IMG_NULL appears in the relevant
+ * entry of the functab) and default implementation shall be used
+ * which will copy the PDumpDefaultMemspaceName into the namespace
+ * argument, and create the symbolic name by concatenating the
+ * "PDumpFlavour" and a numeric representation of the PMR's serial
+ * number.
+ *
+ * The implementation must guarantee that the storage for these two
+ * strings, and the function table, are maintained, as copies are not
+ * made, the pointer is simply stored.
+ *
+ * The function table will contain the following callbacks which may
+ * be overridden by the PMR implementation:
+ *
+ * pfnLockPhysAddresses
+ *
+ *      Called when someone locks requests that Physical pages are to
+ *      be locked down via the PMRLockSysPhysAddresses() API.  Note
+ *      that if physical pages are prefaulted at PMR creation time and
+ *      therefore static, it would not be necessary to override this
+ *      function, in which case IMG_NULL may be supplied.
+ *
+ * pfnUnlockPhysAddresses
+ *
+ *      The reverse of pfnLockPhysAddresses.  Note that this should be
+ *      IMG_NULL if and only if pfnLockPhysAddresses is IMG_NULL
+ *
+ * pfnSysPhysAddr
+ *
+ *      This function is mandatory.  This is the one which returns the
+ *      system physical address for a given offset into this PMR.  The
+ *      "lock" function will have been called, if overridden, before
+ *      this function, thus the implementation should not increase any
+ *      refcount when answering this call.  Refcounting, if necessary,
+ *      should be done in the lock/unlock calls.  Refcounting would
+ *      not be necessary in the prefaulted/static scenario, as the
+ *      pmr.c abstraction will handle the refcounting for the whole
+ *      PMR.
+ *
+ * pfnPDumpSymbolicAddr
+ *
+ *      Derives the PDump symbolic address for the given offset.  The
+ *      default implementation will copy the PDumpDefaultMemspaceName
+ *      into the namespace argument (or use SYSMEM if none was
+ *      supplied), and create the symbolic name by concatenating the
+ *      "PDumpFlavour" and a numeric representation of the PMR's
+ *      serial number.
+ *
+ * pfnFinalize
+ *
+ *      Called when the PMR's refcount reaches zero and it gets
+ *      destroyed.  This allows the implementation to free up any
+ *      resource acquired during creation time.
+ *
+ */
+extern PVRSRV_ERROR
+PMRCreatePMR(PHYS_HEAP *psPhysHeap,
+             PMR_SIZE_T uiLogicalSize,
+             PMR_SIZE_T uiChunkSize,
+             IMG_UINT32 ui32NumPhysChunks,
+             IMG_UINT32 ui32NumVirtChunks,
+             IMG_BOOL *pabMappingTable,
+             PMR_LOG2ALIGN_T uiLog2ContiguityGuarantee,
+             PMR_FLAGS_T uiFlags,
+             const IMG_CHAR *pszPDumpFlavour,
+             const PMR_IMPL_FUNCTAB *psFuncTab,
+             PMR_IMPL_PRIVDATA pvPrivData,
+             PMR **ppsPMRPtr,
+             IMG_HANDLE *phPDumpAllocInfo,
+             IMG_BOOL bForcePersistent);
+
+/*
+ * PMRLockSysPhysAddresses()
+ *
+ * Calls the relevant callback to lock down the system physical addresses of the memory that makes up the whole PMR.
+ *
+ * Before this call, it is not valid to use any of the information
+ * getting APIs: PMR_Flags(), PMR_SysPhysAddr(),
+ * PMR_PDumpSymbolicAddr() [ see note below about lock/unlock
+ * semantics ]
+ *
+ * The caller of this function does not have to care about how the PMR
+ * is implemented.  He only has to know that he is allowed access to
+ * the physical addresses _after_ calling this function and _until_
+ * calling PMRUnlockSysPhysAddresses().
+ *
+ *
+ * Notes to callback implementers (authors of PMR Factories):
+ *
+ * Some PMR implementations will be such that the physical memory
+ * exists for the lifetime of the PMR, with a static address, (and
+ * normally flags and symbolic address are static too) and so it is
+ * legal for a PMR implementation to not provide an implementation for
+ * the lock callback.
+ *
+ * Some PMR implementation may wish to page memory in from secondary
+ * storage on demand.  The lock/unlock callbacks _may_ be the place to
+ * do this.  (more likely, there would be a separate API for doing
+ * this, but this API provides a useful place to assert that it has
+ * been done)
+ */
+
+extern PVRSRV_ERROR
+PMRLockSysPhysAddresses(PMR *psPMR,
+                        IMG_UINT32 uiLog2DevPageSize);
+
+extern PVRSRV_ERROR
+PMRLockSysPhysAddressesNested(PMR *psPMR,
+                        IMG_UINT32 uiLog2DevPageSize,
+                        IMG_UINT32 ui32NestingLevel);
+
+/*
+ * PMRUnlockSysPhysAddresses()
+ *
+ * the reverse of PMRLockSysPhysAddresses()
+ */
+extern PVRSRV_ERROR
+PMRUnlockSysPhysAddresses(PMR *psPMR);
+
+IMG_VOID PMRLock(void);
+IMG_VOID PMRUnlock(void);
+IMG_BOOL PMRIsLocked(void);
+IMG_BOOL PMRIsLockedByMe(void);
+
+/*
+ * PhysmemPMRExport()
+ *
+ * Given a PMR, creates a PMR "Export", which is a handle that
+ * provides sufficient data to be able to "import" this PMR elsewhere.
+ * The PMR Export is an object in its own right, whose existance
+ * implies a reference on the PMR, thus the PMR cannot be destroyed
+ * while the PMR Export exists.  The intention is that the PMR Export
+ * will be wrapped in the devicemem layer by a cross process handle,
+ * and some IPC by which to communicate the handle value and password
+ * to other processes.  The receiving process is able to unwrap this
+ * to gain access to the same PMR Export in this layer, and, via
+ * PhysmemPMRImport(), obtain a reference to the original PMR.
+ *
+ * The caller receives, along with the PMR Export object, information
+ * about the size and contiguity guarantee for the PMR, and also the
+ * PMRs secret password, in order to authenticate the subsequent
+ * import.
+ *
+ * N.B.  If you call PMRExportPMR() (and it succeeds), you are
+ * promising to later call PMRUnexportPMR()
+ */
+extern PVRSRV_ERROR
+PMRExportPMR(PMR *psPMR,
+             PMR_EXPORT **ppsPMRExport,
+             PMR_SIZE_T *puiSize,
+             PMR_LOG2ALIGN_T *puiLog2Contig,
+             PMR_PASSWORD_T *puiPassword);
+
+/*
+ * PMRMakeServerExportClientExport()
+ * 
+ * This is a "special case" function for making a server export cookie
+ * which went through the direct bridge into an export cookie that can
+ * be passed through the client bridge.
+ */
+PVRSRV_ERROR
+PMRMakeServerExportClientExport(DEVMEM_EXPORTCOOKIE *psPMRExportIn,
+                                                               PMR_EXPORT **ppsPMRExportPtr,
+                                                               PMR_SIZE_T *puiSize,
+                                                               PMR_LOG2ALIGN_T *puiLog2Contig,
+                                                               PMR_PASSWORD_T *puiPassword);
+
+PVRSRV_ERROR
+PMRUnmakeServerExportClientExport(PMR_EXPORT *psPMRExport);
+
+/*
+ * PMRUnexporPMRt()
+ *
+ * The reverse of PMRExportPMR().  This causes the PMR to no
+ * longer be exported.  If the PMR has already been imported, the
+ * imported PMR reference will still be valid, but no further imports
+ * will be possible.
+ */
+extern PVRSRV_ERROR
+PMRUnexportPMR(PMR_EXPORT *psPMRExport);
+
+/*
+ * PMRImportPMR()
+ *
+ * Takes a PMR Export object, as obtained by PMRExportPMR(), and
+ * obtains a reference to the original PMR.
+ *
+ * The password must match, and is assumed to have been (by whatever
+ * means, IPC etc.) preserved intact from the former call to
+ * PMRExportPMR()
+ *
+ * The size and contiguity arguments are entirely irrelevant for the
+ * import, however they are verified in order to trap bugs.
+ *
+ * N.B.  If you call PhysmemPMRImport() (and it succeeds), you are
+ * promising to later call PhysmemPMRUnimport()
+ */
+extern PVRSRV_ERROR
+PMRImportPMR(PMR_EXPORT *psPMRExport,
+             PMR_PASSWORD_T uiPassword,
+             PMR_SIZE_T uiSize,
+             PMR_LOG2ALIGN_T uiLog2Contig,
+             PMR **ppsPMR);
+
+/*
+ * PMRUnimportPMR()
+ *
+ * releases the reference on the PMR as obtained by PMRImportPMR()
+ */
+extern PVRSRV_ERROR
+PMRUnimportPMR(PMR *psPMR);
+
+PVRSRV_ERROR
+PMRLocalImportPMR(PMR *psPMR,
+                                 PMR **ppsPMR,
+                                 IMG_DEVMEM_SIZE_T *puiSize,
+                                 IMG_DEVMEM_ALIGN_T *puiAlign);
+
+/*
+ * Equivalent mapping functions when in kernel mode - TOOD: should
+ * unify this and the PMRAcquireMMapArgs API with a suitable
+ * abstraction
+ */
+extern PVRSRV_ERROR
+PMRAcquireKernelMappingData(PMR *psPMR,
+                            IMG_SIZE_T uiLogicalOffset,
+                            IMG_SIZE_T uiSize,
+                            IMG_VOID **ppvKernelAddressOut,
+                            IMG_SIZE_T *puiLengthOut,
+                            IMG_HANDLE *phPrivOut);
+
+extern PVRSRV_ERROR
+PMRAcquireSparseKernelMappingData(PMR *psPMR,
+                                  IMG_SIZE_T uiLogicalOffset,
+                                  IMG_SIZE_T uiSize,
+                                  IMG_VOID **ppvKernelAddressOut,
+                                  IMG_SIZE_T *puiLengthOut,
+                                  IMG_HANDLE *phPrivOut);
+
+extern PVRSRV_ERROR
+PMRReleaseKernelMappingData(PMR *psPMR,
+                            IMG_HANDLE hPriv);
+
+
+/*
+ * PMR_ReadBytes()
+ *
+ * calls into the PMR implementation to read up to uiBufSz bytes,
+ * returning the actual number read in *puiNumBytes
+ *
+ * this will read up to the end of the PMR, or the next symbolic name
+ * boundary, or until the requested number of bytes is read, whichever
+ * comes first
+ *
+ * In the case of sparse PMR's the caller doesn't know what offsets are
+ * valid and which ones aren't so we will just write 0 to invalid offsets
+ */
+extern PVRSRV_ERROR
+PMR_ReadBytes(PMR *psPMR,
+              IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+              IMG_UINT8 *pcBuffer,
+              IMG_SIZE_T uiBufSz,
+              IMG_SIZE_T *puiNumBytes);
+
+/*
+ * PMR_WriteBytes()
+ *
+ * calls into the PMR implementation to write up to uiBufSz bytes,
+ * returning the actual number read in *puiNumBytes
+ *
+ * this will write up to the end of the PMR, or the next symbolic name
+ * boundary, or until the requested number of bytes is written, whichever
+ * comes first
+ *
+ * In the case of sparse PMR's the caller doesn't know what offsets are
+ * valid and which ones aren't so we will just ignore data at invalid offsets
+ */
+extern PVRSRV_ERROR
+PMR_WriteBytes(PMR *psPMR,
+                          IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+               IMG_UINT8 *pcBuffer,
+               IMG_SIZE_T uiBufSz,
+               IMG_SIZE_T *puiNumBytes);
+
+/*
+ * PMRRefPMR()
+ *
+ * Take a reference on the passed in PMR
+ */
+extern IMG_VOID
+PMRRefPMR(PMR *psPMR);
+
+/*
+ * PMRUnrefPMR()
+ *
+ * This undoes a call to any of the PhysmemNew* family of APIs
+ * (i.e. any PMR factory "constructor")
+ *
+ * This relinquishes a reference to the PMR, and, where the refcount
+ * reaches 0, causes the PMR to be destroyed (calling the finalizer
+ * callback on the PMR, if there is one)
+ */
+extern PVRSRV_ERROR
+PMRUnrefPMR(PMR *psPMR);
+
+
+/*
+ * PMR_Flags()
+ *
+ * Flags are static and guaranteed for the life of the PMR.  Thus this
+ * function is idempotent and acquire/release semantics is not
+ * required.
+ *
+ * Returns the flags as specified on the PMR.  The flags are to be
+ * interpreted as mapping permissions
+ */
+extern PVRSRV_ERROR
+PMR_Flags(const PMR *psPMR,
+          PMR_FLAGS_T *puiMappingFlags);
+
+
+extern PVRSRV_ERROR
+PMR_LogicalSize(const PMR *psPMR,
+                               IMG_DEVMEM_SIZE_T *puiLogicalSize);
+
+/*
+ * PMR_SysPhysAddr()
+ *
+ * A note regarding Lock/Unlock semantics
+ * ======================================
+ *
+ * PMR_SysPhysAddr may only be called after PMRLockSysPhysAddresses()
+ * has been called.  The data returned may be used only until
+ * PMRUnlockSysPhysAddresses() is called after which time the licence
+ * to use the data is revoked and the information may be invalid.
+ *
+ * Given an offset, this function returns the device physical address of the
+ * corresponding page in the PMR.  It may be called multiple times
+ * until the address of all relevant pages has been determined.
+ *
+ * If caller only wants one physical address it is sufficient to pass in:
+ * ui32Log2PageSize==0 and ui32NumOfPages==1
+ */
+extern PVRSRV_ERROR
+PMR_DevPhysAddr(const PMR *psPMR,
+                IMG_UINT32 ui32Log2PageSize,
+                IMG_UINT32 ui32NumOfPages,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_DEV_PHYADDR *psDevAddr,
+                IMG_BOOL *pbValid);
+
+/*
+ * PMR_CpuPhysAddr()
+ *
+ * See note above about Lock/Unlock semantics.
+ *
+ * Given an offset, this function returns the CPU physical address of the
+ * corresponding page in the PMR.  It may be called multiple times
+ * until the address of all relevant pages has been determined.
+ *
+ */
+extern PVRSRV_ERROR
+PMR_CpuPhysAddr(const PMR *psPMR,
+                IMG_UINT32 ui32Log2PageSize,
+                IMG_UINT32 ui32NumOfPages,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_CPU_PHYADDR *psCpuAddrPtr,
+                IMG_BOOL *pbValid);
+
+PVRSRV_ERROR
+PMRGetUID(PMR *psPMR,
+                 IMG_UINT64 *pui64UID);
+
+#if defined(PDUMP)
+/*
+ * PMR_PDumpSymbolicAddr()
+ *
+ * Given an offset, returns the pdump memspace name and symbolic
+ * address of the corresponding page in the PMR.
+ *
+ * Note that PDump memspace names and symbolic addresses are static
+ * and valid for the lifetime of the PMR, therefore we don't require
+ * acquire/release semantics here.
+ *
+ * Note that it is expected that the pdump "mapping" code will call
+ * this function multiple times as each page is mapped in turn
+ *
+ * Note that NextSymName is the offset from the base of the PMR to the
+ * next pdump symbolic address (or the end of the PMR if the PMR only
+ * had one PDUMPMALLOC
+ */
+extern PVRSRV_ERROR
+PMR_PDumpSymbolicAddr(const PMR *psPMR,
+                      IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                      IMG_UINT32 ui32NamespaceNameLen,
+                      IMG_CHAR *pszNamespaceName,
+                      IMG_UINT32 ui32SymbolicAddrLen,
+                      IMG_CHAR *pszSymbolicAddr,
+                      IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                     IMG_DEVMEM_OFFSET_T *puiNextSymName
+                      );
+
+/*
+ * PMRPDumpLoadMemValue32()
+ *
+ * writes the current contents of a dword in PMR memory to the pdump
+ * script stream. Useful for patching a buffer by simply editing the
+ * script output file in ASCII plain text.
+ *
+ */
+extern PVRSRV_ERROR
+PMRPDumpLoadMemValue32(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT32 ui32Value,
+                     PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * PMRPDumpLoadMemValue64()
+ *
+ * writes the current contents of a dword in PMR memory to the pdump
+ * script stream. Useful for patching a buffer by simply editing the
+ * script output file in ASCII plain text.
+ *
+ */
+extern PVRSRV_ERROR
+PMRPDumpLoadMemValue64(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT64 ui64Value,
+                     PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * PMRPDumpLoadMem()
+ *
+ * writes the current contents of the PMR memory to the pdump PRM
+ * stream, and emits some PDump code to the script stream to LDB said
+ * bytes from said file. If bZero is IMG_TRUE then the PDump zero page
+ * is used as the source for the LDB.
+ *
+ */
+extern PVRSRV_ERROR
+PMRPDumpLoadMem(PMR *psPMR,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_DEVMEM_SIZE_T uiSize,
+                PDUMP_FLAGS_T uiPDumpFlags,
+                IMG_BOOL bZero);
+
+/*
+ * PMRPDumpSaveToFile()
+ *
+ * emits some PDump that does an SAB (save bytes) using the PDump
+ * symbolic address of the PMR.  Note that this is generally not the
+ * preferred way to dump the buffer contents.  There is an equivalent
+ * function in devicemem_server.h which also emits SAB but using the
+ * virtual address, which is the "right" way to dump the buffer
+ * contents to a file.  This function exists just to aid testing by
+ * providing a means to dump the PMR directly by symbolic address
+ * also.
+ */
+extern PVRSRV_ERROR
+PMRPDumpSaveToFile(const PMR *psPMR,
+                   IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   IMG_UINT32 uiArraySize,
+                   const IMG_CHAR *pszFilename);
+#else  /* PDUMP */
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMR_PDumpSymbolicAddr)
+#endif
+static INLINE PVRSRV_ERROR
+PMR_PDumpSymbolicAddr(const PMR *psPMR,
+                      IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                      IMG_UINT32 ui32NamespaceNameLen,
+                      IMG_CHAR *pszNamespaceName,
+                      IMG_UINT32 ui32SymbolicAddrLen,
+                      IMG_CHAR *pszSymbolicAddr,
+                      IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                      IMG_DEVMEM_OFFSET_T *puiNextSymName)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32NamespaceNameLen);
+       PVR_UNREFERENCED_PARAMETER(pszNamespaceName);
+       PVR_UNREFERENCED_PARAMETER(ui32SymbolicAddrLen);
+       PVR_UNREFERENCED_PARAMETER(pszSymbolicAddr);
+       PVR_UNREFERENCED_PARAMETER(puiNewOffset);
+       PVR_UNREFERENCED_PARAMETER(puiNextSymName);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpLoadMemValue)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpLoadMemValue32(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT32 ui32Value,
+                     PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpLoadMemValue)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpLoadMemValue64(PMR *psPMR,
+                                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                     IMG_UINT64 ui64Value,
+                     PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(ui64Value);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpLoadMem)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpLoadMem(PMR *psPMR,
+                IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                IMG_DEVMEM_SIZE_T uiSize,
+                PDUMP_FLAGS_T uiPDumpFlags,
+                IMG_BOOL bZero)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+       PVR_UNREFERENCED_PARAMETER(bZero);
+       return PVRSRV_OK;
+}
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpSaveToFile)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpSaveToFile(const PMR *psPMR,
+                   IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   IMG_UINT32 uiArraySize,
+                   const IMG_CHAR *pszFilename)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(uiArraySize);
+       PVR_UNREFERENCED_PARAMETER(pszFilename);
+       return PVRSRV_OK;
+}
+
+#endif /* PDUMP */
+
+/* This function returns the private data that a pmr subtype
+   squirrelled in here. We use the function table pointer as
+   "authorization" that this function is being called by the pmr
+   subtype implementation.  We can assume (assert) that.  It would be
+   a bug in the implementation of the pmr subtype if this assertion
+   ever fails. */
+extern IMG_VOID *
+PMRGetPrivateDataHack(const PMR *psPMR,
+                      const PMR_IMPL_FUNCTAB *psFuncTab);
+
+extern PVRSRV_ERROR
+PMRZeroingPMR(PMR *psPMR,
+                               IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize);
+
+PVRSRV_ERROR
+PMRDumpPageList(PMR *psReferencePMR,
+                                       IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize);
+
+extern PVRSRV_ERROR
+PMRWritePMPageList(/* Target PMR, offset, and length */
+                   PMR *psPageListPMR,
+                   IMG_DEVMEM_OFFSET_T uiTableOffset,
+                   IMG_DEVMEM_SIZE_T  uiTableLength,
+                   /* Referenced PMR, and "page" granularity */
+                   PMR *psReferencePMR,
+                   IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
+                   PMR_PAGELIST **ppsPageList,
+                   IMG_UINT64 *pui64CheckSum);
+
+/* Doesn't actually erase the page list - just releases the appropriate refcounts */
+extern PVRSRV_ERROR // should be IMG_VOID, surely
+PMRUnwritePMPageList(PMR_PAGELIST *psPageList);
+
+#if defined(PDUMP)
+extern PVRSRV_ERROR
+PMRPDumpPol32(const PMR *psPMR,
+              IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+              IMG_UINT32 ui32Value,
+              IMG_UINT32 ui32Mask,
+              PDUMP_POLL_OPERATOR eOperator,
+              PDUMP_FLAGS_T uiFlags);
+
+extern PVRSRV_ERROR
+PMRPDumpCBP(const PMR *psPMR,
+            IMG_DEVMEM_OFFSET_T uiReadOffset,
+            IMG_DEVMEM_OFFSET_T uiWriteOffset,
+            IMG_DEVMEM_SIZE_T uiPacketSize,
+            IMG_DEVMEM_SIZE_T uiBufferSize);
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpPol32)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpPol32(const PMR *psPMR,
+              IMG_DEVMEM_OFFSET_T uiLogicalOffset,
+              IMG_UINT32 ui32Value,
+              IMG_UINT32 ui32Mask,
+              PDUMP_POLL_OPERATOR eOperator,
+              PDUMP_FLAGS_T uiFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiLogicalOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(uiFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PMRPDumpCBP)
+#endif
+static INLINE PVRSRV_ERROR
+PMRPDumpCBP(const PMR *psPMR,
+            IMG_DEVMEM_OFFSET_T uiReadOffset,
+            IMG_DEVMEM_OFFSET_T uiWriteOffset,
+            IMG_DEVMEM_SIZE_T uiPacketSize,
+            IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psPMR);
+       PVR_UNREFERENCED_PARAMETER(uiReadOffset);
+       PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+       PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+       PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+       return PVRSRV_OK;
+}
+#endif
+/*
+ * PMRInit()
+ *
+ * To be called once and only once to initialise the internal data in
+ * the PMR module (mutexes and such)
+ *
+ * Not for general use.  Only PVRSRVInit(); should be calling this.
+ */
+extern PVRSRV_ERROR
+PMRInit(IMG_VOID);
+
+/*
+ * PMRDeInit()
+ *
+ * To be called once and only once to deinitialise the internal data in
+ * the PMR module (mutexes and such) and for debug checks
+ *
+ * Not for general use.  Only PVRSRVDeInit(); should be calling this.
+ */
+extern PVRSRV_ERROR
+PMRDeInit(IMG_VOID);
+
+#if defined(PVR_RI_DEBUG)
+extern PVRSRV_ERROR
+PMRStoreRIHandle(PMR *psPMR,
+                                IMG_PVOID hRIHandle);
+#endif
+
+#endif /* #ifdef _SRVSRV_PMR_H_ */
+
diff --git a/drivers/gpu/rogue_m/services/server/include/pmr_impl.h b/drivers/gpu/rogue_m/services/server/include/pmr_impl.h
new file mode 100644 (file)
index 0000000..ff45b24
--- /dev/null
@@ -0,0 +1,180 @@
+/**************************************************************************/ /*!
+@File
+@Title         Implementation Callbacks for Physmem (PMR) abstraction
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Part of the memory management.  This file is for definitions that
+                are private to the world of PMRs, but that needs to be shared between
+                pmr.c itself and the modules that implement the callbacks for the
+                PMR.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef _SRVSRV_PMR_IMPL_H_
+#define _SRVSRV_PMR_IMPL_H_
+
+/* include/ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/* stuff that per-flavour callbacks need to share with pmr.c */
+
+typedef IMG_VOID *PMR_IMPL_PRIVDATA;
+
+typedef PVRSRV_MEMALLOCFLAGS_T PMR_FLAGS_T;
+
+typedef struct {
+    /*
+     * LockPhysAddresses() and UnlockPhysAddresses()
+     *
+     * locks down the physical addresses for the whole PMR.  If memory
+     * is "prefaulted", i.e. exists phsycally at PMR creation time,
+     * then there is no need to override this callback.  The default
+     * implementation is to simply increment a lock-count for
+     * debugging purposes.
+     *
+     * If overridden, this function will be called when someone first
+     * requires a physical addresses, and the UnlockPhysAddresses()
+     * counterpart will be called when the last such reference is
+     * released.
+     *
+     * The PMR implementation may assume that physical addresses will
+     * have been "locked" in this manner before any call is made to
+     * the SysPhysAddr() callback
+     */
+    PVRSRV_ERROR (*pfnLockPhysAddresses)(PMR_IMPL_PRIVDATA pvPriv,
+                                         IMG_UINT32 uiLog2DevPageSize);
+    PVRSRV_ERROR (*pfnUnlockPhysAddresses)(PMR_IMPL_PRIVDATA pvPriv);
+    /*
+     * called iteratively or once to obtain page(s) physical address
+     * ("page" might be device mmu page, or host cpu mmu page, or
+     * something else entirely... the PMR implementation should
+     * make no assumption, and honour the request for a physical
+     * address of any byte in the PMR)
+     *
+     * [ it's the callers responsibility to ensure that no addresses
+     * are missed, by calling this at least as often as once per
+     * "1<<contiguityguarantee" ]
+     *
+     * the LockPhysAddresses callback (if overridden) is guaranteed to
+     * have been called prior to calling this one, and the caller
+     * promises not to rely on the physical address thus obtained
+     * after the UnlockPhysAddresses callback is called.
+     *
+     * Overriding this callback is mandatory in all PMR
+     * implementations.
+     */
+    PVRSRV_ERROR (*pfnDevPhysAddr)(PMR_IMPL_PRIVDATA pvPriv,
+                                   IMG_UINT32 ui32NumOfAddr,
+                                   IMG_DEVMEM_OFFSET_T *puiOffset,
+                                                                  IMG_BOOL *pbValid,
+                                   IMG_DEV_PHYADDR *psDevAddrPtr);
+    /*
+     * called iteratively to obtain PDump symbolic addresses.  Behaves
+     * just like SysPhysAddr callback, except for returning Symbolic
+     * Addresses.
+     *
+     * It is optional to override this callback.  The default
+     * implementation will construct an address from the PMR type and
+     * serial number
+     */
+    PVRSRV_ERROR (*pfnPDumpSymbolicAddr)(PMR_IMPL_PRIVDATA pvPriv,
+                                         IMG_DEVMEM_OFFSET_T uiOffset,
+                                         IMG_CHAR *pszMemspaceName,
+                                         IMG_UINT32 ui32MemspaceNameLen,
+                                         IMG_CHAR *pszSymbolicAddr,
+                                         IMG_UINT32 ui32SymbolicAddrLen,
+                                         IMG_DEVMEM_OFFSET_T *puiNewOffset,
+                                        IMG_DEVMEM_OFFSET_T *puiNextSymName);
+    /*
+     * AcquireKernelMappingData()/ReleaseKernelMappingData()
+     *
+     * called to obtain a kernel virtual address for the PMR for use
+     * internally in services.
+     *
+     * It is not necessary to override this callback, but failure to
+     * do so will mean that kernel mappings will not be possible
+     */
+    PVRSRV_ERROR (*pfnAcquireKernelMappingData)(PMR_IMPL_PRIVDATA pvPriv,
+                                                IMG_SIZE_T uiOffset,
+                                                IMG_SIZE_T uiSize,
+                                                IMG_VOID **ppvKernelAddressOut,
+                                                IMG_HANDLE *phHandleOut,
+                                                PMR_FLAGS_T ulFlags);
+    IMG_VOID (*pfnReleaseKernelMappingData)(PMR_IMPL_PRIVDATA pvPriv,
+                                            IMG_HANDLE hHandle);
+    /*
+     * Read up to uiBufSz bytes from the PMR.
+     * The pmr will be already locked.
+     *
+     * Overriding this is optional.  The default implementation will
+     * acquire a kernel virtual address with
+     * pfnAcquireKernelMappingData and OSMemCopy the data directly
+     */
+    PVRSRV_ERROR (*pfnReadBytes)(PMR_IMPL_PRIVDATA pvPriv,
+                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                 IMG_UINT8 *pcBuffer,
+                                 IMG_SIZE_T uiBufSz,
+                                 IMG_SIZE_T *puiNumBytes);
+
+    /*
+     * Write up to uiBufSz bytes into the PMR.
+     * The pmr will be already locked.
+     *
+     * Overriding this is optional.  The default implementation will
+     * acquire a kernel virtual address with
+     * pfnAcquireKernelMappingData and OSMemCopy the data directly
+     *
+     * Note:
+     * This function callback is optional and unlike pfnReadBytes
+     * isn't required if pfnAcquireKernelMappingData isn't provided
+     */
+    PVRSRV_ERROR (*pfnWriteBytes)(PMR_IMPL_PRIVDATA pvPriv,
+                                  IMG_DEVMEM_OFFSET_T uiOffset,
+                                  IMG_UINT8 *pcBuffer,
+                                  IMG_SIZE_T uiBufSz,
+                                  IMG_SIZE_T *puiNumBytes);
+    /*
+     * Finalize()
+     *
+     * This callback will be called once when the last reference to
+     * the PMR has disappeared.
+     */
+    PVRSRV_ERROR (*pfnFinalize)(PMR_IMPL_PRIVDATA pvPriv);
+} PMR_IMPL_FUNCTAB;
+
+#endif /* of #ifndef _SRVSRV_PHYSMEM_PRIV_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/power.h b/drivers/gpu/rogue_m/services/server/include/power.h
new file mode 100644 (file)
index 0000000..ccbd899
--- /dev/null
@@ -0,0 +1,160 @@
+/*************************************************************************/ /*!
+@File
+@Title          Power Management Functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main APIs for power management functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef POWER_H
+#define POWER_H
+
+
+#include "pvrsrv_device.h"
+
+/*!
+ *****************************************************************************
+ *     Power management
+ *****************************************************************************/
+typedef struct _PVRSRV_POWER_DEV_TAG_
+{
+       PFN_PRE_POWER                                   pfnDevicePrePower;
+       PFN_POST_POWER                                  pfnDevicePostPower;
+       PFN_SYS_DEV_PRE_POWER                   pfnSystemPrePower;
+       PFN_SYS_DEV_POST_POWER                  pfnSystemPostPower;
+       PFN_PRE_CLOCKSPEED_CHANGE               pfnPreClockSpeedChange;
+       PFN_POST_CLOCKSPEED_CHANGE              pfnPostClockSpeedChange;
+       PFN_FORCED_IDLE_REQUEST                 pfnForcedIdleRequest;
+       PFN_FORCED_IDLE_CANCEL_REQUEST          pfnForcedIdleCancelRequest;
+       PFN_DUST_COUNT_REQUEST                  pfnDustCountRequest;
+       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;
+
+typedef IMG_BOOL (*PFN_SYS_DEV_IS_DEFAULT_STATE_OFF)(PVRSRV_POWER_DEV *psPowerDevice);
+
+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_VOID);
+IMG_IMPORT IMG_VOID PVRSRVForcedPowerLock(IMG_VOID);
+IMG_IMPORT IMG_VOID PVRSRVPowerUnlock(IMG_VOID);
+
+IMG_BOOL PVRSRVDeviceIsDefaultStateOFF(PVRSRV_POWER_DEV *psPowerDevice);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32                            ui32DeviceIndex,
+                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState,
+                                                                                IMG_BOOL                               bForced);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState, IMG_BOOL bForced);
+
+/* Type PFN_DC_REGISTER_POWER */
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32                                      ui32DeviceIndex,
+                                                                          PFN_PRE_POWER                                pfnDevicePrePower,
+                                                                          PFN_POST_POWER                               pfnDevicePostPower,
+                                                                          PFN_SYS_DEV_PRE_POWER                pfnSystemPrePower,
+                                                                          PFN_SYS_DEV_POST_POWER               pfnSystemPostPower,
+                                                                          PFN_PRE_CLOCKSPEED_CHANGE    pfnPreClockSpeedChange,
+                                                                          PFN_POST_CLOCKSPEED_CHANGE   pfnPostClockSpeedChange,
+                                                                          PFN_FORCED_IDLE_REQUEST              pfnForcedIdleRequest,
+                                                                          PFN_FORCED_IDLE_CANCEL_REQUEST       pfnForcedIdleCancelRequest,
+                                                                          PFN_DUST_COUNT_REQUEST       pfnDustCountRequest,
+                                                                          IMG_HANDLE                                   hDevCookie,
+                                                                          PVRSRV_DEV_POWER_STATE               eCurrentPowerState,
+                                                                          PVRSRV_DEV_POWER_STATE               eDefaultPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetDevicePowerState(IMG_UINT32 ui32DeviceIndex, PPVRSRV_DEV_POWER_STATE pePowerState);
+
+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);
+
+PVRSRV_ERROR PVRSRVDeviceIdleRequestKM(IMG_BOOL                                        bAllDevices,
+                                       IMG_UINT32                              ui32DeviceIndex,
+                                       PFN_SYS_DEV_IS_DEFAULT_STATE_OFF        pfnCheckIdleReq,
+                                       IMG_BOOL                                bDeviceOffPermitted);
+
+PVRSRV_ERROR PVRSRVDeviceIdleCancelRequestKM(IMG_BOOL                  bAllDevices,
+                                               IMG_UINT32              ui32DeviceIndex);
+
+PVRSRV_ERROR PVRSRVDeviceDustCountChange(IMG_UINT32    ui32DeviceIndex,
+                                               IMG_UINT32      ui32DustCount);
+
+
+#endif /* POWER_H */
+
+/******************************************************************************
+ End of file (power.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/include/process_stats.h b/drivers/gpu/rogue_m/services/server/include/process_stats.h
new file mode 100644 (file)
index 0000000..39b1534
--- /dev/null
@@ -0,0 +1,168 @@
+/*************************************************************************/ /*!
+@File
+@Title          Functions for creating and reading proc filesystem entries.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PROCESS_STATS_H__
+#define __PROCESS_STATS_H__
+
+#include "pvrsrv_error.h"
+
+/*
+ *  The publishing of Process Stats is controlled by the
+ *  PVRSRV_ENABLE_PROCESS_STATS build option. The recording of all Memory
+ *  allocations is controlled by the PVRSRV_ENABLE_MEMORY_STATS build option.
+ * 
+ *  Note: There will be a performance degradation with memory allocation
+ *        recording enabled!
+ */
+
+
+/*
+ *  Memory types which can be tracked...
+ */
+typedef enum {
+    PVRSRV_MEM_ALLOC_TYPE_KMALLOC,                             /* memory allocated by kmalloc() */
+    PVRSRV_MEM_ALLOC_TYPE_VMALLOC,                             /* memory allocated by kmalloc() */
+    PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA,  /* pages allocated from UMA to hold page table information */
+    PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA,                 /* ALLOC_PAGES_PT_UMA mapped to kernel address space */
+    PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA,  /* pages allocated from LMA to hold page table information */
+    PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA,              /* ALLOC_PAGES_PT_LMA mapped to kernel address space */
+    PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES,             /* pages allocated from LMA */
+    PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES,             /* pages allocated from UMA */
+    PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES,   /* mapped UMA/LMA pages  */
+    PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES,              /* pages in the page pool */
+
+       /* Must be the last enum...*/
+    PVRSRV_MEM_ALLOC_TYPE_COUNT
+} PVRSRV_MEM_ALLOC_TYPE;
+
+
+/*
+ * Functions for managing the processes recorded...
+ */
+PVRSRV_ERROR  PVRSRVStatsInitialise(IMG_VOID);
+
+IMG_VOID  PVRSRVStatsDestroy(IMG_VOID);
+
+PVRSRV_ERROR  PVRSRVStatsRegisterProcess(IMG_HANDLE* phProcessStats);
+
+IMG_VOID  PVRSRVStatsDeregisterProcess(IMG_HANDLE hProcessStats);
+
+#define MAX_POWER_STAT_ENTRIES         51
+
+/*
+ * Functions for recording the statistics...
+ */
+IMG_VOID  PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                       IMG_VOID *pvCpuVAddr,
+                                       IMG_CPU_PHYADDR sCpuPAddr,
+                                       IMG_SIZE_T uiBytes,
+                                       IMG_PVOID pvPrivateData);
+
+IMG_VOID  PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                                                 IMG_UINT64 ui64Key);
+
+IMG_VOID PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_SIZE_T uiBytes);
+/*
+ * Increases the memory stat for eAllocType. Tracks the allocation size value
+ * by inserting a value into a hash table with uiCpuVAddr as key.
+ * Pair with PVRSRVStatsDecrMemAllocStatAndUntrack().
+ */
+IMG_VOID PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_SIZE_T uiBytes,
+                                                               IMG_UINT64 uiCpuVAddr);
+
+IMG_VOID PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_SIZE_T uiBytes);
+
+/*
+ * Decrease the memory stat for eAllocType. Takes the allocation size value from the
+ * hash table with uiCpuVAddr as key. Pair with PVRSRVStatsIncrMemAllocStatAndTrack().
+ */
+IMG_VOID PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
+                                                               IMG_UINT64 uiCpuVAddr);
+
+IMG_VOID
+PVRSRVStatsIncrMemAllocPoolStat(IMG_SIZE_T uiBytes);
+
+IMG_VOID
+PVRSRVStatsDecrMemAllocPoolStat(IMG_SIZE_T uiBytes);
+
+IMG_VOID  PVRSRVStatsUpdateRenderContextStats(IMG_UINT32 ui32TotalNumPartialRenders,
+                                              IMG_UINT32 ui32TotalNumOutOfMemory,
+                                              IMG_UINT32 ui32TotalTAStores,
+                                              IMG_UINT32 ui32Total3DStores,
+                                              IMG_UINT32 ui32TotalSHStores,
+                                              IMG_UINT32 ui32TotalCDMStores,
+                                              IMG_PID owner);
+
+IMG_VOID  PVRSRVStatsUpdateZSBufferStats(IMG_UINT32 ui32NumReqByApp,
+                                         IMG_UINT32 ui32NumReqByFW,
+                                         IMG_PID owner);
+
+IMG_VOID  PVRSRVStatsUpdateFreelistStats(IMG_UINT32 ui32NumGrowReqByApp,
+                                         IMG_UINT32 ui32NumGrowReqByFW,
+                                         IMG_UINT32 ui32InitFLPages,
+                                         IMG_UINT32 ui32NumHighPages,
+                                         IMG_PID       ownerPid);
+
+
+typedef enum
+{
+    PVRSRV_POWER_ENTRY_TYPE_PRE,
+    PVRSRV_POWER_ENTRY_TYPE_POST
+} PVRSRV_POWER_ENTRY_TYPE;
+
+IMG_VOID InsertPowerTimeStatistic(PVRSRV_POWER_ENTRY_TYPE bType,
+                                                               IMG_INT32 ui32CurrentState, IMG_INT32 ui32NextState,
+                                IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime,
+                                                               IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime,
+                                                               IMG_BOOL bForced);
+
+IMG_VOID InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer);
+IMG_VOID InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer);
+
+IMG_VOID SetFirmwareStartTime(IMG_UINT32 ui32TimeStamp);
+
+IMG_VOID SetFirmwareHandshakeIdleTime(IMG_UINT64 ui64Duration);
+
+#endif /* __PROCESS_STATS_H__ */
diff --git a/drivers/gpu/rogue_m/services/server/include/pvr_dvfs.h b/drivers/gpu/rogue_m/services/server/include/pvr_dvfs.h
new file mode 100644 (file)
index 0000000..c3bd53f
--- /dev/null
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@File           pvr_dvfs.h
+@Title          System level interface for DVFS
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This file defined the API between services and system layer
+                required for Ion integration.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PVR_DVFS_H_
+#define _PVR_DVFS_H_
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+
+typedef IMG_VOID (*PFN_SYS_DEV_DVFS_SET_FREQUENCY)(IMG_UINT32 ui64Freq);
+typedef IMG_VOID (*PFN_SYS_DEV_DVFS_SET_VOLTAGE)(IMG_UINT32 ui64Volt);
+
+typedef struct _IMG_OPP_
+{
+       IMG_UINT32                      ui32Volt;
+       IMG_UINT32                      ui32Freq;
+} IMG_OPP;
+
+typedef const IMG_OPP* IMG_OPP_TABLE;
+
+typedef struct _IMG_DVFS_GOVERNOR_CFG_
+{
+       IMG_UINT32                      ui32UpThreshold;
+       IMG_UINT32                      ui32DownDifferential;
+} IMG_DVFS_GOVERNOR_CFG;
+
+typedef struct _IMG_DVFS_DEVICE_CFG_
+{
+       IMG_OPP_TABLE                   pasOPPTable;
+       IMG_UINT32                      ui32OPPTableSize;
+
+       IMG_UINT32                      ui32FreqMin;
+       IMG_UINT32                      ui32FreqMax;
+       IMG_UINT32                      ui32PollMs;
+       IMG_BOOL                        bIdleReq;
+
+       PFN_SYS_DEV_DVFS_SET_FREQUENCY  pfnSetFrequency;
+       PFN_SYS_DEV_DVFS_SET_VOLTAGE    pfnSetVoltage;
+} IMG_DVFS_DEVICE_CFG;
+
+typedef struct _IMG_DVFS_GOVERNOR_
+{
+       IMG_BOOL                        bEnabled;
+} IMG_DVFS_GOVERNOR;
+
+#if defined(__linux__)
+typedef struct _IMG_DVFS_DEVICE_
+{
+       POS_LOCK                        hDVFSLock;
+       struct dev_pm_opp               *psOPP;
+       struct devfreq                  *psDevFreq;
+       IMG_BOOL                        bEnabled;
+       IMG_HANDLE                      hGpuUtilUserDVFS;
+} IMG_DVFS_DEVICE;
+
+typedef struct _IMG_POWER_AVG_
+{
+       IMG_UINT32                      ui32Power;
+       IMG_UINT32                      ui32Samples;
+} IMG_POWER_AVG;
+
+typedef struct _IMG_DVFS_PA_
+{
+       IMG_UINT32                      ui32AllocatedPower;
+       IMG_UINT32                      *aui32ConversionTable;
+       IMG_OPP                         sOPPCurrent;
+       IMG_INT32                       i32Temp;
+       IMG_UINT64                      ui64StartTime;
+       IMG_UINT32                      ui32Energy;
+       POS_LOCK                        hDVFSLock;
+       struct power_actor              *psPowerActor;
+       IMG_POWER_AVG                   sPowerAvg;
+} IMG_DVFS_PA;
+
+typedef struct _IMG_DVFS_PA_CFG_
+{
+       /* Coefficients for a curve defining power leakage due to temperature */
+       IMG_INT32                       i32Ta;          /* t^3 */
+       IMG_INT32                       i32Tb;          /* t^2 */
+       IMG_INT32                       i32Tc;          /* t^1 */
+       IMG_INT32                       i32Td;          /* const */
+
+       IMG_UINT32                      ui32Other;      /* Static losses unrelated to GPU */
+       IMG_UINT32                      ui32Weight;     /* Power actor weight */
+} IMG_DVFS_PA_CFG;
+
+typedef struct _IMG_DVFS_
+{
+       IMG_DVFS_DEVICE                 sDVFSDevice;
+       IMG_DVFS_GOVERNOR               sDVFSGovernor;
+       IMG_DVFS_DEVICE_CFG             sDVFSDeviceCfg;
+       IMG_DVFS_GOVERNOR_CFG           sDVFSGovernorCfg;
+#if defined(PVR_POWER_ACTOR)
+       IMG_DVFS_PA                     sDVFSPA;
+       IMG_DVFS_PA_CFG                 sDVFSPACfg;
+#endif
+} PVRSRV_DVFS;
+#endif/* (__linux__) */
+
+#endif /* _PVR_DVFS_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/pvrsrv.h b/drivers/gpu/rogue_m/services/server/include/pvrsrv.h
new file mode 100644 (file)
index 0000000..0ad41c0
--- /dev/null
@@ -0,0 +1,515 @@
+/**************************************************************************/ /*!
+@File
+@Title          PowerVR services server header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef PVRSRV_H
+#define PVRSRV_H
+
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+#include "device.h"
+#include "power.h"
+#include "sysinfo.h"
+#include "physheap.h"
+
+typedef struct _SYS_DEVICE_ID_TAG
+{
+       IMG_UINT32      uiID;
+       IMG_BOOL        bInUse;
+
+} SYS_DEVICE_ID;
+
+
+typedef struct PVRSRV_DATA_TAG
+{
+    IMG_UINT32                  ui32NumDevices;                /*!< number of devices in system */
+       SYS_DEVICE_ID                           sDeviceID[SYS_DEVICE_COUNT];
+       PVRSRV_DEVICE_NODE                      *apsRegisteredDevNodes[SYS_DEVICE_COUNT];
+       IMG_UINT32                                      ui32RegisteredDevices;
+       IMG_UINT32                                      ui32CurrentOSPowerState;        /*!< current OS specific power state */
+       PVRSRV_DEVICE_NODE                      *psDeviceNodeList;                      /*!< List head of device nodes */
+       struct _DEVICE_COMMAND_DATA_ *apsDeviceCommandData[SYS_DEVICE_COUNT];
+
+       IMG_UINT32                                      ui32RegisteredPhysHeaps;
+       PHYS_HEAP                                       *apsRegisteredPhysHeaps[SYS_PHYS_HEAP_COUNT];
+
+    PVRSRV_POWER_DEV                   *psPowerDeviceList;                     /*!< list of devices registered with the power manager */
+       POS_LOCK                                        hPowerLock;                                     /*!< lock for power state transitions */
+       PVRSRV_SYS_POWER_STATE          eCurrentPowerState;                     /*!< current Kernel services power state */
+       PVRSRV_SYS_POWER_STATE          eFailedPowerState;                      /*!< Kernel services power state (Failed to transition to) */
+
+       PVRSRV_SERVICES_STATE           eServicesState;                         /*!< global driver state */
+
+       IMG_HANDLE                                      hGlobalEventObject;                     /*!< OS Global Event Object */
+       IMG_UINT32                                      ui32GEOConsecutiveTimeouts;     /*!< OS Global Event Object Timeouts */
+       
+       PVRSRV_CACHE_OP                         uiCacheOp;                                      /*!< Pending cache operations in the system */
+
+       IMG_HANDLE                                      hCleanupThread;                         /*!< Cleanup thread */
+       IMG_HANDLE                                      hCleanupEventObject;            /*!< Event object to drive cleanup thread */
+       POS_LOCK                                        hCleanupThreadWorkListLock;     /*!< Lock protecting the cleanup thread work list */
+       DLLIST_NODE                                     sCleanupThreadWorkList;         /*!< List of work to do by the cleanup thread */
+       IMG_PID                                         cleanupThreadPid;                       /*!< Cleanup thread process id */
+
+       IMG_HANDLE                                      hDevicesWatchdogThread;         /*!< Devices Watchdog thread */
+       IMG_HANDLE                                      hDevicesWatchdogEvObj;          /*! Event object to drive devices watchdog thread */
+       volatile IMG_UINT32                     ui32DevicesWatchdogPwrTrans;/*! Number of off -> on power state transitions */
+       volatile IMG_UINT32                     ui32DevicesWatchdogTimeout; /*! Timeout for the Devices Watchdog Thread */
+#ifdef PVR_TESTING_UTILS
+       volatile IMG_UINT32                     ui32DevicesWdWakeupCounter;     /* Need this for the unit tests. */
+#endif
+
+       IMG_BOOL                                        bUnload;                                        /*!< Driver unload is in progress */
+} PVRSRV_DATA;
+
+
+typedef IMG_HANDLE PVRSRV_CMDCOMP_HANDLE;
+typedef IMG_VOID (*PFN_CMDCOMP_NOTIFY) (PVRSRV_CMDCOMP_HANDLE hCmdCompHandle);
+
+typedef struct PVRSRV_CMDCOMP_NOTIFY_TAG
+{
+       PVRSRV_CMDCOMP_HANDLE   hCmdCompHandle;
+       PFN_CMDCOMP_NOTIFY              pfnCmdCompleteNotify;
+
+       DLLIST_NODE                                     sListNode;
+} PVRSRV_CMDCOMP_NOTIFY;
+
+#define DEBUG_REQUEST_VERBOSITY_LOW            0
+#define DEBUG_REQUEST_VERBOSITY_MEDIUM 1
+#define DEBUG_REQUEST_VERBOSITY_HIGH   2
+
+#define DEBUG_REQUEST_VERBOSITY_MAX    (DEBUG_REQUEST_VERBOSITY_HIGH)
+
+typedef IMG_HANDLE PVRSRV_DBGREQ_HANDLE;
+typedef IMG_VOID (*PFN_DBGREQ_NOTIFY) (PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel);
+
+typedef struct PVRSRV_DBGREQ_NOTIFY_TAG
+{
+       PVRSRV_DBGREQ_HANDLE    hDbgRequestHandle;
+       PFN_DBGREQ_NOTIFY               pfnDbgRequestNotify;
+       IMG_UINT32                              ui32RequesterID;
+
+       DLLIST_NODE                                     sListNode;
+} PVRSRV_DBGREQ_NOTIFY;
+
+/*!
+*******************************************************************************
+
+ @Description
+
+ Macro used within debug dump functions to send output either to PVR_LOG or
+ a custom function.
+
+******************************************************************************/
+#define PVR_DUMPDEBUG_LOG(x)                                   \
+       do                                                                                      \
+       {                                                                                       \
+               if (pfnDumpDebugPrintf)                                 \
+               {                                                                               \
+                       pfnDumpDebugPrintf x;                           \
+               }                                                                               \
+               else                                                                    \
+               {                                                                               \
+                       PVR_LOG(x);                                                     \
+               }                                                                               \
+       } while(0)
+
+/*!
+*******************************************************************************
+
+ @Description
+
+ Typedef for custom debug dump output functions.
+
+******************************************************************************/
+typedef void (DUMPDEBUG_PRINTF_FUNC)(const IMG_CHAR *pszFormat, ...);
+
+extern DUMPDEBUG_PRINTF_FUNC *g_pfnDumpDebugPrintf;
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVGetPVRSRVData
+
+ @Description  Get a pointer to the global data
+
+ @Return   PVRSRV_DATA *
+
+******************************************************************************/
+PVRSRV_DATA *PVRSRVGetPVRSRVData(IMG_VOID);
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+                                                   PVRSRV_DEVICE_TYPE *peDeviceType,
+                                                   PVRSRV_DEVICE_CLASS *peDeviceClass,
+                                                   IMG_UINT32 *pui32DeviceIndex);
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32                        ui32DevIndex,
+                                                                                                        PVRSRV_DEVICE_TYPE     eDeviceType,
+                                                                                                        IMG_HANDLE                     *phDevCookie);
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseDeviceDataKM (IMG_HANDLE hDevCookie);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                                                                       IMG_UINT32 *pui32DeviceIndex,
+                                                                                                       IMG_UINT32 ui32PhysHeapID);
+
+IMG_VOID IMG_CALLCONV PVRSRVUnregisterExtDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSysPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState, IMG_BOOL bForced);
+
+PVRSRV_ERROR LMA_MMUPxAlloc(PVRSRV_DEVICE_NODE *psDevNode, IMG_SIZE_T uiSize,
+                                                       Px_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr);
+
+IMG_VOID LMA_MMUPxFree(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle);
+
+PVRSRV_ERROR LMA_MMUPxMap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                                       IMG_SIZE_T uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+                                                       IMG_VOID **pvPtr);
+
+IMG_VOID LMA_MMUPxUnmap(PVRSRV_DEVICE_NODE *psDevNode, Px_HANDLE *psMemHandle,
+                                               IMG_VOID *pvPtr);
+                                                                               
+
+/*!
+******************************************************************************
+ @Function     PVRSRVPollForValueKM
+
+ @Description
+ Polls for a value to match a masked read
+
+ @Input pui32LinMemAddr : CPU linear address to poll
+ @Input ui32Value : required value
+ @Input ui32Mask : Mask
+
+ @Return   PVRSRV_ERROR :
+******************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVPollForValueKM(volatile IMG_UINT32  *pui32LinMemAddr,
+                                                                                                                 IMG_UINT32                    ui32Value,
+                                                                                                                 IMG_UINT32                    ui32Mask);
+
+/*!
+******************************************************************************
+ @Function     PVRSRVWaitForValueKM
+
+ @Description
+ Waits (using EventObjects) for a value to match a masked read
+
+ @Input pui32LinMemAddr                        : CPU linear address to poll
+ @Input ui32Value                              : required value
+ @Input ui32Mask                               : Mask
+
+ @Return   PVRSRV_ERROR :
+******************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForValueKM(volatile IMG_UINT32  *pui32LinMemAddr,
+                                                                                                               IMG_UINT32                      ui32Value,
+                                                                                                               IMG_UINT32                      ui32Mask);
+
+/*!
+******************************************************************************
+ @Function     PVRSRVWaitForValueKMAndHoldBridgeLockKM
+
+ @Description
+ Waits without releasing bridge lock (using EventObjects) for a value
+ to match a masked read
+
+ @Input pui32LinMemAddr                        : CPU linear address to poll
+ @Input ui32Value                              : required value
+ @Input ui32Mask                               : Mask
+
+ @Return   PVRSRV_ERROR :
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWaitForValueKMAndHoldBridgeLockKM(volatile IMG_UINT32 *pui32LinMemAddr,
+                                                                  IMG_UINT32          ui32Value,
+                                                                  IMG_UINT32          ui32Mask);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVSystemDebugInfo
+
+ @Description  : Dump the system debug info
+
+@Input pfnDumpDebugPrintf : Used to specify the appropriate printf function.
+                            If this argument is IMG_NULL, then PVR_LOG() will
+                            be used as the default printing function.
+
+*****************************************************************************/
+PVRSRV_ERROR PVRSRVSystemDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVGetSystemName
+
+ @Description  : Gets the system name string
+
+ @Return : The system name
+*****************************************************************************/
+const IMG_CHAR *PVRSRVGetSystemName(IMG_VOID);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVSystemHasCacheSnooping
+
+ @Description  : Returns whether the system has cache snooping
+
+ @Return : IMG_TRUE if the system has cache snooping
+*****************************************************************************/
+IMG_BOOL PVRSRVSystemHasCacheSnooping(IMG_VOID);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVSystemSnoopingOfCPUCache
+
+ @Description  : Returns whether the system supports snooping of the CPU cache
+
+ @Return : IMG_TRUE if the system has CPU cache snooping
+*****************************************************************************/
+IMG_BOOL PVRSRVSystemSnoopingOfCPUCache(IMG_VOID);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVSystemSnoopingOfDeviceCache
+
+ @Description  : Returns whether the system supports snooping of the device cache
+
+ @Return : IMG_TRUE if the system has device cache snooping
+*****************************************************************************/
+IMG_BOOL PVRSRVSystemSnoopingOfDeviceCache(IMG_VOID);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVSystemWaitCycles
+
+ @Description  : Waits for at least ui32Cycles of the Device clk.
+
+*****************************************************************************/
+IMG_VOID PVRSRVSystemWaitCycles(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT32 ui32Cycles);
+
+
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVCheckStatus
+
+ @Description  : Notify any registered cmd complete function (except if its
+                                 hPrivData matches the hCmdCompHandle handler) and raise the global 
+                                 event object. 
+
+ @Input hCmdCompHandle : Identify the caller by the handler used when 
+                                                 registering for cmd complete. IMG_NULL calls all
+                                                 the notify functions.
+
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV PVRSRVCheckStatus(PVRSRV_CMDCOMP_HANDLE hCmdCompCallerHandle);
+
+PVRSRV_ERROR IMG_CALLCONV PVRSRVKickDevicesKM(IMG_VOID);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVResetHWRLogsKM
+
+ @Description  : Resets the HWR Logs buffer (the hardware recovery count is not reset)
+
+ @Input psDeviceNode   : Pointer to the device
+
+ @Return   PVRSRV_ERROR : PVRSRV_OK on success. Otherwise, a PVRSRV_ error code
+*****************************************************************************
+ */
+PVRSRV_ERROR PVRSRVResetHWRLogsKM(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVRegisterCmdCompleteNotify
+
+ @Description  : Register a notify function which is called when some device
+                                 finishes some work (that is, when someone calls to PVRSRVCheckStatus).
+
+ @Input phNotify : Pointer to the Cmd complete notify handler
+
+ @Input pfnCmdCompleteNotify : Notify function
+
+ @Input hPrivData : Handler to data passed to the Notify function when called
+
+*****************************************************************************/
+PVRSRV_ERROR PVRSRVRegisterCmdCompleteNotify(IMG_HANDLE *phNotify, PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, PVRSRV_CMDCOMP_HANDLE hPrivData);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVUnregisterCmdCompleteNotify
+
+ @Description  : Unregister a previously registered notify func.
+
+ @Input hNotify : Cmd complete notify handler registered previously
+
+*****************************************************************************/
+PVRSRV_ERROR PVRSRVUnregisterCmdCompleteNotify(IMG_HANDLE hNotify);
+
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVDebugRequest
+
+ @Description  : Notify any registered debug request handler that a debug
+                  request has been made and at what level. It dumps information 
+                 for all debug handlers unlike RGXDumpDebugInfo
+
+ @Input ui32VerbLevel  : The maximum verbosity level to dump
+
+ @Input pfnDumpDebugPrintf : Used to specify the appropriate printf function.
+                            If this argument is IMG_NULL, then PVR_LOG() will
+                            be used as the default printing function.
+
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV PVRSRVDebugRequest(IMG_UINT32 ui32VerbLevel, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVRegisterDebugRequestNotify
+
+ @Description  : Register a notify function which is called when a debug
+                                 request is made into the driver (that is, when someone
+                                 calls to PVRSRVDebugRequest). There are a number of levels
+                                 of verbosity, starting at 0 and going to
+                                 DEBUG_REQUEST_VERBOSITY_MAX. For each level that's required
+                                 a new call to the notify function will be made.
+
+ @Input phNotify : Pointer to the debug request notify handler
+
+ @Input pfnDbgRequestNotify : Notify function
+
+ @Input ui32RequesterID : Used to determine the order debug request callbacks get
+                          called in with the table passed into 
+
+ @Input hDbgReqeustHandle : Handler to data passed to the Notify function when called
+
+*****************************************************************************/
+PVRSRV_ERROR PVRSRVRegisterDbgRequestNotify(IMG_HANDLE *phNotify, PFN_DBGREQ_NOTIFY pfnDbgRequestNotify, IMG_UINT32 ui32RequesterID, PVRSRV_DBGREQ_HANDLE hDbgReqeustHandle);
+
+/*!
+*****************************************************************************
+ @Function     : PVRSRVUnregisterDebugRequestNotify
+
+ @Description  : Unregister a previously registered notify func.
+
+ @Input hNotify : Debug request notify handler registered previously
+
+*****************************************************************************/
+PVRSRV_ERROR PVRSRVUnregisterDbgRequestNotify(IMG_HANDLE hNotify);
+
+/*!
+*****************************************************************************
+ @Function     : AcquireGlobalEventObjectServer
+
+ @Description  : Acquire the global event object.
+
+ @Output phGlobalEventObject : Handle to the global event object
+
+*****************************************************************************/
+PVRSRV_ERROR AcquireGlobalEventObjectServer(IMG_HANDLE *phGlobalEventObject);
+
+/*!
+*****************************************************************************
+ @Function     : ReleaseGlobalEventObjectServer
+
+ @Description  : Release the global event object.
+
+ @Input hGlobalEventObject : Handle to the global event object
+
+*****************************************************************************/
+PVRSRV_ERROR ReleaseGlobalEventObjectServer(IMG_HANDLE hGlobalEventObject);
+
+
+/*!
+*****************************************************************************
+ @Function     : GetBIFTilingHeapXStride
+
+ @Description  : return the default x-stride configuration for the given
+                  BIF tiling heap number
+
+ @Input uiHeapNum: BIF tiling heap number, starting from 1
+
+ @Output puiXStride: pointer to x-stride output of the requested heap
+
+*****************************************************************************/
+PVRSRV_ERROR GetBIFTilingHeapXStride(IMG_UINT32 uiHeapNum, IMG_UINT32 *puiXStride);
+
+/*!
+*****************************************************************************
+ @Function     : GetNumBIFTilingHeaps
+
+ @Description  : return the number of BIF tiling heaps on this system
+
+ @Output puiNumHeaps: pointer to uint to hold number of heaps
+
+*****************************************************************************/
+PVRSRV_ERROR GetNumBifTilingHeapConfigs(IMG_UINT32 *puiNumHeaps);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+/*!
+***********************************************************************************
+ @Function                             : PopulateLMASubArenas
+
+ @Description                  : Uses the Apphints passed by the client at initialization
+                                                 time to add bases and sizes in the various arenas in the
+                                                 LMA memory
+
+ @Input psDeviceNode   : Pointer to the device node struct containing all the
+                                                 arena information
+
+ @Input ui32OSidMin            : Single dimensional array containing the minimum values
+                                                 for each OSid area
+
+ @Input ui32OSidMax            : Single dimensional array containing the maximum values
+                                                 for each OSid area
+***********************************************************************************/
+
+IMG_VOID PopulateLMASubArenas(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 aui32OSidMin[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS], IMG_UINT32 aui32OSidMax[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS]);
+#endif
+
+#endif /* PVRSRV_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/pvrsrv_cleanup.h b/drivers/gpu/rogue_m/services/server/include/pvrsrv_cleanup.h
new file mode 100644 (file)
index 0000000..fba346e
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************************/ /*!
+@File
+@Title          PowerVR SrvKM cleanup thread deferred work interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef PVRSRV_CLEANUP_H
+#define PVRSRV_CLEANUP_H
+
+typedef PVRSRV_ERROR (*CLEANUP_THREAD_FN)(void *pvParam);
+
+/* typical number of times a caller should want the work to be retried in case
+ * of the callback function (pfnFree) returning an error.
+ * Callers to PVRSRVCleanupThreadAddWork should provide this value as the retry
+ * count (ui32RetryCount) unless there are special requirements.
+ * A value of 6000 corresponds to around 10 minutes.
+ */
+#define CLEANUP_THREAD_RETRY_COUNT_DEFAULT 6000
+
+typedef struct _PVRSRV_CLEANUP_THREAD_WORK_
+{
+       DLLIST_NODE sNode; /*!< list node to attach to the cleanup thread work list */
+       CLEANUP_THREAD_FN pfnFree; /*!< function to be called */
+       void *pvData; /*!< private data for pfnFree */
+       IMG_UINT32 ui32RetryCount; /*!< number of times the callback should be re-tried when it returns error */
+} PVRSRV_CLEANUP_THREAD_WORK;
+
+/*!
+******************************************************************************
+ @Function                PVRSRVCleanupThreadAddWork
+
+ @Description             Add a work item to be called from the cleanup thread
+
+ @Input psData          : The function pointer and private data for the callback
+
+ @Return                  None
+******************************************************************************/
+void PVRSRVCleanupThreadAddWork(PVRSRV_CLEANUP_THREAD_WORK *psData);
+
+#endif /* PVRSRV_CLEANUP_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/pvrsrv_device.h b/drivers/gpu/rogue_m/services/server/include/pvrsrv_device.h
new file mode 100644 (file)
index 0000000..0453e71
--- /dev/null
@@ -0,0 +1,193 @@
+/**************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef __PVRSRV_DEVICE_H__
+#define __PVRSRV_DEVICE_H__
+
+#include "servicesext.h"
+#include "pvrsrv_device_types.h"
+#include "img_types.h"
+#include "ra.h"
+#include "physheap.h"
+#include "rgx_fwif_km.h"
+#include "pmr.h"
+#include "lock.h"
+#include "pvr_dvfs.h"
+
+typedef struct _PVRSRV_DEVICE_CONFIG_ PVRSRV_DEVICE_CONFIG;
+
+/*! The CPU physical base of the LMA physical heap is used as the base for
+ *  device memory physical heap allocations */
+#define PVRSRV_DEVICE_CONFIG_LMA_USE_CPU_ADDR  (1<<0)
+
+/*
+ *  The maximum number of physical heaps associated
+ *  with a device
+ */
+typedef enum
+{
+       PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL = 0,
+       PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL = 1,
+       PVRSRV_DEVICE_PHYS_HEAP_LAST
+}PVRSRV_DEVICE_PHYS_HEAP;
+
+typedef enum
+{
+       PVRSRV_DEVICE_IRQ_ACTIVE_SYSDEFAULT = 0,
+       PVRSRV_DEVICE_IRQ_ACTIVE_LOW,
+       PVRSRV_DEVICE_IRQ_ACTIVE_HIGH
+}PVRSRV_DEVICE_IRQ_ACTIVE_LEVEL;
+
+typedef IMG_VOID (*PFN_MISR)(IMG_VOID *pvData);
+
+typedef IMG_BOOL (*PFN_LISR)(IMG_VOID *pvData);
+
+typedef IMG_UINT32 (*PFN_SYS_DEV_CLK_FREQ_GET)(IMG_HANDLE hSysData);
+
+typedef PVRSRV_ERROR (*PFN_SYS_DEV_PRE_POWER)(PVRSRV_DEV_POWER_STATE eNewPowerState,
+                                              PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+                                                                                         IMG_BOOL bForced);
+
+
+typedef PVRSRV_ERROR (*PFN_SYS_DEV_POST_POWER)(PVRSRV_DEV_POWER_STATE eNewPowerState,
+                                               PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+                                                                                          IMG_BOOL bForced);
+
+typedef IMG_VOID (*PFN_SYS_DEV_INTERRUPT_HANDLED)(PVRSRV_DEVICE_CONFIG *psDevConfig);
+
+typedef PVRSRV_ERROR (*PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                                                                                IMG_UINT64 ui64MemSize);
+
+struct _PVRSRV_DEVICE_CONFIG_
+{
+       /*! Configuration flags */
+       IMG_UINT32                      uiFlags;
+
+       /*! Name of the device (used when registering the IRQ) */
+       IMG_CHAR                        *pszName;
+
+       /*! Type of device this is */
+       PVRSRV_DEVICE_TYPE              eDeviceType;
+
+       /*! Register bank address */
+       IMG_CPU_PHYADDR                 sRegsCpuPBase;
+       /*! Register bank size */
+       IMG_UINT32                      ui32RegsSize;
+       /*! Device interrupt number */
+       IMG_UINT32                      ui32IRQ;
+
+       /*! The device interrupt is shared */
+       IMG_BOOL                        bIRQIsShared;
+
+       /*! IRQ polarity */
+       PVRSRV_DEVICE_IRQ_ACTIVE_LEVEL  eIRQActiveLevel;
+
+       /*! Device specific data handle */
+       IMG_HANDLE                      hDevData;
+
+       /*! System specific data. This gets passed into system callback functions */
+       IMG_HANDLE                      hSysData;
+
+       /*! ID of the Physical memory heap to use
+        *! The first entry (aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL])  will be used for allocations
+        *!  where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is not set. Normally this will be the PhysHeapID
+        *!  of an LMA heap (but the configuration could specify a UMA heap here, if desired)
+        *! The second entry (aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) will be used for allocations
+        *!  where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is set. Normally this will be the PhysHeapID
+        *!  of a UMA heap (but the configuration could specify an LMA heap here, if desired)
+        *! In the event of there being only one Physical Heap, the configuration should specify the
+        *!  same heap details in both entries */
+       IMG_UINT32                      aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_LAST];
+
+       /*! Callback to inform the device we about to change power state */
+       PFN_SYS_DEV_PRE_POWER           pfnPrePowerState;
+
+       /*! Callback to inform the device we have finished the power state change */
+       PFN_SYS_DEV_POST_POWER          pfnPostPowerState;
+
+       /*! Callback to obtain the clock frequency from the device */
+       PFN_SYS_DEV_CLK_FREQ_GET        pfnClockFreqGet;
+
+       /*! Callback to inform the device that an interrupt has been handled */
+       PFN_SYS_DEV_INTERRUPT_HANDLED   pfnInterruptHandled;
+
+       /*! Callback to handle memory budgeting */
+       PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE        pfnCheckMemAllocSize;
+
+       /*! Current breakpoint data master */
+       RGXFWIF_DM                      eBPDM;
+       /*! A Breakpoint has been set */
+       IMG_BOOL                        bBPSet; 
+
+#if defined(PVR_DVFS)
+       PVRSRV_DVFS                     sDVFS;
+#endif
+};
+
+typedef PVRSRV_ERROR (*PFN_SYSTEM_PRE_POWER_STATE)(PVRSRV_SYS_POWER_STATE eNewPowerState);
+typedef PVRSRV_ERROR (*PFN_SYSTEM_POST_POWER_STATE)(PVRSRV_SYS_POWER_STATE eNewPowerState);
+
+typedef enum _PVRSRV_SYSTEM_SNOOP_MODE_ {
+       PVRSRV_SYSTEM_SNOOP_NONE = 0,
+       PVRSRV_SYSTEM_SNOOP_CPU_ONLY,
+       PVRSRV_SYSTEM_SNOOP_DEVICE_ONLY,
+       PVRSRV_SYSTEM_SNOOP_CROSS,
+} PVRSRV_SYSTEM_SNOOP_MODE;
+
+typedef struct _PVRSRV_SYSTEM_CONFIG_
+{
+       IMG_UINT32                              uiSysFlags;
+       IMG_CHAR                                *pszSystemName;
+       IMG_UINT32                              uiDeviceCount;
+       PVRSRV_DEVICE_CONFIG    *pasDevices;
+       PFN_SYSTEM_PRE_POWER_STATE pfnSysPrePowerState;
+       PFN_SYSTEM_POST_POWER_STATE pfnSysPostPowerState;
+       PVRSRV_SYSTEM_SNOOP_MODE eCacheSnoopingMode;
+
+       PHYS_HEAP_CONFIG                *pasPhysHeaps;
+       IMG_UINT32                              ui32PhysHeapCount;
+
+       IMG_UINT32              *pui32BIFTilingHeapConfigs;
+       IMG_UINT32              ui32BIFTilingHeapCount;
+} PVRSRV_SYSTEM_CONFIG;
+
+
+#endif /* __PVRSRV_DEVICE_H__*/
diff --git a/drivers/gpu/rogue_m/services/server/include/ri_server.h b/drivers/gpu/rogue_m/services/server/include/ri_server.h
new file mode 100644 (file)
index 0000000..9a98a30
--- /dev/null
@@ -0,0 +1,87 @@
+/*************************************************************************/ /*!
+@File                  ri_server.h
+@Title          Resource Information abstraction
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description   Resource Information (RI) functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RI_SERVER_H_
+#define _RI_SERVER_H_
+
+#include <img_defs.h>
+#include <ri_typedefs.h>
+#include <pmr.h>
+#include <pvrsrv_error.h>
+
+PVRSRV_ERROR RIInitKM(IMG_VOID);
+IMG_VOID RIDeInitKM(IMG_VOID);
+
+PVRSRV_ERROR RIWritePMREntryKM(PMR *hPMR,
+                                                          IMG_UINT32 ui32TextASize,
+                                                          const IMG_CHAR ai8TextA[RI_MAX_TEXT_LEN+1],
+                                                          IMG_UINT64 uiLogicalSize);
+
+PVRSRV_ERROR RIWriteMEMDESCEntryKM(PMR *hPMR,
+                                                                  IMG_UINT32 ui32TextBSize,
+                                                                  const IMG_CHAR ai8TextB[RI_MAX_TEXT_LEN+1],
+                                                                  IMG_UINT64 uiOffset,
+                                                                  IMG_UINT64 uiSize,
+                                                                  IMG_BOOL bIsImport,
+                                                                  IMG_BOOL bIsExportable,
+                                                                  RI_HANDLE *phRIHandle);
+
+PVRSRV_ERROR RIUpdateMEMDESCAddrKM(RI_HANDLE hRIHandle,
+                                                                  IMG_DEV_VIRTADDR sVAddr);
+
+PVRSRV_ERROR RIDeletePMREntryKM(RI_HANDLE hRIHandle);
+PVRSRV_ERROR RIDeleteMEMDESCEntryKM(RI_HANDLE hRIHandle);
+
+PVRSRV_ERROR RIDeleteListKM(IMG_VOID);
+
+PVRSRV_ERROR RIDumpListKM(PMR *hPMR);
+
+PVRSRV_ERROR RIDumpAllKM(IMG_VOID);
+
+PVRSRV_ERROR RIDumpProcessKM(IMG_PID pid);
+
+IMG_BOOL RIGetListEntryKM(IMG_PID pid,
+                                                 IMG_HANDLE **ppHandle,
+                                                 IMG_CHAR **ppszEntryString);
+
+#endif /* #ifndef _RI_SERVER_H _*/
diff --git a/drivers/gpu/rogue_m/services/server/include/secure_export.h b/drivers/gpu/rogue_m/services/server/include/secure_export.h
new file mode 100644 (file)
index 0000000..55aac8c
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pmr.h"
+#include "connection_server.h"
+
+typedef struct _SECURE_CLEANUP_DATA_ {
+       PMR *psPMR;
+} SECURE_CLEANUP_DATA;
+
+PVRSRV_ERROR PMRSecureExportPMR(CONNECTION_DATA *psConnection,
+                                                               PMR *psPMR,
+                                                               IMG_SECURE_TYPE *phSecure,
+                                                               PMR **ppsPMR,
+                                                               CONNECTION_DATA **ppsSecureConnection);
+
+PVRSRV_ERROR PMRSecureUnexportPMR(PMR *psPMR);
+
+PVRSRV_ERROR PMRSecureImportPMR(IMG_SECURE_TYPE hSecure,
+                                                               PMR **ppsPMR,
+                                                               IMG_DEVMEM_SIZE_T *puiSize,
+                                                               IMG_DEVMEM_ALIGN_T *puiAlign);
+
+PVRSRV_ERROR PMRSecureUnimportPMR(PMR *psPMR);
+
diff --git a/drivers/gpu/rogue_m/services/server/include/srvcore.h b/drivers/gpu/rogue_m/services/server/include/srvcore.h
new file mode 100644 (file)
index 0000000..038a1c9
--- /dev/null
@@ -0,0 +1,203 @@
+/**************************************************************************/ /*!
+@File
+@Title          PVR Bridge Functionality
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Header for the PVR Bridge code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef __BRIDGED_PVR_BRIDGE_H__
+#define __BRIDGED_PVR_BRIDGE_H__
+
+#include "lock_types.h"
+#include "connection_server.h"
+#include "pvr_debug.h"
+
+#include "pvr_bridge.h"
+#if defined(SUPPORT_RGX)
+#include "rgx_bridge.h"
+#endif
+#include "pvr_bridge_io.h"
+
+#ifndef ENOMEM
+#define ENOMEM 12
+#endif
+#ifndef EFAULT
+#define EFAULT 14
+#endif
+#ifndef ENOTTY
+#define ENOTTY 25
+#endif
+
+PVRSRV_ERROR
+CopyFromUserWrapper(CONNECTION_DATA *psConnection,
+                                       IMG_UINT32 ui32DispatchTableEntry,
+                                       IMG_VOID *pvDest,
+                                       IMG_VOID *pvSrc,
+                                       IMG_UINT32 ui32Size);
+PVRSRV_ERROR
+CopyToUserWrapper(CONNECTION_DATA *psConnection, 
+                                 IMG_UINT32 ui32DispatchTableEntry,
+                                 IMG_VOID *pvDest,
+                                 IMG_VOID *pvSrc,
+                                 IMG_UINT32 ui32Size);
+
+IMG_INT
+DummyBW(IMG_UINT32 ui32DispatchTableEntry,
+               IMG_VOID *psBridgeIn,
+               IMG_VOID *psBridgeOut,
+               CONNECTION_DATA *psConnection);
+
+typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32DispatchTableEntry,
+                                                                        IMG_VOID *psBridgeIn,
+                                                                        IMG_VOID *psBridgeOut,
+                                                                        CONNECTION_DATA *psConnection);
+
+typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
+{
+       BridgeWrapperFunction pfFunction; /*!< The wrapper function that validates the ioctl
+                                                                               arguments before calling into srvkm proper */
+       POS_LOCK        hBridgeLock;    /*!< The bridge lock which needs to be acquired 
+                                               before calling the above wrapper */
+       IMG_PVOID       pvBridgeBuffer; /*!< The buffer that will be used for bridgeIn and bridgeOut structs during this bridge call */
+       IMG_UINT32      ui32BridgeInBufferSize; /*!< Available bridge input buffer size */
+       IMG_UINT32      ui32BridgeOutBufferSize;        /*!< Available bridge output buffer size */
+#if defined(DEBUG_BRIDGE_KM)
+       const IMG_CHAR *pszIOCName; /*!< Name of the ioctl: e.g. "PVRSRV_BRIDGE_CONNECT_SERVICES" */
+       const IMG_CHAR *pszFunctionName; /*!< Name of the wrapper function: e.g. "PVRSRVConnectBW" */
+       const IMG_CHAR *pszBridgeLockName;      /*!< Name of bridge lock which will be acquired */
+       IMG_UINT32 ui32CallCount; /*!< The total number of times the ioctl has been called */
+       IMG_UINT32 ui32CopyFromUserTotalBytes; /*!< The total number of bytes copied from
+                                                                                        userspace within this ioctl */
+       IMG_UINT32 ui32CopyToUserTotalBytes; /*!< The total number of bytes copied from
+                                                                                  userspace within this ioctl */
+#endif
+}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
+
+#if defined(SUPPORT_RGX)
+       #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT  (PVRSRV_BRIDGE_RGX_DISPATCH_LAST+1)
+       #define BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT  (PVRSRV_BRIDGE_RGX_LAST+1)
+#else
+       #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT  (PVRSRV_BRIDGE_DISPATCH_LAST+1)
+       #define BRIDGE_DISPATCH_TABLE_START_ENTRY_COUNT  (PVRSRV_BRIDGE_LAST+1)
+#endif
+
+extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
+
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32BridgeGroup,
+                                          IMG_UINT32 ui32Index,
+                                          const IMG_CHAR *pszIOCName,
+                                          BridgeWrapperFunction pfFunction,
+                                          const IMG_CHAR *pszFunctionName,
+                                          POS_LOCK hBridgeLock,
+                                          const IMG_CHAR* pszBridgeLockName,
+                                          IMG_BYTE* pbyBridgeBuffer,
+                                          IMG_UINT32 ui32BridgeInBufferSize,
+                                          IMG_UINT32 ui32BridgeOutBufferSize );
+
+
+/* PRQA S 0884,3410 2*/ /* macro relies on the lack of brackets */
+#define SetDispatchTableEntry(ui32BridgeGroup, ui32Index, pfFunction,\
+                                       hBridgeLock, pbyBridgeBuffer,\
+                                       ui32BridgeInBufferSize, ui32BridgeOutBufferSize) \
+       _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32BridgeGroup), ui32Index, #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction,\
+                                                       (POS_LOCK)hBridgeLock, #hBridgeLock,\
+                                                       pbyBridgeBuffer, ui32BridgeInBufferSize, ui32BridgeOutBufferSize )
+
+#define DISPATCH_TABLE_GAP_THRESHOLD 5
+
+
+#if defined(DEBUG_BRIDGE_KM)
+typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS
+{
+       IMG_UINT32 ui32IOCTLCount;
+       IMG_UINT32 ui32TotalCopyFromUserBytes;
+       IMG_UINT32 ui32TotalCopyToUserBytes;
+} PVRSRV_BRIDGE_GLOBAL_STATS;
+
+/* OS specific code may want to report the stats held here and within the
+ * BRIDGE_DISPATCH_TABLE_ENTRYs (E.g. on Linux we report these via a
+ * debugfs entry /sys/kernel/debug/pvr/bridge_stats) */
+extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
+#endif
+
+
+IMG_INT BridgedDispatchKM(CONNECTION_DATA * psConnection,
+                                         PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM);
+
+
+PVRSRV_ERROR
+PVRSRVConnectKM(CONNECTION_DATA *psConnection,
+                               IMG_UINT32 ui32Flags,
+                               IMG_UINT32 ui32ClientBuildOptions,
+                               IMG_UINT32 ui32ClientDDKVersion,
+                               IMG_UINT32 ui32ClientDDKBuild,
+                               IMG_UINT8  *pui8KernelArch,
+                               IMG_UINT32 *ui32Log2PageSize);
+
+PVRSRV_ERROR
+PVRSRVDisconnectKM(IMG_VOID);
+
+PVRSRV_ERROR
+PVRSRVInitSrvDisconnectKM(CONNECTION_DATA *psConnection,
+                                                       IMG_BOOL bInitSuccesful,
+                                                       IMG_UINT32 ui32ClientBuildOptions);
+
+PVRSRV_ERROR
+PVRSRVDumpDebugInfoKM(IMG_UINT32 ui32VerbLevel);
+
+PVRSRV_ERROR
+PVRSRVGetDevClockSpeedKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+                                                       IMG_PUINT32  pui32RGXClockSpeed);
+
+PVRSRV_ERROR
+PVRSRVHWOpTimeoutKM(IMG_VOID);
+
+/* performs a SOFT_RESET on the given device node */
+PVRSRV_ERROR
+PVRSRVSoftResetKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+                  IMG_UINT64 ui64ResetValue1,
+                  IMG_UINT64 ui64ResetValue2);
+
+
+#endif /* __BRIDGED_PVR_BRIDGE_H__ */
+
+/******************************************************************************
+ End of file (bridged_pvr_bridge.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/server/include/srvkm.h b/drivers/gpu/rogue_m/services/server/include/srvkm.h
new file mode 100644 (file)
index 0000000..40c6dcb
--- /dev/null
@@ -0,0 +1,193 @@
+/**************************************************************************/ /*!
+@File
+@Title          Services kernel module internal header file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef SRVKM_H
+#define SRVKM_H
+
+#include "servicesext.h"
+
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+/**    Use PVR_DPF() unless message is necessary in release build
+ */
+#ifdef PVR_DISABLE_LOGGING
+#define PVR_LOG(X)
+#else
+/* PRQA S 3410 1 */ /* this macro requires no brackets in order to work */
+#define PVR_LOG(X)                     PVRSRVReleasePrintf X;
+#endif
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVInit
+
+ @Description  Initialise services
+
+ @Input           psSysData    : sysdata structure
+
+ @Return   PVRSRV_ERROR        :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(void *);
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVDeInit
+
+ @Description  De-Initialise services
+
+ @Input           psSysData    : sysdata structure
+
+ @Return   PVRSRV_ERROR        :
+
+******************************************************************************/
+IMG_VOID IMG_CALLCONV PVRSRVDeInit(IMG_VOID *);
+
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVScheduleDevicesKM
+
+ @Description  Schedules all Services-Managed Devices to check their pending
+                               command queues. The intention is that ScheduleDevices be called by the
+                               3rd party BC driver after it has finished writing new data to its output
+                               texture.
+
+ @Input                bInLISR
+
+ @Return       IMG_VOID
+
+******************************************************************************/
+IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_BOOL bInLISR);
+
+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);
+
+/*!
+******************************************************************************
+
+ @Function     PVRSRVScheduleDeviceCallbacks
+
+ @Description  Schedule all device callbacks
+
+ @Input                ui32CallerID
+
+ @Return       IMG_VOID
+
+******************************************************************************/
+IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_UINT32 ui32CallerID);
+
+
+
+/******************
+HIGHER LEVEL MACROS
+*******************/
+
+/*----------------------------------------------------------------------------
+Repeats the body of the loop for a certain minimum time, or until the body
+exits by its own means (break, return, goto, etc.)
+
+Example of usage:
+
+LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+{
+       if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
+       {
+               bTimeout = IMG_FALSE;
+               break;
+       }
+       
+       OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
+} END_LOOP_UNTIL_TIMEOUT();
+
+-----------------------------------------------------------------------------*/
+
+/*     uiNotLastLoop will remain at 1 until the timeout has expired, at which time             
+ *     it will be decremented and the loop executed one final time. This is necessary
+ *     when preemption is enabled. 
+ */
+/* PRQA S 3411,3431 12 */ /* critical format, leave alone */
+#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() \
+}
+
+/*!
+ ******************************************************************************
+
+ @Function             PVRSRVGetErrorStringKM
+
+ @Description  Returns a text string relating to the PVRSRV_ERROR enum.
+
+ ******************************************************************************/
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
+
+/*
+       FIXME: This should be defined elsewhere when server sync are implemented
+*/
+typedef struct _SERVER_SYNC_PRIM_
+{
+       /* Placeholder until structure is properly implemented */
+       IMG_UINT32 ui32Placeholder;
+} SERVER_SYNC_PRIM;
+
+
+#endif /* SRVKM_H */
diff --git a/drivers/gpu/rogue_m/services/server/include/sync_server.h b/drivers/gpu/rogue_m/services/server/include/sync_server.h
new file mode 100644 (file)
index 0000000..10cebd1
--- /dev/null
@@ -0,0 +1,345 @@
+/**************************************************************************/ /*!
+@File
+@Title          Server side synchronisation interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Describes the server side synchronisation functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "img_types.h"
+#include "device.h"
+#include "devicemem.h"
+#include "pdump.h"
+#include "pvrsrv_error.h"
+#include "connection_server.h"
+
+#ifndef _SYNC_SERVER_H_
+#define _SYNC_SERVER_H_
+
+typedef struct _SERVER_OP_COOKIE_ SERVER_OP_COOKIE;
+typedef struct _SERVER_SYNC_PRIMITIVE_ SERVER_SYNC_PRIMITIVE;
+typedef struct _SYNC_PRIMITIVE_BLOCK_ SYNC_PRIMITIVE_BLOCK;
+typedef struct _SERVER_SYNC_EXPORT_ SERVER_SYNC_EXPORT;
+typedef struct _SYNC_CONNECTION_DATA_ SYNC_CONNECTION_DATA;
+typedef struct SYNC_RECORD* SYNC_RECORD_HANDLE;
+
+typedef struct _SYNC_ADDR_LIST_
+{
+       IMG_UINT32 ui32NumSyncs;
+       PRGXFWIF_UFO_ADDR *pasFWAddrs;
+} SYNC_ADDR_LIST;
+
+PVRSRV_ERROR
+SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock,
+                                               IMG_UINT32 ui32Offset,
+                                               PRGXFWIF_UFO_ADDR *psAddrOut);
+
+IMG_VOID
+SyncAddrListInit(SYNC_ADDR_LIST *psList);
+
+IMG_VOID
+SyncAddrListDeinit(SYNC_ADDR_LIST *psList);
+
+PVRSRV_ERROR
+SyncAddrListPopulate(SYNC_ADDR_LIST *psList,
+                                               IMG_UINT32 ui32NumSyncs,
+                                               SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock,
+                                               IMG_UINT32 *paui32SyncOffset);
+
+PVRSRV_ERROR
+PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection,
+                                                               PVRSRV_DEVICE_NODE *psDevNode,
+                                                               SYNC_PRIMITIVE_BLOCK **ppsSyncBlk,
+                                                               IMG_UINT32 *puiSyncPrimVAddr,
+                                                               IMG_UINT32 *puiSyncPrimBlockSize,
+                                                               DEVMEM_EXPORTCOOKIE **psExportCookie);
+
+PVRSRV_ERROR
+PVRSRVExportSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk,
+                                                                DEVMEM_EXPORTCOOKIE **psExportCookie);
+
+PVRSRV_ERROR
+PVRSRVUnexportSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk);
+
+PVRSRV_ERROR
+PVRSRVFreeSyncPrimitiveBlockKM(SYNC_PRIMITIVE_BLOCK *ppsSyncBlk);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimSetKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Index,
+                                       IMG_UINT32 ui32Value);
+
+PVRSRV_ERROR
+PVRSRVServerSyncPrimSetKM(SERVER_SYNC_PRIMITIVE *psServerSync, IMG_UINT32 ui32Value);
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+PVRSRV_ERROR
+PVRSRVSyncPrimServerExportKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                       SERVER_SYNC_EXPORT **ppsExport);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerUnexportKM(SERVER_SYNC_EXPORT *psExport);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerImportKM(SERVER_SYNC_EXPORT *psExport,
+                                                        SERVER_SYNC_PRIMITIVE **ppsSync,
+                                                        IMG_UINT32 *pui32SyncPrimVAddr);
+#endif
+
+#if defined(SUPPORT_SECURE_EXPORT)
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureExportKM(CONNECTION_DATA *psConnection,
+                                                                  SERVER_SYNC_PRIMITIVE *psSync,
+                                                                  IMG_SECURE_TYPE *phSecure,
+                                                                  SERVER_SYNC_EXPORT **ppsExport,
+                                                                  CONNECTION_DATA **ppsSecureConnection);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureUnexportKM(SERVER_SYNC_EXPORT *psExport);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimServerSecureImportKM(IMG_SECURE_TYPE hSecure,
+                                                                  SERVER_SYNC_PRIMITIVE **ppsSync,
+                                                                  IMG_UINT32 *pui32SyncPrimVAddr);
+#endif
+
+IMG_UINT32 PVRSRVServerSyncRequesterRegisterKM(IMG_UINT32 *pui32SyncRequesterID);
+IMG_VOID PVRSRVServerSyncRequesterUnregisterKM(IMG_UINT32 ui32SyncRequesterID);
+
+PVRSRV_ERROR
+PVRSRVSyncRecordAddKM(
+                       SYNC_RECORD_HANDLE * phRecord,
+                       SYNC_PRIMITIVE_BLOCK * hServerSyncPrimBlock,
+                       IMG_UINT32 ui32FwBlockAddr,
+                       IMG_UINT32 ui32SyncOffset,
+                       IMG_BOOL bServerSync,
+                       IMG_UINT32 ui32ClassNameSize,
+                       const IMG_CHAR *pszClassName);
+PVRSRV_ERROR
+PVRSRVSyncRecordRemoveByHandleKM(
+                       SYNC_RECORD_HANDLE hRecord);
+
+PVRSRV_ERROR
+PVRSRVServerSyncAllocKM(PVRSRV_DEVICE_NODE *psDevNode,
+                                               SERVER_SYNC_PRIMITIVE **ppsSync,
+                                               IMG_UINT32 *pui32SyncPrimVAddr,
+                                               IMG_UINT32 ui32ClassNameSize,
+                                               const IMG_CHAR *szClassName);
+PVRSRV_ERROR
+PVRSRVServerSyncFreeKM(SERVER_SYNC_PRIMITIVE *psSync);
+
+PVRSRV_ERROR
+PVRSRVServerSyncGetStatusKM(IMG_UINT32 ui32SyncCount,
+                                                       SERVER_SYNC_PRIMITIVE **papsSyncs,
+                                                       IMG_UINT32 *pui32UID,
+                                                       IMG_UINT32 *pui32FWAddr,
+                                                       IMG_UINT32 *pui32CurrentOp,
+                                                       IMG_UINT32 *pui32NextOp);
+
+PVRSRV_ERROR
+PVRSRVServerSyncQueueSWOpKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                 IMG_UINT32 *pui32FenceValue,
+                                                 IMG_UINT32 *pui32UpdateValue,
+                                                 IMG_UINT32 ui32SyncRequesterID,
+                                                 IMG_BOOL bUpdate,
+                                                 IMG_BOOL *pbFenceRequired);
+
+PVRSRV_ERROR
+PVRSRVServerSyncQueueHWOpKM(SERVER_SYNC_PRIMITIVE *psSync,
+                                                          IMG_BOOL bUpdate,
+                                                      IMG_UINT32 *pui32FenceValue,
+                                                      IMG_UINT32 *pui32UpdateValue);
+
+IMG_BOOL
+ServerSyncFenceIsMet(SERVER_SYNC_PRIMITIVE *psSync,
+                                        IMG_UINT32 ui32FenceValue);
+
+IMG_VOID
+ServerSyncCompleteOp(SERVER_SYNC_PRIMITIVE *psSync,
+                                        IMG_BOOL bDoUpdate,
+                                        IMG_UINT32 ui32UpdateValue);
+
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpCreateKM(IMG_UINT32 ui32SyncBlockCount,
+                                                SYNC_PRIMITIVE_BLOCK **papsSyncPrimBlock,
+                                                IMG_UINT32 ui32ClientSyncCount,
+                                                IMG_UINT32 *paui32SyncBlockIndex,
+                                                IMG_UINT32 *paui32Index,
+                                                IMG_UINT32 ui32ServerSyncCount,
+                                                SERVER_SYNC_PRIMITIVE **papsServerSync,
+                                                SERVER_OP_COOKIE **ppsServerCookie);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpTakeKM(SERVER_OP_COOKIE *psServerCookie,
+                                              IMG_UINT32 ui32ClientSyncCount,
+                                              IMG_UINT32 *paui32Flags,
+                                              IMG_UINT32 *paui32FenceValue,
+                                              IMG_UINT32 *paui32UpdateValue,
+                                              IMG_UINT32 ui32ServerSyncCount,
+                                                  IMG_UINT32 *paui32ServerFlags);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpReadyKM(SERVER_OP_COOKIE *psServerCookie,
+                                               IMG_BOOL *pbReady);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpCompleteKM(SERVER_OP_COOKIE *psServerCookie);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpDestroyKM(SERVER_OP_COOKIE *psServerCookie);
+
+IMG_UINT32 ServerSyncGetId(SERVER_SYNC_PRIMITIVE *psSync);
+
+IMG_UINT32 ServerSyncGetFWAddr(SERVER_SYNC_PRIMITIVE *psSync);
+
+IMG_UINT32 ServerSyncGetValue(SERVER_SYNC_PRIMITIVE *psSync);
+
+IMG_UINT32 ServerSyncGetNextValue(SERVER_SYNC_PRIMITIVE *psSync);
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+IMG_VOID SyncRecordLookup(IMG_UINT32 ui32FwAddr, IMG_CHAR * pszSyncInfo, IMG_SIZE_T len);
+#endif
+
+IMG_VOID ServerSyncDumpPending(IMG_VOID);
+
+PVRSRV_ERROR SyncRegisterConnection(SYNC_CONNECTION_DATA **ppsSyncConnectionData);
+IMG_VOID SyncUnregisterConnection(SYNC_CONNECTION_DATA *ppsSyncConnectionData);
+IMG_VOID SyncConnectionPDumpSyncBlocks(SYNC_CONNECTION_DATA *ppsSyncConnectionData);
+
+PVRSRV_ERROR ServerSyncInit(IMG_VOID);
+IMG_VOID ServerSyncDeinit(IMG_VOID);
+
+#if defined(PDUMP)
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, 
+                                                       IMG_UINT32 ui32Value);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset,
+                                                IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T uiDumpFlags);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimOpPDumpPolKM(SERVER_OP_COOKIE *psServerCookie,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T ui32PDumpFlags);
+
+PVRSRV_ERROR
+PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset,
+                                                IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize,
+                                                IMG_UINT64 uiBufferSize);
+
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVSyncPrimPDumpKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset)
+{
+       PVR_UNREFERENCED_PARAMETER(psSyncBlk);
+       PVR_UNREFERENCED_PARAMETER(ui32Offset);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpValueKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVSyncPrimPDumpValueKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset, 
+                                                       IMG_UINT32 ui32Value)
+{
+       PVR_UNREFERENCED_PARAMETER(psSyncBlk);
+       PVR_UNREFERENCED_PARAMETER(ui32Offset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVSyncPrimPDumpPolKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT32 ui32Offset,
+                                                IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T uiDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psSyncBlk);
+       PVR_UNREFERENCED_PARAMETER(ui32Offset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(uiDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimOpPDumpPolKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVSyncPrimOpPDumpPolKM(SERVER_OP_COOKIE *psServerCookie,
+                                                PDUMP_POLL_OPERATOR eOperator,
+                                                PDUMP_FLAGS_T uiDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psServerCookie);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(uiDumpFlags);
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVSyncPrimPDumpCBPKM)
+#endif
+static INLINE PVRSRV_ERROR
+PVRSRVSyncPrimPDumpCBPKM(SYNC_PRIMITIVE_BLOCK *psSyncBlk, IMG_UINT64 ui32Offset,
+                                                IMG_UINT64 uiWriteOffset, IMG_UINT64 uiPacketSize,
+                                                IMG_UINT64 uiBufferSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psSyncBlk);
+       PVR_UNREFERENCED_PARAMETER(ui32Offset);
+       PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+       PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+       PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+#endif /*_SYNC_SERVER_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/sync_server_internal.h b/drivers/gpu/rogue_m/services/server/include/sync_server_internal.h
new file mode 100644 (file)
index 0000000..3a913df
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************/ /*!
+@File
+@Title          Server side internal synchronisation interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Describes the server side internal synchronisation functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef _SYNC_SERVER_INTERNAL_H_
+#define _SYNC_SERVER_INTERNAL_H_
+
+#include "img_types.h"
+
+IMG_VOID
+ServerSyncRef(SERVER_SYNC_PRIMITIVE *psSync);
+
+IMG_VOID
+ServerSyncUnref(SERVER_SYNC_PRIMITIVE *psSync);
+
+#endif /*_SYNC_SERVER_INTERNAL_H_ */
diff --git a/drivers/gpu/rogue_m/services/server/include/tlintern.h b/drivers/gpu/rogue_m/services/server/include/tlintern.h
new file mode 100644 (file)
index 0000000..2aaa776
--- /dev/null
@@ -0,0 +1,273 @@
+/*************************************************************************/ /*!
+@File
+@Title          Transport Layer internals
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport Layer header used by TL internally
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __TLINTERN_H__
+#define __TLINTERN_H__
+
+
+#include "devicemem_typedefs.h"
+#include "pvr_tlcommon.h"
+#include "device.h"
+#include "lock.h"
+
+/* Forward declarations */
+typedef struct _TL_SNODE_* PTL_SNODE;
+
+/*! TL stream structure container.
+ *    pbyBuffer   holds the circular buffer.
+ *    ui32Read    points to the beginning of the buffer, ie to where data to
+ *                  Read begin.
+ *    ui32Write   points to the end of data that have been committed, ie this is
+ *                  where new data will be written.
+ *    ui32Pending number of bytes reserved in last reserve call which have not
+ *                  yet been submitted. Therefore these data are not ready to
+ *                  be transported.
+ *    hStreamLock - provides atomic protection for the ui32Pending & ui32Write
+ *                  members of the structure for when they are checked and/or
+ *                  updated in the context of a stream writer (producer)
+ *                  calling DoTLStreamReserve() & TLStreamCommit().
+ *                - Reader context is not multi-threaded, only one client per
+ *                  stream is allowed. Also note the read context may be in an
+ *                  ISR which prevents a design where locks can be held in the
+ *                  AcquireData/ReleaseData() calls. Thus this lock only
+ *                  protects the stream members from simultaneous writers.
+ *
+ *      ui32Read < ui32Write <= ui32Pending 
+ *        where < and <= operators are overloaded to make sense in a circular way.
+ */
+typedef struct _TL_STREAM_ 
+{
+       IMG_CHAR                        szName[PRVSRVTL_MAX_STREAM_NAME_SIZE];  /*!< String name identifier */
+       IMG_BOOL                        bDrop;                                  /*!< Flag: When buffer is full drop new data instead of 
+                                                                                                                  overwriting older data */
+       IMG_BOOL                        bBlock;                                 /*!< Flag: When buffer is full reserve will block until there is
+                                                                                                                  enough free space in the buffer to fullfil the request. */
+       IMG_BOOL                        bWaitForEmptyOnDestroy; /*!< Flag: On destroying a non empty stream block until 
+                                                                                                                  stream is drained. */
+       IMG_BOOL            bNoSignalOnCommit;      /*!< Flag: Used to avoid the TL signalling waiting consumers
+                                                           that new data is available on every commit. Producers
+                                                           using this flag will need to manually signal when
+                                                           appropriate using the TLStreamSync() API */
+
+       IMG_VOID                        (*pfProducerCallback)(IMG_VOID); /*!< Optional producer callback of type TL_STREAM_SOURCECB */
+       IMG_PVOID                       pvProducerUserData;                  /*!< Producer callback user data */
+
+       volatile IMG_UINT32 ui32Read;                           /*!< Pointer to the beginning of available data */
+       volatile IMG_UINT32 ui32Write;                          /*!< Pointer to already committed data which are ready to be
+                                                                                                        copied to user space*/
+       IMG_UINT32                      ui32BufferUt;                   /*!< Buffer utilisation high watermark, see
+                                                                                                * TL_BUFFER_UTILIZATION in tlstream.c */
+       IMG_UINT32                      ui32Pending;                    /*!< Count pending bytes reserved in buffer */
+       IMG_UINT32                      ui32Size;                               /*!< Buffer size */
+       IMG_BYTE                        *pbyBuffer;                             /*!< Actual data buffer */
+
+       PTL_SNODE                       psNode;                                 /*!< Ptr to parent stream node */
+       DEVMEM_MEMDESC          *psStreamMemDesc;               /*!< MemDescriptor used to allocate buffer space through PMR */
+       DEVMEM_EXPORTCOOKIE sExportCookie;                      /*!< Export cookie for stream DEVMEM */
+
+       IMG_HANDLE                      hProducerEvent;                 /*!< Handle to wait on if there is not enough space */
+       IMG_HANDLE                      hProducerEventObj;              /*!< Handle to signal blocked reserve calls */
+
+       POS_LOCK                        hStreamLock;                    /*!< Lock for ui32Pending & ui32Write*/
+} TL_STREAM, *PTL_STREAM;
+
+/* there need to be enough space reserved in the buffer for 2 minimal packets
+ * and it needs to be aligned the same way the buffer is or there will be a
+ * compile error.*/
+#define BUFFER_RESERVED_SPACE 2*PVRSRVTL_PACKET_ALIGNMENT
+
+/* ensure the space reserved follows the buffer's alignment */
+BLD_ASSERT(!(BUFFER_RESERVED_SPACE&(PVRSRVTL_PACKET_ALIGNMENT-1)), tlintern_h);
+
+/* Define the largest value that a uint that matches the 
+ * PVRSRVTL_PACKET_ALIGNMENT size can hold */
+#define MAX_UINT 0xffffFFFF
+
+/*! Defines the value used for TL_STREAM.ui32Pending when no reserve is
+ * outstanding on the stream. */
+#define NOTHING_PENDING IMG_UINT32_MAX
+
+
+/*
+ * Transport Layer Stream Descriptor types/defs
+ */
+typedef struct _TL_STREAM_DESC_
+{
+       PTL_SNODE       psNode;                 /*!< Ptr to parent stream node */
+       IMG_UINT32      ui32Flags;
+       IMG_HANDLE      hDataEvent;     /*!< For wait call */
+} TL_STREAM_DESC, *PTL_STREAM_DESC;
+
+PTL_STREAM_DESC TLMakeStreamDesc(PTL_SNODE f1, IMG_UINT32 f2, IMG_HANDLE f3);
+
+#define TL_STREAM_KM_FLAG_MASK 0xFFFF0000
+#define TL_STREAM_FLAG_TEST            0x10000000
+#define TL_STREAM_FLAG_WRAPREAD        0x00010000
+
+#define TL_STREAM_UM_FLAG_MASK 0x0000FFFF
+
+/*
+ * Transport Layer stream list node
+ */
+typedef struct _TL_SNODE_
+{
+       struct _TL_SNODE_*  psNext;                             /*!< Linked list next element */
+       IMG_HANDLE                      hDataEventObj;          /*!< Readers 'wait for data' event */
+       PTL_STREAM                      psStream;                       /*!< TL Stream object */
+       IMG_INT                         uiWRefCount;            /*!< Stream writer reference count */
+       PTL_STREAM_DESC         psRDesc;                        /*!< Stream reader 0 or ptr only */
+} TL_SNODE;
+
+PTL_SNODE TLMakeSNode(IMG_HANDLE f2, TL_STREAM *f3, TL_STREAM_DESC *f4);
+
+/*
+ * Transport Layer global top types and variables
+ * Use access function to obtain pointer.
+ *
+ * hTLGDLock - provides atomicity over read/check/write operations and
+ *             sequence of operations on uiClientCnt, psHead list of SNODEs and
+ *             the immediate members in a list element SNODE structure.
+ *           - This larger scope of responsibility for this lock helps avoid
+ *             the need for a lock in the SNODE structure.
+ *           - Lock held in the client (reader) context when streams are
+ *             opened/closed and in the server (writer) context when streams
+ *             are created/open/closed.
+ */
+typedef struct _TL_GDATA_
+{
+       IMG_PVOID  psRgxDevNode;        /* Device node to use for buffer allocations */
+       IMG_HANDLE hTLEventObj;         /* Global TL signal object, new streams, etc */
+
+       IMG_UINT   uiClientCnt;         /* Counter to track the number of client stream connections. */
+       PTL_SNODE  psHead;              /* List of TL streams and associated client handle */
+
+       POS_LOCK        hTLGDLock;          /* Lock for structure AND psHead SNODE list */
+} TL_GLOBAL_DATA, *PTL_GLOBAL_DATA;
+
+/*
+ * Transport Layer Internal Kernel-Mode Server API
+ */
+TL_GLOBAL_DATA* TLGGD(IMG_VOID);               /* TLGetGlobalData() */
+
+PVRSRV_ERROR TLInit(PVRSRV_DEVICE_NODE *psDevNode);
+IMG_VOID TLDeInit(IMG_VOID);
+
+PVRSRV_DEVICE_NODE* TLGetGlobalRgxDevice(IMG_VOID);
+
+IMG_VOID  TLAddStreamNode(PTL_SNODE psAdd);
+PTL_SNODE TLFindStreamNodeByName(IMG_PCHAR pszName);
+PTL_SNODE TLFindStreamNodeByDesc(PTL_STREAM_DESC psDesc);
+
+/****************************************************************************************
+ Function Name : TLTryRemoveStreamAndFreeStreamNode
+ Inputs                : PTL_SNODE     Pointer to the TL_SNODE whose stream is requested
+                       to be removed from TL_GLOBAL_DATA's list
+ Return Value  : IMG_TRUE      -       If the stream was made NULL and this
+                                       TL_SNODE was removed from the
+                                       TL_GLOBAL_DATA's list
+
+                 IMG_FALSE     -       If the stream wasn't made NULL as there
+                                       is a client connected to this stream
+
+ Description   : If there is no client currently connected to this stream then,
+                       This function removes this TL_SNODE from the
+                       TL_GLOBAL_DATA's list. The caller is responsible for the
+                       cleanup of the TL_STREAM whose TL_SNODE may be removed
+                 
+                 Otherwise, this function does nothing
+*****************************************************************************************/
+IMG_BOOL  TLTryRemoveStreamAndFreeStreamNode(PTL_SNODE psRemove);
+
+/*****************************************************************************************
+ Function Name : TLRemoveDescAndTryFreeStreamNode
+ Inputs                : PTL_SNODE     Pointer to the TL_SNODE whose descriptor is
+                       requested to be removed 
+ Return Value  : IMG_TRUE      -       If this TL_SNODE was removed from the
+                                       TL_GLOBAL_DATA's list
+
+                 IMG_FALSE     -       Otherwise
+
+ Description   : This function removes the stream descriptor from this TL_SNODE
+                 and,
+                 If there is no writer (producer context) currently bound to this stream,
+                       This function removes this TL_SNODE from the
+                       TL_GLOBAL_DATA's list. The caller is responsible for the
+                       cleanup of the TL_STREAM whose TL_SNODE may be removed
+******************************************************************************************/
+IMG_BOOL  TLRemoveDescAndTryFreeStreamNode(PTL_SNODE psRemove);
+
+/*
+ * Transport Layer stream interface to server part declared here to avoid
+ * circular dependency.
+ */
+IMG_UINT32 TLStreamAcquireReadPos(PTL_STREAM psStream, IMG_UINT32* puiReadOffset);
+IMG_VOID TLStreamAdvanceReadPos(PTL_STREAM psStream, IMG_UINT32 uiReadLen);
+
+DEVMEM_EXPORTCOOKIE* TLStreamGetBufferCookie(PTL_STREAM psStream);
+IMG_BOOL TLStreamEOS(PTL_STREAM psStream);
+
+/****************************************************************************************
+ Function Name : TLStreamDestroy
+  
+ Inputs                : PTL_STREAM    Pointer to the TL_STREAM to be destroyed
+ Description   : This function performs all the clean-up operations required for
+                       destruction of this stream
+*****************************************************************************************/
+IMG_VOID TLStreamDestroy (PTL_STREAM);
+
+/*
+ * Test related functions
+ */
+PVRSRV_ERROR TUtilsInit (IMG_VOID);
+PVRSRV_ERROR TUtilsDeinit (IMG_VOID);
+
+
+#endif /* __TLINTERN_H__ */
+/******************************************************************************
+ End of file (tlintern.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/server/include/tlserver.h b/drivers/gpu/rogue_m/services/server/include/tlserver.h
new file mode 100644 (file)
index 0000000..4dda604
--- /dev/null
@@ -0,0 +1,83 @@
+/*************************************************************************/ /*!
+@File
+@Title          KM server Transport Layer implementation
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Main bridge APIs for Transport Layer client functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __TLSERVER_H_
+#define __TLSERVER_H_
+
+#include <stddef.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+
+#include "tlintern.h"
+
+/*
+ * Transport Layer Client API Kernel-Mode bridge implementation
+ */
+
+PVRSRV_ERROR TLServerConnectKM(CONNECTION_DATA *psConnection);
+PVRSRV_ERROR TLServerDisconnectKM(CONNECTION_DATA *psConnection);
+
+PVRSRV_ERROR TLServerOpenStreamKM(IMG_PCHAR pszName,
+                          IMG_UINT32 ui32Mode,
+                          PTL_STREAM_DESC* ppsSD,
+                          DEVMEM_EXPORTCOOKIE** ppsBufCookie);
+
+PVRSRV_ERROR TLServerCloseStreamKM(PTL_STREAM_DESC psSD);
+
+PVRSRV_ERROR TLServerAcquireDataKM(PTL_STREAM_DESC psSD,
+                          IMG_UINT32* puiReadOffset,
+                          IMG_UINT32* puiReadLen);
+
+PVRSRV_ERROR TLServerReleaseDataKM(PTL_STREAM_DESC psSD,
+                                IMG_UINT32 uiReadOffset,
+                                IMG_UINT32 uiReadLen);
+
+
+#endif /* __TLSERVER_H_ */
+
+/*****************************************************************************
+ End of file (tlserver.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/server/include/tlstream.h b/drivers/gpu/rogue_m/services/server/include/tlstream.h
new file mode 100644 (file)
index 0000000..dbca4a9
--- /dev/null
@@ -0,0 +1,331 @@
+/*************************************************************************/ /*!
+@File
+@Title          Transport Layer kernel side API.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    TL provides driver components with a way to copy data from kernel
+                space to user space (e.g. screen/file).
+
+                Data can be passed to the Transport Layer through the 
+                TL Stream (kernel space) API interface.
+
+                The buffer provided to every stream is a modified version of a 
+                circular buffer. Which CB version is created is specified by
+                relevant flags when creating a stream. Currently two types
+                of buffer are available:
+                - TL_FLAG_DROP_DATA:
+                  When the buffer is full, incoming data are dropped 
+                  (instead of overwriting older data) and a marker is set 
+                  to let the user know that data have been lost.
+                - TL_FLAG_BLOCKING_RESERVE:
+                  When the circular buffer is full, reserve/write calls block
+                  until enough space is freed.
+
+                All size/space requests are in bytes. However, the actual
+                implementation uses native word sizes (i.e. 4 byte aligned).
+
+                The user does not need to provide space for the stream buffer 
+                as the TL handles memory allocations and usage.
+
+                Inserting data to a stream's buffer can be done either:
+                - by using TLReserve/TLCommit: User is provided with a buffer
+                                                 to write data to.
+                - or by using TLWrite:         User provides a buffer with 
+                                                 data to be committed. The TL 
+                                                 copies the data from the 
+                                                 buffer into the stream buffer 
+                                                 and returns.
+                Users should be aware that there are implementation overheads 
+                associated with every stream buffer. If you find that less 
+                data are captured than expected then try increasing the
+                stream buffer size or use TLInfo to obtain buffer parameters
+                and calculate optimum required values at run time.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __TLSTREAM_H__
+#define __TLSTREAM_H__
+
+
+#include "img_types.h"
+
+/*! Flags specifying stream and circular buffer behaviour */
+/*! Discard new data if the buffer is full */
+#define TL_FLAG_DROP_DATA              (1U<<0)
+/*! Block Reserve (subsequently Write) calls if there is not enough space 
+ *    until some space is freed. */
+#define TL_FLAG_BLOCKING_RESERVE           (1U<<1)
+/*! Do not destroy stream if there still are data that have not been 
+ *     copied in user space. BLock until the stream is emptied. */
+#define TL_FLAG_FORCE_FLUSH            (1U<<2)
+/*! Do not signal consumers on commit automatically when the stream buffer
+ * transitions from empty to non-empty. Producer responsible for signal when
+ * it chooses. */
+#define TL_FLAG_NO_SIGNAL_ON_COMMIT    (1U<<3)
+
+/*! Structure used to pass internal TL stream sizes information to users.*/
+typedef struct _TL_STREAM_INFO_
+{
+    IMG_UINT32 headerSize;          /*!< Packet header size in bytes */
+    IMG_UINT32 minReservationSize;  /*!< Minimum data size reserved in bytes */
+    IMG_UINT32 pageSize;            /*!< Page size in bytes */
+    IMG_UINT32 pageAlign;           /*!< Page alignment in bytes */
+} TL_STREAM_INFO, *PTL_STREAM_INFO;
+
+/*! Callback operations or notifications that a stream producer may handle
+ * when requested by the Transport Layer.
+ */
+#define TL_SOURCECB_OP_CLIENT_EOS 0x01  /*!< Client has reached end of stream,
+                                         * can anymore data be supplied?
+                                         * ui32Resp ignored in this operation */
+
+/*! Function pointer type for the callback handler into the "producer" code
+ * that writes data to the TL stream.  Producer should handle the notification
+ * or operation supplied in ui32ReqOp on stream hStream. The
+ * Operations and notifications are defined above in TL_SOURCECB_OP */
+typedef PVRSRV_ERROR (*TL_STREAM_SOURCECB)(IMG_HANDLE hStream,
+               IMG_UINT32 ui32ReqOp, IMG_UINT32* ui32Resp, IMG_VOID* pvUser);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamCreate
+ @Description   Request the creation of a new stream and open a handle.
+                               If creating a stream which should continue to exist after the
+                               current context is finished, then TLStreamCreate must be 
+                               followed by a TLStreamOpen call. On any case, the number of 
+                               create/open calls must balance with the number of close calls
+                               used. This ensures the resources of a stream are released when
+                               it is no longer required.
+ @Output        phStream        Pointer to handle to store the new stream.
+ @Input         szStreamName    Name of stream, maximum length:
+                                  PRVSRVTL_MAX_STREAM_NAME_SIZE.
+                                  If a longer string is provided,creation fails.
+ @Input         ui32Size        Desired buffer size in bytes.
+ @Input         ui32StreamFlags Flags that configure buffer behaviour.See above.
+ @Input         pfProducerDB    Optional callback, may be null.
+ @Input         pvProducerData  Optional user data for callback, may be null.
+ @Return        PVRSRV_ERROR_INVALID_PARAMS  NULL stream handle or string name 
+                                               exceeded MAX_STREAM_NAME_SIZE
+ @Return        PVRSRV_ERROR_OUT_OF_MEMORY   Failed to allocate space for stream
+                                               handle.
+ @Return        PVRSRV_ERROR_DUPLICATE_VALUE There already exists a stream with
+                                                                                          the same stream name string.
+ @Return        eError                       Internal services call returned
+                                               eError error number.
+ @Return        PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR 
+TLStreamCreate(IMG_HANDLE *phStream,
+               IMG_CHAR          *szStreamName,
+               IMG_UINT32 ui32Size,
+               IMG_UINT32 ui32StreamFlags,
+               TL_STREAM_SOURCECB pfProducerCB,
+               IMG_PVOID pvProducerUD);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamOpen
+ @Description   Attach to existing stream that has already been created by a
+                  TLStreamCreate call. A handle is returned to the stream.
+ @Output        phStream        Pointer to handle to store the stream.
+ @Input         szStreamName    Name of stream, should match an already
+                                  existing stream name
+ @Return        PVRSRV_ERROR_NOT_FOUND        None of the streams matched the
+                                                 requested stream name.
+                               PVRSRV_ERROR_INVALID_PARAMS        non NULL pointer to stream 
+                                                                                            handler is required.
+ @Return        PVRSRV_OK                      Success.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+TLStreamOpen(IMG_HANDLE *phStream,
+             IMG_CHAR   *szStreamName);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamClose
+ @Description   Detach from the stream associated with the given handle. If
+                  the current handle is the last one accessing the stream 
+                                 (i.e. the number of TLStreamCreate+TLStreamOpen calls matches
+                                 the number of TLStreamClose calls) then the stream is also
+                                 deleted.
+                               On return the handle is no longer valid.
+ @Input         hStream     Handle to stream that will be closed.
+ @Return        None.
+*/ /**************************************************************************/
+IMG_VOID
+TLStreamClose(IMG_HANDLE hStream);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamReserve
+ @Description   Reserve space in stream buffer. When successful every
+                  TLStreamReserve call must be followed by a matching
+                  TLStreamCommit call. While a TLStreamCommit call is pending
+                  for a stream, subsequent TLStreamReserve calls for this
+                  stream will fail.
+ @Input         hStream         Stream handle.
+ @Output        ppui8Data       Pointer to a pointer to a location in the 
+                                  buffer. The caller can then use this address
+                                  in writing data into the stream. 
+ @Input         ui32Size        Number of bytes to reserve in buffer.
+ @Return        PVRSRV_INVALID_PARAMS       NULL stream handler.
+ @Return        PVRSRV_ERROR_NOT_READY      There are data previously reserved
+                                              that are pending to be committed.
+ @Return        PVRSRV_ERROR_STREAM_MISUSE  Misusing the stream by trying to 
+                                              reserve more space than the 
+                                              buffer size.
+                PVRSRV_ERROR_STREAM_FULL    Stream buffer full, data not written
+ @Return        PVRSRV_OK                   Success, output arguments valid.
+*/ /**************************************************************************/
+PVRSRV_ERROR 
+TLStreamReserve(IMG_HANDLE hStream, 
+                IMG_UINT8  **ppui8Data,
+                IMG_UINT32 ui32Size);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamReserve2
+ @Description   Reserve space in stream buffer. When successful every
+                  TLStreamReserve call must be followed by a matching
+                  TLStreamCommit call. While a TLStreamCommit call is pending
+                  for a stream, subsequent TLStreamReserve calls for this
+                  stream will fail.
+ @Input         hStream         Stream handle.
+ @Output        ppui8Data       Pointer to a pointer to a location in the
+                                  buffer. The caller can then use this address
+                                  in writing data into the stream.
+ @Input         ui32Size        Ideal number of bytes to reserve in buffer.
+ @Input         ui32SizeMin     Minimum number of bytes to reserve in buffer.
+ @Input         pui32Available  Optional, but when present and the FULL error
+                                  is returned, a size suggestion is returned
+                                                                 in this argument which the caller can attempt
+                                  to reserve again for a successful allocation.
+ @Return        PVRSRV_INVALID_PARAMS       NULL stream handler.
+ @Return        PVRSRV_ERROR_NOT_READY      There are data previously reserved
+                                              that are pending to be committed.
+ @Return        PVRSRV_ERROR_STREAM_MISUSE  Misusing the stream by trying to
+                                              reserve more space than the
+                                              buffer size.
+                PVRSRV_ERROR_STREAM_FULL    Stream buffer full, data not written
+ @Return        PVRSRV_OK                   Success, output arguments valid.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+TLStreamReserve2(IMG_HANDLE hStream,
+                IMG_UINT8  **ppui8Data,
+                IMG_UINT32 ui32Size,
+                IMG_UINT32 ui32SizeMin,
+                IMG_UINT32* pui32Available);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamCommit
+ @Description   Notify TL that data have been written in the stream buffer.
+                  Should always follow and match TLStreamReserve call.
+ @Input         hStream         Stream handle.
+ @Input         ui32Size        Number of bytes that have been added to the
+                                  stream.
+ @Return        PVRSRV_ERROR_INVALID_PARAMS  NULL stream handle.
+ @Return        PVRSRV_ERROR_STREAM_MISUSE   Commit results in more data 
+                                               committed than the buffer size,
+                                               the stream is misused.
+ @Return        eError                       Commit was successful but 
+                                               internal services call returned
+                                               eError error number.
+ @Return        PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR 
+TLStreamCommit(IMG_HANDLE hStream,
+               IMG_UINT32 ui32Size);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamWrite
+ @Description   Combined Reserve/Commit call. This function Reserves space in 
+                  the specified stream buffer, copies ui32Size bytes of data
+                  from the array pui8Src points to and Commits in an "atomic"
+                  style operation.
+ @Input         hStream         Stream handle.
+ @Input         pui8Src         Source to read data from.
+ @Input         ui32Size        Number of bytes to copy and commit.
+ @Return        PVRSRV_ERROR_INVALID_PARAMS  NULL stream handler.
+ @Return        eError                       Error codes returned by either 
+                                               Reserve or Commit.
+ @Return        PVRSRV_OK
+ */ /**************************************************************************/
+PVRSRV_ERROR 
+TLStreamWrite(IMG_HANDLE hStream, 
+              IMG_UINT8  *pui8Src,
+              IMG_UINT32 ui32Size);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamSync
+ @Description   Signal the consumer to start acquiring data from the stream
+                buffer. Called by producers that use the TL_FLAG_NO_SIGNAL_ON_COMMIT
+                flag to manually control when consumers starting reading the
+                stream. Used when multiple small writes need to be batched.
+ @Input         hStream         Stream handle.
+ @Return        PVRSRV_ERROR_INVALID_PARAMS  NULL stream handle.
+ @Return        eError                       Error codes returned by either
+                                               Reserve or Commit.
+ @Return        PVRSRV_OK
+ */ /**************************************************************************/
+PVRSRV_ERROR
+TLStreamSync(IMG_HANDLE hStream);
+
+
+/*************************************************************************/ /*!
+ @Function      TLStreamMarkEOS
+ @Description   Insert a EOS marker packet in the given stream.
+ @Input         hStream         Stream handle.
+ @Return        PVRSRV_ERROR_INVALID_PARAMS    NULL stream handler.
+ @Return        eError                         Error codes returned by either
+                                              Reserve or Commit.
+ @Return        PVRSRV_OK                              Success.
+*/ /**************************************************************************/
+PVRSRV_ERROR 
+TLStreamMarkEOS(IMG_HANDLE hStream);
+
+/*************************************************************************/ /*!
+ @Function      TLStreamInfo
+ @Description   Run time information about buffer elemental sizes.
+                It sets psInfo members accordingly. Users can use those values
+                to calculate the parameters they use in TLStreamCreate and 
+                TLStreamReserve.
+ @Output        psInfo          pointer to stream info structure.
+ @Return        None.
+*/ /**************************************************************************/
+IMG_VOID 
+TLStreamInfo(PTL_STREAM_INFO psInfo);
+
+
+#endif /* __TLSTREAM_H__ */
+/*****************************************************************************
+ End of file (tlstream.h)
+*****************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/devicemem.c b/drivers/gpu/rogue_m/services/shared/common/devicemem.c
new file mode 100644 (file)
index 0000000..5f1c376
--- /dev/null
@@ -0,0 +1,2054 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Front End (nominally Client side part, but now invokable
+                from server too) of device memory management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "devicemem.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "allocmem.h"
+#include "ra.h"
+#include "osfunc.h"
+#include "devicemem_mmap.h"
+#include "devicemem_utils.h"
+#include "client_mm_bridge.h"
+#if defined(PDUMP)
+#include "devicemem_pdump.h"
+#endif
+#if defined(PVR_RI_DEBUG)
+#include "client_ri_bridge.h"
+#endif 
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#include "client_devicememhistory_bridge.h"
+#endif
+
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#if defined(LINUX)
+#include "linux/kernel.h"
+#endif
+#endif
+
+/** Page size.
+ *  Should be initialised to the correct value at driver init time.
+ *  Use macros from devicemem.h to access from outside this module.
+ */
+IMG_UINT32 g_uiLog2PageSize = 0;
+
+static PVRSRV_ERROR
+_Mapping_Export(DEVMEM_IMPORT *psImport,
+                DEVMEM_EXPORTHANDLE *phPMRExportHandlePtr,
+                DEVMEM_EXPORTKEY *puiExportKeyPtr,
+                DEVMEM_SIZE_T *puiSize,
+                DEVMEM_LOG2ALIGN_T *puiLog2Contig)
+{
+    /* Gets an export handle and key for the PMR used for this mapping */
+    /* Can only be done if there are no suballocations for this mapping */
+
+    PVRSRV_ERROR eError;
+    DEVMEM_EXPORTHANDLE hPMRExportHandle;
+    DEVMEM_EXPORTKEY uiExportKey;
+    IMG_DEVMEM_SIZE_T uiSize;
+    IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig;
+
+    if (psImport == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto failParams;
+    }
+
+    if (!psImport->bExportable)
+    {
+               eError = PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION;
+        goto failParams;
+    }
+
+    eError = BridgePMRExportPMR(psImport->hBridge,
+                                psImport->hPMR,
+                                &hPMRExportHandle,
+                                &uiSize,
+                                &uiLog2Contig,
+                                &uiExportKey);
+    if (eError != PVRSRV_OK)
+    {
+        goto failExport;
+    }
+
+    PVR_ASSERT(uiSize == psImport->uiSize);
+
+    *phPMRExportHandlePtr = hPMRExportHandle;
+    *puiExportKeyPtr = uiExportKey;
+    *puiSize = uiSize;
+    *puiLog2Contig = uiLog2Contig;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+failExport:
+failParams:
+
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+
+}
+
+static IMG_VOID
+_Mapping_Unexport(DEVMEM_IMPORT *psImport,
+                  DEVMEM_EXPORTHANDLE hPMRExportHandle)
+{
+    PVRSRV_ERROR eError;
+
+    PVR_ASSERT (psImport != IMG_NULL);
+
+    eError = BridgePMRUnexportPMR(psImport->hBridge,
+                                  hPMRExportHandle);
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+/*****************************************************************************
+ *                    Sub allocation internals                               *
+ *****************************************************************************/
+
+static PVRSRV_ERROR
+_AllocateDeviceMemory(IMG_HANDLE hBridge,
+                                         IMG_HANDLE hDeviceNode,
+                                         IMG_UINT32 uiLog2Quantum,
+                                         IMG_DEVMEM_SIZE_T uiSize,
+                                         IMG_DEVMEM_SIZE_T uiChunkSize,
+                                         IMG_UINT32 ui32NumPhysChunks,
+                                         IMG_UINT32 ui32NumVirtChunks,
+                                         IMG_BOOL *pabMappingTable,
+                                         IMG_DEVMEM_ALIGN_T uiAlign,
+                                         DEVMEM_FLAGS_T uiFlags,
+                                         IMG_BOOL bExportable,
+                                         DEVMEM_IMPORT **ppsImport)
+{
+       DEVMEM_IMPORT *psImport;
+       DEVMEM_FLAGS_T uiPMRFlags;
+       IMG_HANDLE hPMR;
+       PVRSRV_ERROR eError;
+
+       eError = _DevmemImportStructAlloc(hBridge,
+                                                                         bExportable,
+                                                                         &psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failAlloc;
+       }
+
+    /* Check the size is a multiple of the quantum */
+    PVR_ASSERT((uiSize & ((1ULL<<uiLog2Quantum)-1)) == 0);
+
+       /* Pass only the PMR flags down */
+       uiPMRFlags = uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK;
+
+    eError = BridgePhysmemNewRamBackedPMR(hBridge,
+                                          hDeviceNode,
+                                          uiSize,
+                                          uiChunkSize,
+                                          ui32NumPhysChunks,
+                                          ui32NumVirtChunks,
+                                          pabMappingTable,
+                                          uiLog2Quantum,
+                                          uiPMRFlags,
+                                          &hPMR);
+    if (eError != PVRSRV_OK)
+    {
+        /* Our check above should have ensured this the "not page
+           multiple" error never happens */
+        PVR_ASSERT(eError != PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE);
+
+        goto failPMR;
+    }
+
+       _DevmemImportStructInit(psImport,
+                                                       uiSize,
+                                                       uiAlign,
+                                                       uiFlags,
+                                                       hPMR);
+
+       *ppsImport = psImport;
+       return PVRSRV_OK;
+
+failPMR:
+       _DevmemImportDiscard(psImport);
+failAlloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+static IMG_VOID
+_FreeDeviceMemory(DEVMEM_IMPORT *psImport)
+{
+       _DevmemImportStructRelease(psImport);
+}
+
+static IMG_BOOL
+_SubAllocImportAlloc(RA_PERARENA_HANDLE hArena,
+                     RA_LENGTH_T uiSize,
+                     RA_FLAGS_T _flags,
+                     /* returned data */
+                     RA_BASE_T *puiBase,
+                     RA_LENGTH_T *puiActualSize,
+                     RA_PERISPAN_HANDLE *phImport)
+{
+    /* When suballocations need a new lump of memory, the RA calls
+       back here.  Later, in the kernel, we must construct a new PMR
+       and a pairing between the new lump of virtual memory and the
+       PMR (whether or not such PMR is backed by physical memory) */
+    DEVMEM_HEAP *psHeap;
+    DEVMEM_IMPORT *psImport;
+    IMG_DEVMEM_ALIGN_T uiAlign;
+    DEVMEM_FLAGS_T uiFlags;
+    PVRSRV_ERROR eError;
+    IMG_BOOL bMappingTable = IMG_TRUE;
+
+    uiFlags = (DEVMEM_FLAGS_T) _flags;
+
+    /* Per-arena private handle is, for us, the heap */
+    psHeap = hArena;
+
+    /* align to the l.s.b. of the size...  e.g. 96kiB aligned to
+       32kiB. NB: There is an argument to say that the RA should never
+       ask us for Non-power-of-2 size anyway, but I don't want to make
+       that restriction arbitrarily now */
+    uiAlign = uiSize & ~(uiSize-1);
+
+    /* The RA should not have invoked us with a size that is not a
+       multiple of the quantum anyway */
+    PVR_ASSERT((uiSize & ((1ULL<<psHeap->uiLog2Quantum)-1)) == 0);
+
+       eError = _AllocateDeviceMemory(psHeap->psCtx->hBridge,
+                                                                  psHeap->psCtx->hDeviceNode,
+                                                                  psHeap->uiLog2Quantum,
+                                                                  uiSize,
+                                                                  uiSize,
+                                                                  1,
+                                                                  1,
+                                                                  &bMappingTable,
+                                                                  uiAlign,
+                                                                  uiFlags,
+                                                                  IMG_FALSE,
+                                                                  &psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failAlloc;
+       }
+
+#if defined(PVR_RI_DEBUG)
+       {
+               eError = BridgeRIWritePMREntry (psImport->hBridge,
+                                                                               psImport->hPMR,
+                                                                               sizeof("PMR sub-allocated"),
+                                                                               "PMR sub-allocated",
+                                                                               psImport->uiSize);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#endif
+       /*
+               Suballocations always get mapped into the device was we need to
+               key the RA off something and as we can't export suballocations
+               there is no valid reason to request an allocation an not map it
+       */
+       eError = _DevmemImportStructDevMap(psHeap,
+                                                                          IMG_TRUE,
+                                                                          psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failMap;
+       }
+
+       *puiBase = psImport->sDeviceImport.sDevVAddr.uiAddr;
+       *puiActualSize = uiSize;
+       *phImport = psImport;
+
+    return IMG_TRUE;
+
+    /*
+      error exit paths follow
+    */
+failMap:
+    _FreeDeviceMemory(psImport);
+failAlloc:
+
+    return IMG_FALSE;
+}
+
+static IMG_VOID
+_SubAllocImportFree(RA_PERARENA_HANDLE hArena,
+                    RA_BASE_T uiBase,
+                    RA_PERISPAN_HANDLE hImport)
+{
+    DEVMEM_IMPORT *psImport = hImport;
+
+    PVR_ASSERT(psImport != IMG_NULL);
+    PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap);
+    PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr);
+
+    _DevmemImportStructDevUnmap(psImport);  
+       _DevmemImportStructRelease(psImport);
+}
+
+/*****************************************************************************
+ *                    Devmem context internals                               *
+ *****************************************************************************/
+
+static PVRSRV_ERROR
+_PopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx,
+                              IMG_HANDLE hDeviceNode,
+                              DEVMEM_HEAPCFGID uiHeapBlueprintID)
+{
+    PVRSRV_ERROR eError;
+    PVRSRV_ERROR eError2;
+    struct _DEVMEM_HEAP_ **ppsHeapArray;
+    IMG_UINT32 uiNumHeaps;
+    IMG_UINT32 uiHeapsToUnwindOnError;
+    IMG_UINT32 uiHeapIndex;
+    IMG_DEV_VIRTADDR sDevVAddrBase;
+    IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH];
+    IMG_DEVMEM_SIZE_T uiHeapLength;
+    IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize;
+    IMG_DEVMEM_LOG2ALIGN_T uiLog2ImportAlignment;
+
+    eError = DevmemHeapCount(psCtx->hBridge,
+                             hDeviceNode,
+                             uiHeapBlueprintID,
+                             &uiNumHeaps);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    if (uiNumHeaps == 0)
+    {
+        ppsHeapArray = IMG_NULL;
+    }
+    else
+    {
+        ppsHeapArray = OSAllocMem(sizeof(*ppsHeapArray) * uiNumHeaps);
+        if (ppsHeapArray == IMG_NULL)
+        {
+            eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+            goto e0;
+        }
+    }
+
+    uiHeapsToUnwindOnError = 0;
+
+    for (uiHeapIndex = 0; uiHeapIndex < uiNumHeaps; uiHeapIndex++)
+    {
+        eError = DevmemHeapDetails(psCtx->hBridge,
+                                   hDeviceNode,
+                                   uiHeapBlueprintID,
+                                   uiHeapIndex,
+                                   &aszHeapName[0],
+                                   sizeof(aszHeapName),
+                                   &sDevVAddrBase,
+                                   &uiHeapLength,
+                                   &uiLog2DataPageSize,
+                                   &uiLog2ImportAlignment);
+        if (eError != PVRSRV_OK)
+        {
+            goto e1;
+        }
+
+        eError = DevmemCreateHeap(psCtx,
+                                  sDevVAddrBase,
+                                  uiHeapLength,
+                                  uiLog2DataPageSize,
+                                  uiLog2ImportAlignment,
+                                  aszHeapName,
+                                  uiHeapBlueprintID,
+                                  &ppsHeapArray[uiHeapIndex]);
+        if (eError != PVRSRV_OK)
+        {
+            goto e1;
+        }
+
+        uiHeapsToUnwindOnError = uiHeapIndex + 1;
+    }
+
+    psCtx->uiAutoHeapCount = uiNumHeaps;
+    psCtx->ppsAutoHeapArray = ppsHeapArray;
+
+    PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
+    PVR_ASSERT(psCtx->uiAutoHeapCount == uiNumHeaps);
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths
+    */
+ e1:
+    for (uiHeapIndex = 0; uiHeapIndex < uiHeapsToUnwindOnError; uiHeapIndex++)
+    {
+        eError2 = DevmemDestroyHeap(ppsHeapArray[uiHeapIndex]);
+        PVR_ASSERT(eError2 == PVRSRV_OK);
+    }
+
+    if (uiNumHeaps != 0)
+    {
+        OSFreeMem(ppsHeapArray);
+    }
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+static IMG_VOID
+_UnpopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx)
+{
+    PVRSRV_ERROR eError2;
+    IMG_UINT32 uiHeapIndex;
+    IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__)
+    PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+    if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+    {
+       bDoCheck = IMG_FALSE;
+    }
+#endif
+
+    PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
+
+    for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++)
+    {
+        eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]);
+        if (bDoCheck)
+        {
+               PVR_ASSERT(eError2 == PVRSRV_OK);
+        }
+    }
+
+    if (psCtx->uiAutoHeapCount != 0)
+    {
+        OSFreeMem(psCtx->ppsAutoHeapArray);
+        psCtx->ppsAutoHeapArray = IMG_NULL;
+    }
+    psCtx->uiAutoHeapCount = 0;
+
+    PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
+    PVR_ASSERT(psCtx->ppsAutoHeapArray == IMG_NULL);
+}
+
+
+/*****************************************************************************
+ *                    Devmem context functions                               *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemCreateContext(DEVMEM_BRIDGE_HANDLE hBridge,
+                    IMG_HANDLE hDeviceNode,
+                    DEVMEM_HEAPCFGID uiHeapBlueprintID,
+                    DEVMEM_CONTEXT **ppsCtxPtr)
+{
+    PVRSRV_ERROR eError;
+    DEVMEM_CONTEXT *psCtx;
+    /* handle to the server-side counterpart of the device memory
+       context (specifically, for handling mapping to device MMU) */
+    IMG_HANDLE hDevMemServerContext;
+    IMG_HANDLE hPrivData;
+
+
+    if (ppsCtxPtr == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e0;
+    }
+
+    psCtx = OSAllocMem(sizeof *psCtx);
+    if (psCtx == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto e0;
+    }
+
+    psCtx->uiNumHeaps = 0;
+
+    psCtx->hBridge = hBridge;
+
+    /* Create (server-side) Device Memory context */
+    eError = BridgeDevmemIntCtxCreate(psCtx->hBridge,
+                                   hDeviceNode,
+                                   &hDevMemServerContext,
+                                   &hPrivData);
+    if (eError != PVRSRV_OK)
+    {
+        goto e1;
+    }
+
+    psCtx->hDeviceNode = hDeviceNode;
+    psCtx->hDevMemServerContext = hDevMemServerContext;
+    psCtx->hPrivData = hPrivData;
+
+    /* automagic heap creation */
+    psCtx->uiAutoHeapCount = 0;
+
+    eError = _PopulateContextFromBlueprint(psCtx, hDeviceNode, uiHeapBlueprintID);
+    if (eError != PVRSRV_OK)
+    {
+        goto e2;
+    }
+
+
+    *ppsCtxPtr = psCtx;
+
+
+    PVR_ASSERT(psCtx->uiNumHeaps == psCtx->uiAutoHeapCount);
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e2:
+    PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
+    PVR_ASSERT(psCtx->uiNumHeaps == 0);
+    BridgeDevmemIntCtxDestroy(psCtx->hBridge, hDevMemServerContext);
+
+ e1:
+    OSFreeMem(psCtx);
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx,
+                         IMG_HANDLE *hPrivData)
+{
+       PVRSRV_ERROR eError;
+
+       if ((psCtx == IMG_NULL) || (hPrivData == IMG_NULL))
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       *hPrivData = psCtx->hPrivData;
+       return PVRSRV_OK;
+
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx)
+{
+       PVRSRV_ERROR eError;
+
+       if (psCtx == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+       return PVRSRV_OK;
+
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemFindHeapByName(const struct _DEVMEM_CONTEXT_ *psCtx,
+                     const IMG_CHAR *pszHeapName,
+                     struct _DEVMEM_HEAP_ **ppsHeapRet)
+{
+    IMG_UINT32 uiHeapIndex;
+
+    /* N.B.  This func is only useful for finding "automagic" heaps by name */
+    for (uiHeapIndex = 0;
+         uiHeapIndex < psCtx->uiAutoHeapCount;
+         uiHeapIndex++)
+    {
+        if (!OSStringCompare(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName, pszHeapName))
+        {
+            *ppsHeapRet = psCtx->ppsAutoHeapArray[uiHeapIndex];
+            return PVRSRV_OK;
+        }
+    }
+
+    return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemDestroyContext(DEVMEM_CONTEXT *psCtx)
+{
+    PVRSRV_ERROR eError;
+    IMG_BOOL bDoCheck = IMG_TRUE;
+
+#if defined(__KERNEL__)
+    PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+    if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+    {
+       bDoCheck = IMG_FALSE;
+    }
+#endif
+
+    if (psCtx == IMG_NULL)
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    /* should be only the automagically instantiated heaps left */
+    if (psCtx->uiNumHeaps != psCtx->uiAutoHeapCount)
+    {
+        return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
+    }
+
+    _UnpopulateContextFromBlueprint(psCtx);
+
+    if (bDoCheck)
+    {
+               PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
+               PVR_ASSERT(psCtx->uiNumHeaps == 0);
+    }
+    eError = BridgeDevmemIntCtxDestroy(psCtx->hBridge,
+                                      psCtx->hDevMemServerContext);
+    if (bDoCheck)
+    {
+       PVR_ASSERT (eError == PVRSRV_OK);
+    }
+
+    OSFreeMem(psCtx);
+
+    return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ *                 Devmem heap query functions                               *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapConfigCount(DEVMEM_BRIDGE_HANDLE hBridge,
+                      IMG_HANDLE hDeviceNode,
+                      IMG_UINT32 *puiNumHeapConfigsOut)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgeHeapCfgHeapConfigCount(hBridge,
+                                          hDeviceNode,
+                                          puiNumHeapConfigsOut);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapCount(DEVMEM_BRIDGE_HANDLE hBridge,
+                IMG_HANDLE hDeviceNode,
+                IMG_UINT32 uiHeapConfigIndex,
+                IMG_UINT32 *puiNumHeapsOut)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgeHeapCfgHeapCount(hBridge,
+                                    hDeviceNode,
+                                    uiHeapConfigIndex,
+                                    puiNumHeapsOut);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapConfigName(DEVMEM_BRIDGE_HANDLE hBridge,
+                     IMG_HANDLE hDeviceNode,
+                     IMG_UINT32 uiHeapConfigIndex,
+                     IMG_CHAR *pszConfigNameOut,
+                     IMG_UINT32 uiConfigNameBufSz)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgeHeapCfgHeapConfigName(hBridge,
+                                         hDeviceNode,
+                                         uiHeapConfigIndex,
+                                         uiConfigNameBufSz,
+                                         pszConfigNameOut);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapDetails(DEVMEM_BRIDGE_HANDLE hBridge,
+                  IMG_HANDLE hDeviceNode,
+                  IMG_UINT32 uiHeapConfigIndex,
+                  IMG_UINT32 uiHeapIndex,
+                  IMG_CHAR *pszHeapNameOut,
+                  IMG_UINT32 uiHeapNameBufSz,
+                  IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+                  IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+                  IMG_UINT32 *puiLog2DataPageSizeOut,
+                  IMG_UINT32 *puiLog2ImportAlignmentOut)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgeHeapCfgHeapDetails(hBridge,
+                                      hDeviceNode,
+                                      uiHeapConfigIndex,
+                                      uiHeapIndex,
+                                      uiHeapNameBufSz,
+                                      pszHeapNameOut,
+                                      psDevVAddrBaseOut,
+                                      puiHeapLengthOut,
+                                      puiLog2DataPageSizeOut,
+                                      puiLog2ImportAlignmentOut);
+
+    VG_MARK_INITIALIZED(pszHeapNameOut,uiHeapNameBufSz);
+
+    return eError;
+}
+
+/*****************************************************************************
+ *                    Devmem heap functions                                  *
+ *****************************************************************************/
+/* See devicemem.h for important notes regarding the arguments
+   to this function */
+IMG_INTERNAL PVRSRV_ERROR
+DevmemCreateHeap(DEVMEM_CONTEXT *psCtx,
+                 IMG_DEV_VIRTADDR sBaseAddress,
+                 IMG_DEVMEM_SIZE_T uiLength,
+                 IMG_UINT32 ui32Log2Quantum,
+                 IMG_UINT32 ui32Log2ImportAlignment,
+                 const IMG_CHAR *pszName,
+                 DEVMEM_HEAPCFGID uiHeapBlueprintID,
+                 DEVMEM_HEAP **ppsHeapPtr)
+{
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    PVRSRV_ERROR eError2;
+    DEVMEM_HEAP *psHeap;
+    /* handle to the server-side counterpart of the device memory
+       heap (specifically, for handling mapping to device MMU */
+    IMG_HANDLE hDevMemServerHeap;
+    IMG_BOOL bRANoSplit = IMG_FALSE;
+
+    IMG_CHAR aszBuf[100];
+    IMG_CHAR *pszStr;
+
+    if (ppsHeapPtr == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e0;
+    }
+
+    psHeap = OSAllocMem(sizeof *psHeap);
+    if (psHeap == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto e0;
+    }
+
+    /* Need to keep local copy of heap name, so caller may free
+       theirs */
+    pszStr = OSAllocMem(OSStringLength(pszName)+1);
+    if (pszStr == IMG_NULL)
+    {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto e1;
+    }
+    OSStringCopy(pszStr, pszName);
+    psHeap->pszName = pszStr;
+
+    psHeap->sBaseAddress = sBaseAddress;
+    OSAtomicWrite(&psHeap->hImportCount,0);
+
+    OSSNPrintf(aszBuf, sizeof(aszBuf),
+               "NDM heap '%s' (suballocs) ctx:%p",
+               pszName, psCtx);
+    pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
+    if (pszStr == IMG_NULL)
+    {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto e2;
+    }
+    OSStringCopy(pszStr, aszBuf);
+    psHeap->pszSubAllocRAName = pszStr;
+
+#if defined(PDUMP) && defined(ANDROID)
+    /* the META heap is shared globally so a single
+     * physical memory import may be used to satisfy
+     * allocations of different processes.
+     * This is problematic when PDumping because the
+     * physical memory import used to satisfy a new allocation
+     * may actually have been imported (and thus the PDump MALLOC
+     * generated) before the PDump client was started, leading to the
+     * MALLOC being missing.
+     * This is solved by disabling splitting of imports for the META physmem
+     * RA, meaning that every firmware allocation gets its own import, thus
+     * ensuring the MALLOC is present for every allocation made within the
+     * pdump capture range
+     */
+    if(uiHeapBlueprintID == DEVMEM_HEAPCFG_META)
+    {
+       bRANoSplit = IMG_TRUE;
+    }
+#else
+    PVR_UNREFERENCED_PARAMETER(uiHeapBlueprintID);
+#endif
+
+
+    psHeap->psSubAllocRA = RA_Create(psHeap->pszSubAllocRAName,
+                       /* Subsequent imports: */
+                       ui32Log2Quantum,
+                                          RA_LOCKCLASS_2,
+                       _SubAllocImportAlloc,
+                       _SubAllocImportFree,
+                       (RA_PERARENA_HANDLE) psHeap,
+                       bRANoSplit);
+    if (psHeap->psSubAllocRA == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+        goto e3;
+    }
+
+    psHeap->uiLog2ImportAlignment = ui32Log2ImportAlignment;
+    psHeap->uiLog2Quantum = ui32Log2Quantum;
+
+    OSSNPrintf(aszBuf, sizeof(aszBuf),
+               "NDM heap '%s' (QVM) ctx:%p",
+               pszName, psCtx);
+    pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
+    if (pszStr == IMG_NULL)
+    {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto e4;
+    }
+    OSStringCopy(pszStr, aszBuf);
+    psHeap->pszQuantizedVMRAName = pszStr;
+
+    psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName,
+                       /* Subsequent import: */
+                                       0, RA_LOCKCLASS_1, IMG_NULL, IMG_NULL,
+                       (RA_PERARENA_HANDLE) psHeap,
+                       IMG_FALSE);
+
+    if (psHeap->psQuantizedVMRA == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+        goto e5;
+    }
+
+       if (!RA_Add(psHeap->psQuantizedVMRA,
+                       (RA_BASE_T)sBaseAddress.uiAddr,
+                       (RA_LENGTH_T)uiLength,
+                       (RA_FLAGS_T)0, /* This RA doesn't use or need flags */
+                               IMG_NULL /* per ispan handle */))
+       {
+               RA_Delete(psHeap->psQuantizedVMRA);
+        eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+        goto e5;
+       }
+
+
+    psHeap->psCtx = psCtx;
+
+
+    /* Create server-side counterpart of Device Memory heap */
+    eError = BridgeDevmemIntHeapCreate(psCtx->hBridge,
+                                      psCtx->hDevMemServerContext,
+                                      sBaseAddress,
+                                      uiLength,
+                                      ui32Log2Quantum,
+                                      &hDevMemServerHeap);
+    if (eError != PVRSRV_OK)
+    {
+        goto e6;
+    }
+    psHeap->hDevMemServerHeap = hDevMemServerHeap;
+
+       eError = OSLockCreate(&psHeap->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto e7;
+       }
+
+    psHeap->psCtx->uiNumHeaps ++;
+    *ppsHeapPtr = psHeap;
+
+#if defined PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING
+    psHeap->psMemDescList = IMG_NULL;
+#endif  /* PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING */
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths
+    */
+ e7:
+    eError2 = BridgeDevmemIntHeapDestroy(psCtx->hBridge,
+                                       psHeap->hDevMemServerHeap);
+    PVR_ASSERT (eError2 == PVRSRV_OK);
+ e6:
+    RA_Delete(psHeap->psQuantizedVMRA);
+ e5:
+    OSFreeMem(psHeap->pszQuantizedVMRAName);
+ e4:
+    RA_Delete(psHeap->psSubAllocRA);
+ e3:
+    OSFreeMem(psHeap->pszSubAllocRAName);
+ e2:
+    OSFreeMem(psHeap->pszName);
+ e1:
+    OSFreeMem(psHeap);
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapBaseDevVAddr(struct _DEVMEM_HEAP_ *psHeap,
+                         IMG_DEV_VIRTADDR *pDevVAddr)
+{
+       if (psHeap == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *pDevVAddr = psHeap->sBaseAddress;
+
+       return PVRSRV_OK;
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemExportalignAdjustSizeAndAlign(DEVMEM_HEAP *psHeap, IMG_DEVMEM_SIZE_T *puiSize, IMG_DEVMEM_ALIGN_T *puiAlign)
+{
+       IMG_DEVMEM_SIZE_T uiSize = *puiSize;
+       IMG_DEVMEM_ALIGN_T uiAlign = *puiAlign;
+       IMG_UINT32 uiLog2Quantum;
+
+       if (psHeap)
+       {
+               uiLog2Quantum = psHeap->uiLog2Quantum;
+       }
+       else
+       {
+               uiLog2Quantum = GET_LOG2_PAGESIZE();
+       }
+
+    if ((1ULL << uiLog2Quantum) > uiAlign)
+    {
+               uiAlign = 1ULL << uiLog2Quantum;
+    }
+    uiSize = (uiSize + uiAlign - 1) & ~(uiAlign - 1);
+
+       *puiSize = uiSize;
+       *puiAlign = uiAlign;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemDestroyHeap(DEVMEM_HEAP *psHeap)
+{
+    PVRSRV_ERROR eError;
+       IMG_INT uiImportCount;
+
+    if (psHeap == IMG_NULL)
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+       uiImportCount = OSAtomicRead(&psHeap->hImportCount);
+    if (uiImportCount > 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", uiImportCount, psHeap->pszName));
+        return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
+    }
+
+       OSLockDestroy(psHeap->hLock);
+
+    PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0);
+    psHeap->psCtx->uiNumHeaps --;
+
+    eError = BridgeDevmemIntHeapDestroy(psHeap->psCtx->hBridge,
+                                       psHeap->hDevMemServerHeap);
+    PVR_ASSERT (eError == PVRSRV_OK);
+
+    RA_Delete(psHeap->psQuantizedVMRA);
+    OSFreeMem(psHeap->pszQuantizedVMRAName);
+
+    RA_Delete(psHeap->psSubAllocRA);
+    OSFreeMem(psHeap->pszSubAllocRAName);
+
+    OSFreeMem(psHeap->pszName);
+
+    OSFreeMem(psHeap);
+
+    return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ *                Devmem allocation/free functions                           *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAllocate(DEVMEM_HEAP *psHeap,
+               IMG_DEVMEM_SIZE_T uiSize,
+               IMG_DEVMEM_ALIGN_T uiAlign,
+               DEVMEM_FLAGS_T uiFlags,
+               const IMG_PCHAR pszText,
+                          DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+    IMG_BOOL bStatus; /* eError for RA */
+    RA_BASE_T uiAllocatedAddr;
+    RA_LENGTH_T uiAllocatedSize;
+    RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */
+    RA_FLAGS_T uiFlagsForRA;
+    PVRSRV_ERROR eError;
+    DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
+       IMG_DEVMEM_OFFSET_T uiOffset = 0;
+       DEVMEM_IMPORT *psImport;
+       IMG_VOID *pvAddr;
+
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+       {
+               /* Deferred Allocation not supported on SubAllocs*/
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto failParams;
+       }
+
+    if (psHeap == IMG_NULL || ppsMemDescPtr == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto failParams;
+    }
+
+       eError = _DevmemValidateParams(uiSize,
+                                                                  uiAlign,
+                                                                  uiFlags);
+       if (eError != PVRSRV_OK)
+       {
+               goto failParams;
+       }
+
+       eError =_DevmemMemDescAlloc(&psMemDesc);
+    if (eError != PVRSRV_OK)
+    {
+        goto failMemDescAlloc;
+    }
+
+    /*
+        If zero flag is set we have to have write access to the page.
+    */
+    uiFlags |= (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) ? PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE : 0;
+
+       /*
+               No request for exportable memory so use the RA
+       */
+    uiFlagsForRA = (RA_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK);
+    /* Check that the cast didn't lose any flags due to different integer widths */
+    PVR_ASSERT(uiFlagsForRA == (uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK));
+
+       /* 
+          When the RA suballocates memory from a Span it does not zero it. It only zeroes the
+          memory if it allocates a new Span; but we don't know what is going to happen for this
+          RA_Alloc call. Therefore, we zero the mem after the allocation below.
+       */
+       uiFlagsForRA &= ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
+       
+       bStatus = RA_Alloc(psHeap->psSubAllocRA,
+                                          uiSize,
+                                          uiFlagsForRA,
+                                          uiAlign,
+                                          &uiAllocatedAddr,
+                                          &uiAllocatedSize,
+                                          &hImport);
+       if (!bStatus)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto failDeviceMemAlloc;
+       }
+
+       psImport = hImport;
+       uiOffset = uiAllocatedAddr - psImport->sDeviceImport.sDevVAddr.uiAddr;
+
+       _DevmemMemDescInit(psMemDesc,
+                                          uiOffset,
+                                          psImport);
+
+       /* zero the memory */
+       if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+
+       {
+               eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
+               if (eError != PVRSRV_OK)
+               {
+                       goto failZero;
+               }
+
+               /* FIXME: uiSize is a 64-bit quantity whereas the 3rd argument
+                * to OSDeviceMemSet is a 32-bit quantity on 32-bit systems
+                * hence a compiler warning of implicit cast and loss of data.
+                * Added explicit cast and assert to remove warning.
+                */
+#if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
+               PVR_ASSERT(uiSize<IMG_UINT32_MAX);
+#endif
+
+               OSDeviceMemSet(pvAddr, 0x0, (IMG_SIZE_T) uiSize);
+           
+               DevmemReleaseCpuVirtAddr(psMemDesc);
+
+#if defined(PDUMP)
+               DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS);
+#endif
+       }
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+        * the allocation gets mapped/unmapped
+        */
+       OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+       psMemDesc->sTraceData.uiSize = uiSize;
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       {
+               /* Attach RI information */
+               eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
+                                                                                       psMemDesc->psImport->hPMR,
+                                                                                       OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+                                                                                       pszText,
+                                                                                       psMemDesc->uiOffset,
+                                                                                       uiAllocatedSize,
+                                                                                       IMG_FALSE,
+                                                                                       IMG_FALSE,
+                                                                                       &(psMemDesc->hRIHandle));
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#else  /* if defined(PVR_RI_DEBUG) */
+       PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVR_RI_DEBUG) */
+
+       *ppsMemDescPtr = psMemDesc;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+failZero:
+       _DevmemMemDescRelease(psMemDesc);
+       psMemDesc = IMG_NULL;   /* Make sure we don't do a discard after the release */
+failDeviceMemAlloc:
+       if (psMemDesc)
+               _DevmemMemDescDiscard(psMemDesc);
+failMemDescAlloc:
+failParams:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAllocateExportable(IMG_HANDLE hBridge,
+                                                IMG_HANDLE hDeviceNode,
+                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                IMG_DEVMEM_ALIGN_T uiAlign,
+                                                DEVMEM_FLAGS_T uiFlags,
+                                                const IMG_PCHAR pszText,
+                                                DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+    PVRSRV_ERROR eError;
+    DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
+       DEVMEM_IMPORT *psImport;
+       IMG_BOOL bMappingTable = IMG_TRUE;
+
+
+       DevmemExportalignAdjustSizeAndAlign(IMG_NULL,
+                                                                               &uiSize,
+                                                                               &uiAlign);
+
+       eError = _DevmemValidateParams(uiSize,
+                                                                  uiAlign,
+                                                                  uiFlags);
+       if (eError != PVRSRV_OK)
+       {
+               goto failParams;
+       }
+
+
+       eError =_DevmemMemDescAlloc(&psMemDesc);
+    if (eError != PVRSRV_OK)
+    {
+        goto failMemDescAlloc;
+    }
+
+       /*
+               Note:
+               In the case of exportable memory we have no heap to
+               query the pagesize from, so we assume host pagesize.
+       */
+       eError = _AllocateDeviceMemory(hBridge,
+                                                                  hDeviceNode,
+                                                                  GET_LOG2_PAGESIZE(),
+                                                                  uiSize,
+                                                                  uiSize,
+                                                                  1,
+                                                                  1,
+                                                                  &bMappingTable,
+                                                                  uiAlign,
+                                                                  uiFlags,
+                                                                  IMG_TRUE,
+                                                                  &psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failDeviceMemAlloc;
+       }
+
+       _DevmemMemDescInit(psMemDesc,
+                                          0,
+                                          psImport);
+
+    *ppsMemDescPtr = psMemDesc;
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+        * the allocation gets mapped/unmapped
+        */
+       OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+       psMemDesc->sTraceData.uiSize = uiSize;
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       {
+               eError = BridgeRIWritePMREntry (psImport->hBridge,
+                                                                               psImport->hPMR,
+                                                                               OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+                                                                               (IMG_CHAR *)pszText,
+                                                                               psImport->uiSize);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
+               }
+
+                /* Attach RI information */
+               eError = BridgeRIWriteMEMDESCEntry (psImport->hBridge,
+                                                                                       psImport->hPMR,
+                                                                                       sizeof("^"),
+                                                                                       "^",
+                                                                                       psMemDesc->uiOffset,
+                                                                                       uiSize,
+                                                                                       IMG_FALSE,
+                                                                                       IMG_TRUE,
+                                                                                       &psMemDesc->hRIHandle);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#else  /* if defined(PVR_RI_DEBUG) */
+       PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVR_RI_DEBUG) */
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+failDeviceMemAlloc:
+    _DevmemMemDescDiscard(psMemDesc);
+
+failMemDescAlloc:
+failParams:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAllocateSparse(IMG_HANDLE hBridge,
+                                        IMG_HANDLE hDeviceNode,
+                                        IMG_DEVMEM_SIZE_T uiSize,
+                                        IMG_DEVMEM_SIZE_T uiChunkSize,
+                                        IMG_UINT32 ui32NumPhysChunks,
+                                        IMG_UINT32 ui32NumVirtChunks,
+                                        IMG_BOOL *pabMappingTable,
+                                        IMG_DEVMEM_ALIGN_T uiAlign,
+                                        DEVMEM_FLAGS_T uiFlags,
+                                        const IMG_PCHAR pszText,
+                                        DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+    PVRSRV_ERROR eError;
+    DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
+       DEVMEM_IMPORT *psImport;
+
+
+       DevmemExportalignAdjustSizeAndAlign(IMG_NULL,
+                                                                               &uiSize,
+                                                                               &uiAlign);
+
+       eError = _DevmemValidateParams(uiSize,
+                                                                  uiAlign,
+                                                                  uiFlags);
+       if (eError != PVRSRV_OK)
+       {
+               goto failParams;
+       }
+
+
+       eError =_DevmemMemDescAlloc(&psMemDesc);
+    if (eError != PVRSRV_OK)
+    {
+        goto failMemDescAlloc;
+    }
+
+       /*
+               Note:
+               In the case of sparse memory we have no heap to
+               query the pagesize from, so we assume host pagesize.
+       */
+       eError = _AllocateDeviceMemory(hBridge,
+                                                                  hDeviceNode,
+                                                                  GET_LOG2_PAGESIZE(),
+                                                                  uiSize,
+                                                                  uiChunkSize,
+                                                                  ui32NumPhysChunks,
+                                                                  ui32NumVirtChunks,
+                                                                  pabMappingTable,
+                                                                  uiAlign,
+                                                                  uiFlags,
+                                                                  IMG_TRUE,
+                                                                  &psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failDeviceMemAlloc;
+       }
+
+       _DevmemMemDescInit(psMemDesc,
+                                          0,
+                                          psImport);
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+        * the allocation gets mapped/unmapped
+        */
+       OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+       psMemDesc->sTraceData.uiSize = uiSize;
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       {
+               eError = BridgeRIWritePMREntry (psImport->hBridge,
+                                                                               psImport->hPMR,
+                                                                               OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+                                                                               (IMG_CHAR *)pszText,
+                                                                               psImport->uiSize);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
+               }
+
+               /* Attach RI information */
+       eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
+                                                                                       psMemDesc->psImport->hPMR,
+                                                                                       sizeof("^"),
+                                                                                       "^",
+                                                                                       psMemDesc->uiOffset,
+                                                                                       uiSize,
+                                                                                       IMG_FALSE,
+                                                                                       IMG_TRUE,
+                                                                                       &psMemDesc->hRIHandle);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#else  /* if defined(PVR_RI_DEBUG) */
+       PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVR_RI_DEBUG) */
+
+       *ppsMemDescPtr = psMemDesc;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+failDeviceMemAlloc:
+    _DevmemMemDescDiscard(psMemDesc);
+
+failMemDescAlloc:
+failParams:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+/*****************************************************************************
+ *                Devmem unsecure export functions                           *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemExport(DEVMEM_MEMDESC *psMemDesc,
+             DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+    /* Caller to provide storage for export cookie struct */
+    PVRSRV_ERROR eError;
+    IMG_HANDLE hPMRExportHandle = 0;
+    IMG_UINT64 uiPMRExportPassword = 0;
+    IMG_DEVMEM_SIZE_T uiSize = 0;
+    IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig = 0;
+
+    if (psMemDesc == IMG_NULL || psExportCookie == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto e0;
+    }
+
+    eError = _Mapping_Export(psMemDesc->psImport,
+                             &hPMRExportHandle,
+                             &uiPMRExportPassword,
+                             &uiSize,
+                             &uiLog2Contig);
+    if (eError != PVRSRV_OK)
+    {
+               psExportCookie->uiSize = 0;
+        goto e0;
+    }
+
+    psExportCookie->hPMRExportHandle = hPMRExportHandle;
+    psExportCookie->uiPMRExportPassword = uiPMRExportPassword;
+    psExportCookie->uiSize = uiSize;
+    psExportCookie->uiLog2ContiguityGuarantee = uiLog2Contig;
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
+                                   DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie,
+                                   DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+       DEVMEM_EXPORTHANDLE hPMRExportHandle;
+       IMG_DEVMEM_SIZE_T uiPMRSize;
+       IMG_DEVMEM_LOG2ALIGN_T uiPMRLog2Contig;
+       DEVMEM_EXPORTKEY uiPMRExportKey;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       eError = BridgePMRMakeServerExportClientExport(hBridge,
+                                                                                                       hServerExportCookie,
+                                                                                                       &hPMRExportHandle,
+                                                                                                       &uiPMRSize,
+                                                                                                       &uiPMRLog2Contig,
+                                                                                                       &uiPMRExportKey);
+
+       if (eError == PVRSRV_OK)
+       {
+               psExportCookie->hPMRExportHandle = hPMRExportHandle;
+               psExportCookie->uiPMRExportPassword = uiPMRExportKey;
+               psExportCookie->uiSize = uiPMRSize;
+               psExportCookie->uiLog2ContiguityGuarantee = uiPMRLog2Contig;
+       }
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemUnmakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
+                                   DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+       return BridgePMRUnmakeServerExportClientExport(hBridge, psExportCookie->hPMRExportHandle);
+}
+
+IMG_INTERNAL IMG_BOOL
+DevmemIsValidExportCookie(DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+       /* Assume that if the size is set, the export cookie is used */
+       return (psExportCookie->uiSize != 0x0);
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemUnexport(DEVMEM_MEMDESC *psMemDesc,
+               DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+    _Mapping_Unexport(psMemDesc->psImport,
+                      psExportCookie->hPMRExportHandle);
+
+    psExportCookie->uiSize = 0;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemImport(IMG_HANDLE hBridge,
+                        DEVMEM_EXPORTCOOKIE *psCookie,
+                        DEVMEM_FLAGS_T uiFlags,
+                        DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+    DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
+    DEVMEM_IMPORT *psImport;
+    IMG_HANDLE hPMR;
+    PVRSRV_ERROR eError;
+
+       if (ppsMemDescPtr == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto failParams;
+    }
+
+       eError =_DevmemMemDescAlloc(&psMemDesc);
+    if (eError != PVRSRV_OK)
+    {
+        goto failMemDescAlloc;
+    }
+
+       eError = _DevmemImportStructAlloc(hBridge,
+                                                                         IMG_TRUE,
+                                                                         &psImport);
+    if (eError != PVRSRV_OK)
+    {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto failImportAlloc;
+    }
+
+
+    /* Get a handle to the PMR (inc refcount, checks authorization) */
+    eError = BridgePMRImportPMR(hBridge,
+                                psCookie->hPMRExportHandle,
+                                psCookie->uiPMRExportPassword,
+                                psCookie->uiSize, /* not trusted - just for sanity checks */
+                                psCookie->uiLog2ContiguityGuarantee, /* not trusted - just for sanity checks */
+                                &hPMR);
+    if (eError != PVRSRV_OK)
+    {
+        goto failImport;
+    }
+
+       _DevmemImportStructInit(psImport,
+                                                       psCookie->uiSize,
+                                                       1ULL << psCookie->uiLog2ContiguityGuarantee,
+                                                       uiFlags,
+                                                       hPMR);
+
+       _DevmemMemDescInit(psMemDesc,
+                                          0,
+                                          psImport);
+
+    *ppsMemDescPtr = psMemDesc;
+
+#if defined(PVR_RI_DEBUG)
+       {
+               /* Attach RI information */
+               eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
+                                                                                       psMemDesc->psImport->hPMR,
+                                                                                       sizeof("^"),
+                                                                                       "^",
+                                                                                       psMemDesc->uiOffset,
+                                                                                       psMemDesc->psImport->uiSize,
+                                                                                       IMG_TRUE,
+                                                                                       IMG_FALSE,
+                                                                                       &psMemDesc->hRIHandle);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#endif /* if defined(PVR_RI_DEBUG) */
+
+       return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+failImport:
+    _DevmemImportDiscard(psImport);
+failImportAlloc:
+    _DevmemMemDescDiscard(psMemDesc);
+failMemDescAlloc:
+failParams:
+    PVR_ASSERT(eError != PVRSRV_OK);
+
+    return eError;
+}
+
+/*****************************************************************************
+ *                   Common MemDesc functions                                *
+ *****************************************************************************/
+
+/*
+       This function is called for freeing any class of memory
+*/
+IMG_INTERNAL IMG_VOID
+DevmemFree(DEVMEM_MEMDESC *psMemDesc)
+{
+#if defined(PVR_RI_DEBUG)
+       if (psMemDesc->hRIHandle)
+       {
+           PVRSRV_ERROR eError;
+
+           eError = BridgeRIDeleteMEMDESCEntry(psMemDesc->psImport->hBridge,
+                                                                  psMemDesc->hRIHandle);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIDeleteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#endif  /* if defined(PVR_RI_DEBUG) */
+       _DevmemMemDescRelease(psMemDesc);
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc,
+                                 DEVMEM_HEAP *psHeap,
+                                 IMG_DEV_VIRTADDR *psDevVirtAddr)
+{
+       DEVMEM_IMPORT *psImport;
+       IMG_DEV_VIRTADDR sDevVAddr;
+       PVRSRV_ERROR eError;
+       IMG_BOOL bMap = IMG_TRUE;
+
+       OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+       if (psHeap == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto failParams;
+       }
+
+       if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0)
+       {
+               eError = PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED;
+               goto failCheck;
+       }
+
+       /* Don't map memory for deferred allocations */
+       if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+       {
+               PVR_ASSERT(psMemDesc->psImport->bExportable);
+               bMap = IMG_FALSE;
+       }
+
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount+1);
+
+       psImport = psMemDesc->psImport;
+       _DevmemMemDescAcquire(psMemDesc);
+
+       eError = _DevmemImportStructDevMap(psHeap,
+                                                                          bMap,
+                                                                          psImport);
+       if (eError != PVRSRV_OK)
+       {
+               goto failMap;
+       }
+
+       sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
+       sDevVAddr.uiAddr += psMemDesc->uiOffset;
+       psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr;
+       psMemDesc->sDeviceMemDesc.ui32RefCount++;
+
+    *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
+
+    OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       BridgeDevicememHistoryMap(psMemDesc->psImport->hBridge,
+                                               psMemDesc->sDeviceMemDesc.sDevVAddr,
+                                               psMemDesc->sTraceData.uiSize,
+                                               psMemDesc->sTraceData.szText);
+#endif
+
+#if defined(PVR_RI_DEBUG)
+       if (psMemDesc->hRIHandle)
+    {
+                eError = BridgeRIUpdateMEMDESCAddr(psImport->hBridge,
+                                                                          psMemDesc->hRIHandle,
+                                                                          psImport->sDeviceImport.sDevVAddr);
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
+               }
+       }
+#endif
+
+    return PVRSRV_OK;
+
+failMap:
+       _DevmemMemDescRelease(psMemDesc);
+failCheck:
+failParams:
+       OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+                         IMG_DEV_VIRTADDR *psDevVirtAddr)
+{
+       PVRSRV_ERROR eError;
+
+       OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount+1);
+
+       if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
+       {
+               eError = PVRSRV_ERROR_DEVICEMEM_NO_MAPPING;
+               goto failCheck;
+       }
+       psMemDesc->sDeviceMemDesc.ui32RefCount++;
+
+    *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
+       OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+    return PVRSRV_OK;
+
+failCheck:
+       OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc)
+{
+       PVR_ASSERT(psMemDesc != IMG_NULL);
+
+       OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount,
+                                       psMemDesc->sDeviceMemDesc.ui32RefCount-1);
+
+       PVR_ASSERT(psMemDesc->sDeviceMemDesc.ui32RefCount != 0);
+
+       if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
+       {
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+               BridgeDevicememHistoryUnmap(psMemDesc->psImport->hBridge,
+                                                       psMemDesc->sDeviceMemDesc.sDevVAddr,
+                                                       psMemDesc->sTraceData.uiSize,
+                                                       psMemDesc->sTraceData.szText);
+#endif
+               _DevmemImportStructDevUnmap(psMemDesc->psImport);
+               OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+               _DevmemMemDescRelease(psMemDesc);
+       }
+       else
+       {
+               OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+       }
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+                         IMG_VOID **ppvCpuVirtAddr)
+{
+       PVRSRV_ERROR eError;
+
+       OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       psMemDesc->sCPUMemDesc.ui32RefCount,
+                                       psMemDesc->sCPUMemDesc.ui32RefCount+1);
+
+       if (psMemDesc->sCPUMemDesc.ui32RefCount++ == 0)
+       {
+               DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+               IMG_UINT8 *pui8CPUVAddr;
+
+               _DevmemMemDescAcquire(psMemDesc);
+               eError = _DevmemImportStructCPUMap(psImport);
+               if (eError != PVRSRV_OK)
+               {
+                       goto failMap;
+               }
+
+               pui8CPUVAddr = psImport->sCPUImport.pvCPUVAddr;
+               pui8CPUVAddr += psMemDesc->uiOffset;
+               psMemDesc->sCPUMemDesc.pvCPUVAddr = pui8CPUVAddr;
+       }
+    *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr;
+
+    VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize);
+
+    OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+
+    return PVRSRV_OK;
+
+failMap:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       psMemDesc->sCPUMemDesc.ui32RefCount--;
+       _DevmemMemDescRelease(psMemDesc);
+       OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+
+       return eError;
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc)
+{
+       PVR_ASSERT(psMemDesc != IMG_NULL);
+
+       OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       psMemDesc->sCPUMemDesc.ui32RefCount,
+                                       psMemDesc->sCPUMemDesc.ui32RefCount-1);
+
+       PVR_ASSERT(psMemDesc->sCPUMemDesc.ui32RefCount != 0);
+
+       if (--psMemDesc->sCPUMemDesc.ui32RefCount == 0)
+       {
+               OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+               _DevmemImportStructCPUUnmap(psMemDesc->psImport);
+               _DevmemMemDescRelease(psMemDesc);
+       }
+       else
+       {
+               OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+       }
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+                          IMG_HANDLE *phImport)
+{
+       if (psMemDesc->psImport->bExportable == IMG_FALSE)
+       {
+               return PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION;
+       }
+
+       *phImport = psMemDesc->psImport->hPMR;
+
+       return PVRSRV_OK;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc,
+                                                  IMG_UINT64 *pui64UID)
+{
+       DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+       PVRSRV_ERROR eError;
+
+       eError = BridgePMRGetUID(psImport->hBridge,
+                                                        psImport->hPMR,
+                                                        pui64UID);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc,
+                               IMG_HANDLE *hReservation)
+{
+       DEVMEM_IMPORT *psImport;
+
+       PVR_ASSERT(psMemDesc);
+       psImport = psMemDesc->psImport;
+
+       PVR_ASSERT(psImport);
+       *hReservation = psImport->sDeviceImport.hReservation;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc,
+               IMG_HANDLE *phPMR,
+               IMG_DEVMEM_OFFSET_T *puiPMROffset)
+{
+       DEVMEM_IMPORT *psImport;
+
+       PVR_ASSERT(psMemDesc);
+       *puiPMROffset = psMemDesc->uiOffset;
+       psImport = psMemDesc->psImport;
+
+       PVR_ASSERT(psImport);
+       *phPMR = psImport->hPMR;
+
+       return PVRSRV_OK;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
+                               DEVMEM_FLAGS_T *puiFlags)
+{
+       DEVMEM_IMPORT *psImport;
+
+       PVR_ASSERT(psMemDesc);
+       psImport = psMemDesc->psImport;
+
+       PVR_ASSERT(psImport);
+       *puiFlags = psImport->uiFlags;
+
+       return PVRSRV_OK;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemLocalImport(IMG_HANDLE hBridge,
+                                 IMG_HANDLE hExtHandle,
+                                 DEVMEM_FLAGS_T uiFlags,
+                                 DEVMEM_MEMDESC **ppsMemDescPtr,
+                                 IMG_DEVMEM_SIZE_T *puiSizePtr)
+{
+    DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
+    DEVMEM_IMPORT *psImport;
+    IMG_DEVMEM_SIZE_T uiSize;
+    IMG_DEVMEM_ALIGN_T uiAlign;
+    IMG_HANDLE hPMR;
+    PVRSRV_ERROR eError;
+
+    if (ppsMemDescPtr == IMG_NULL)
+    {
+        eError = PVRSRV_ERROR_INVALID_PARAMS;
+        goto failParams;
+    }  
+
+       eError =_DevmemMemDescAlloc(&psMemDesc);
+    if (eError != PVRSRV_OK)
+    {
+        goto failMemDescAlloc;
+    }
+
+       eError = _DevmemImportStructAlloc(hBridge,
+                                                                         IMG_TRUE,
+                                                                         &psImport);
+    if (eError != PVRSRV_OK)
+    {
+        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+        goto failImportAlloc;
+    }
+
+       /* Get the PMR handle and it's size from the server */
+       eError = BridgePMRLocalImportPMR(hBridge,
+                                                                        hExtHandle,
+                                                                        &hPMR,
+                                                                        &uiSize,
+                                                                        &uiAlign);
+       if (eError != PVRSRV_OK)
+       {
+               goto failImport;
+       }
+
+       _DevmemImportStructInit(psImport,
+                                                       uiSize,
+                                                       uiAlign,
+                                                       uiFlags,
+                                                       hPMR);
+
+       _DevmemMemDescInit(psMemDesc,
+                                          0,
+                                          psImport);
+
+    *ppsMemDescPtr = psMemDesc;
+       if (puiSizePtr)
+               *puiSizePtr = uiSize;
+
+#if defined(PVR_RI_DEBUG)
+       {
+               /* Attach RI information */
+               eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
+                                                                                       psMemDesc->psImport->hPMR,
+                                                                                       sizeof("^"),
+                                                                                       "^",
+                                                                                       psMemDesc->uiOffset,
+                                                                                       psMemDesc->psImport->uiSize,
+                                                                                       IMG_TRUE,
+                                                                                       IMG_FALSE,
+                                                                                       &(psMemDesc->hRIHandle));
+               if( eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
+               }
+       }
+#endif /* if defined(PVR_RI_DEBUG) */
+       return PVRSRV_OK;
+
+failImport:
+    _DevmemImportDiscard(psImport);
+failImportAlloc:
+       _DevmemMemDescDiscard(psMemDesc);
+failMemDescAlloc:
+failParams:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext,
+                         IMG_DEV_VIRTADDR sDevVAddr)
+{
+    return BridgeDevmemIsVDevAddrValid(psContext->hBridge,
+                                       psContext->hDevMemServerContext,
+                                       sDevVAddr);
+}
+
+IMG_INTERNAL IMG_UINT32
+DevmemGetHeapLog2ImportAlignment(DEVMEM_HEAP *psHeap)
+{
+       return psHeap->uiLog2ImportAlignment;
+}
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/devicemem_pdump.c b/drivers/gpu/rogue_m/services/shared/common/devicemem_pdump.c
new file mode 100644 (file)
index 0000000..36bc123
--- /dev/null
@@ -0,0 +1,323 @@
+/*************************************************************************/ /*!
+@File
+@Title          Shared device memory management PDump functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements common (client & server) PDump functions for the
+                memory management code
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined PDUMP
+
+#include "allocmem.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pdump.h"
+#include "devicemem_utils.h"
+#include "devicemem_pdump.h"
+#include "client_pdumpmm_bridge.h"
+
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
+                   IMG_DEVMEM_OFFSET_T uiOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+
+    PVR_ASSERT(uiOffset + uiSize <= psMemDesc->psImport->uiSize);
+
+    eError = BridgePMRPDumpLoadMem(psMemDesc->psImport->hBridge,
+                                   psMemDesc->psImport->hPMR,
+                                   psMemDesc->uiOffset + uiOffset,
+                                   uiSize,
+                                   uiPDumpFlags,
+                                   IMG_FALSE);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadZeroMem(DEVMEM_MEMDESC *psMemDesc,
+                   IMG_DEVMEM_OFFSET_T uiOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+
+    PVR_ASSERT(uiOffset + uiSize <= psMemDesc->psImport->uiSize);
+
+    eError = BridgePMRPDumpLoadMem(psMemDesc->psImport->hBridge,
+                                   psMemDesc->psImport->hPMR,
+                                   psMemDesc->uiOffset + uiOffset,
+                                   uiSize,
+                                   uiPDumpFlags,
+                                   IMG_TRUE);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT32 ui32Value,
+                        PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgePMRPDumpLoadMemValue32(psMemDesc->psImport->hBridge,
+                                        psMemDesc->psImport->hPMR,
+                                        psMemDesc->uiOffset + uiOffset,
+                                        ui32Value,
+                                        uiPDumpFlags);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT64 ui64Value,
+                        PDUMP_FLAGS_T uiPDumpFlags)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgePMRPDumpLoadMemValue64(psMemDesc->psImport->hBridge,
+                                          psMemDesc->psImport->hPMR,
+                                          psMemDesc->uiOffset + uiOffset,
+                                          ui64Value,
+                                          uiPDumpFlags);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+/* FIXME: This should be server side only */
+IMG_INTERNAL PVRSRV_ERROR
+DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC           *psMemDesc,
+                                                         IMG_DEVMEM_OFFSET_T   *puiMemOffset,
+                                                         IMG_CHAR                              *pszName,
+                                                         IMG_UINT32                    ui32Size)
+{
+    PVRSRV_ERROR               eError;
+       IMG_CHAR                        aszMemspaceName[100];
+       IMG_CHAR                        aszSymbolicName[100];
+       IMG_DEVMEM_OFFSET_T uiNextSymName;
+
+       *puiMemOffset += psMemDesc->uiOffset;
+
+    eError = BridgePMRPDumpSymbolicAddr(psMemDesc->psImport->hBridge,
+                                                                               psMemDesc->psImport->hPMR,
+                                                                               *puiMemOffset,
+                                                                               sizeof(aszMemspaceName),
+                                                                               &aszMemspaceName[0],
+                                                                               sizeof(aszSymbolicName),
+                                                                               &aszSymbolicName[0],
+                                                                               puiMemOffset,
+                                                                               &uiNextSymName);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+
+       OSSNPrintf(pszName, ui32Size, "%s:%s", &aszMemspaceName[0], &aszSymbolicName[0]);
+       return eError;
+}
+
+IMG_INTERNAL IMG_VOID
+DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc,
+                      IMG_DEVMEM_OFFSET_T uiOffset,
+                      IMG_DEVMEM_SIZE_T uiSize,
+                      const IMG_CHAR *pszFilename)
+{
+    PVRSRV_ERROR eError;
+
+    eError = BridgePMRPDumpSaveToFile(psMemDesc->psImport->hBridge,
+                                                                         psMemDesc->psImport->hPMR,
+                                                                         psMemDesc->uiOffset + uiOffset,
+                                                                         uiSize,
+                                                                         OSStringLength(pszFilename) + 1,
+                                                                         pszFilename);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+/* FIXME: Remove? */
+IMG_INTERNAL IMG_VOID
+DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
+                             IMG_DEVMEM_OFFSET_T uiOffset,
+                             IMG_DEVMEM_SIZE_T uiSize,
+                             const IMG_CHAR *pszFilename,
+                                                        IMG_UINT32 ui32FileOffset,
+                                                        IMG_UINT32     ui32PdumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_DEV_VIRTADDR sDevAddrStart;
+
+    sDevAddrStart = psMemDesc->psImport->sDeviceImport.sDevVAddr;
+    sDevAddrStart.uiAddr += psMemDesc->uiOffset;
+    sDevAddrStart.uiAddr += uiOffset;
+
+    eError = BridgeDevmemIntPDumpSaveToFileVirtual(psMemDesc->psImport->hBridge,
+                                                   psMemDesc->psImport->sDeviceImport.psHeap->psCtx->hDevMemServerContext,
+                                                   sDevAddrStart,
+                                                   uiSize,
+                                                   OSStringLength(pszFilename) + 1,
+                                                   pszFilename,
+                                                                                                  ui32FileOffset,
+                                                                                                  ui32PdumpFlags);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc,
+                       IMG_DEVMEM_OFFSET_T uiOffset,
+                       IMG_UINT32 ui32Value,
+                       IMG_UINT32 ui32Mask,
+                       PDUMP_POLL_OPERATOR eOperator,
+                       PDUMP_FLAGS_T ui32PDumpFlags)
+{
+    PVRSRV_ERROR eError;
+    IMG_DEVMEM_SIZE_T uiNumBytes;
+
+    uiNumBytes = 4;
+
+    if (psMemDesc->uiOffset + uiOffset + uiNumBytes >= psMemDesc->psImport->uiSize)
+    {
+        eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE;
+        goto e0;
+    }
+
+    eError = BridgePMRPDumpPol32(psMemDesc->psImport->hBridge,
+                                 psMemDesc->psImport->hPMR,
+                                 psMemDesc->uiOffset + uiOffset,
+                                 ui32Value,
+                                 ui32Mask,
+                                 eOperator,
+                                 ui32PDumpFlags);
+    if (eError != PVRSRV_OK)
+    {
+        goto e0;
+    }
+
+    return PVRSRV_OK;
+
+    /*
+      error exit paths follow
+    */
+
+ e0:
+    PVR_ASSERT(eError != PVRSRV_OK);
+    return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc,
+                               IMG_DEVMEM_OFFSET_T uiReadOffset,
+                               IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                               IMG_DEVMEM_SIZE_T uiPacketSize,
+                               IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVRSRV_ERROR eError;
+
+       if ((psMemDesc->uiOffset + uiReadOffset) > psMemDesc->psImport->uiSize)
+       {
+               eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE;
+               goto e0;
+       }
+
+       eError = BridgePMRPDumpCBP(psMemDesc->psImport->hBridge,
+                                                          psMemDesc->psImport->hPMR,
+                                                          psMemDesc->uiOffset + uiReadOffset,
+                                                          uiWriteOffset,
+                                                          uiPacketSize,
+                                                          uiBufferSize);
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+
+       return PVRSRV_OK;
+
+e0:
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+#endif /* PDUMP */
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/devicemem_utils.c b/drivers/gpu/rogue_m/services/shared/common/devicemem_utils.c
new file mode 100644 (file)
index 0000000..307f047
--- /dev/null
@@ -0,0 +1,698 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management internal utility functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Utility functions used internally by device memory management
+                code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "allocmem.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "ra.h"
+#include "devicemem_utils.h"
+#include "client_mm_bridge.h"
+
+#if !defined(__KERNEL__) && defined(SUPPORT_ION)
+#include <sys/mman.h>
+#endif
+
+/*
+       The Devmem import structure is the structure we use
+       to manage memory that is "imported" (which is page
+       granular) from the server into our process, this
+       includes allocations.
+
+       This allows memory to be imported without requiring
+       any CPU or device mapping. Memory can then be mapped
+       into the device or CPU on demand, but neither is
+       required.
+*/
+
+IMG_INTERNAL
+IMG_VOID _DevmemImportStructAcquire(DEVMEM_IMPORT *psImport)
+{
+       IMG_INT iRefCount = OSAtomicIncrement(&psImport->hRefCount);
+       PVR_UNREFERENCED_PARAMETER(iRefCount);
+       PVR_ASSERT(iRefCount != 1);
+
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       iRefCount-1,
+                                       iRefCount);
+}
+
+IMG_INTERNAL
+IMG_VOID _DevmemImportStructRelease(DEVMEM_IMPORT *psImport)
+{
+       IMG_INT iRefCount = OSAtomicDecrement(&psImport->hRefCount);
+       PVR_ASSERT(iRefCount >= 0);
+
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       iRefCount+1,
+                                       iRefCount);
+
+       if (iRefCount == 0)
+       {
+               BridgePMRUnrefPMR(psImport->hBridge,
+                                                 psImport->hPMR);
+               OSLockDestroy(psImport->sCPUImport.hLock);
+               OSLockDestroy(psImport->sDeviceImport.hLock);
+               OSLockDestroy(psImport->hLock);
+               OSFreeMem(psImport);
+       }
+}
+
+IMG_INTERNAL
+IMG_VOID _DevmemImportDiscard(DEVMEM_IMPORT *psImport)
+{
+       PVR_ASSERT(OSAtomicRead(&psImport->hRefCount) == 0);
+       OSLockDestroy(psImport->sCPUImport.hLock);
+       OSLockDestroy(psImport->sDeviceImport.hLock);
+       OSLockDestroy(psImport->hLock);
+       OSFreeMem(psImport);
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc)
+{
+       DEVMEM_MEMDESC *psMemDesc;
+       PVRSRV_ERROR eError;
+
+       psMemDesc = OSAllocMem(sizeof(DEVMEM_MEMDESC));
+
+       if (psMemDesc == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto failAlloc;
+       }
+       
+       /* Structure must be zero'd incase it needs to be freed before it is initialised! */
+       OSCachedMemSet(psMemDesc, 0, sizeof(DEVMEM_MEMDESC));
+
+       eError = OSLockCreate(&psMemDesc->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failMDLock;
+       }
+
+       eError = OSLockCreate(&psMemDesc->sDeviceMemDesc.hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failDMDLock;
+       }
+
+       eError = OSLockCreate(&psMemDesc->sCPUMemDesc.hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failCMDLock;
+       }
+
+       *ppsMemDesc = psMemDesc;
+
+       return PVRSRV_OK;
+
+failCMDLock:
+       OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+failDMDLock:
+       OSLockDestroy(psMemDesc->hLock);
+failMDLock:
+       OSFreeMem(psMemDesc);
+failAlloc:
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+/*
+       Init the MemDesc structure
+*/
+IMG_INTERNAL
+IMG_VOID _DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
+                                                                                 IMG_DEVMEM_OFFSET_T uiOffset,
+                                                                                 DEVMEM_IMPORT *psImport)
+{
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       0,
+                                       1);
+
+       psMemDesc->psImport = psImport;
+       psMemDesc->uiOffset = uiOffset;
+
+       psMemDesc->sDeviceMemDesc.ui32RefCount = 0;
+       psMemDesc->sCPUMemDesc.ui32RefCount = 0;
+       OSAtomicWrite(&psMemDesc->hRefCount, 1);
+}
+
+IMG_INTERNAL
+IMG_VOID _DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc)
+{
+       IMG_INT iRefCount;
+       PVR_UNREFERENCED_PARAMETER(iRefCount);
+
+       iRefCount = OSAtomicIncrement(&psMemDesc->hRefCount);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       iRefCount-1,
+                                       iRefCount);
+}
+
+IMG_INTERNAL
+IMG_VOID _DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc)
+{
+       IMG_INT iRefCount;
+       PVR_ASSERT(psMemDesc != NULL);
+       
+       iRefCount = OSAtomicDecrement(&psMemDesc->hRefCount);
+       PVR_ASSERT(iRefCount >= 0);
+
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psMemDesc,
+                                       iRefCount+1,
+                                       iRefCount);
+
+       if (iRefCount == 0)
+       {
+               if (!psMemDesc->psImport->bExportable)
+               {
+                       RA_Free(psMemDesc->psImport->sDeviceImport.psHeap->psSubAllocRA,
+                                       psMemDesc->psImport->sDeviceImport.sDevVAddr.uiAddr +
+                                       psMemDesc->uiOffset);
+               }
+               else
+               {
+                       _DevmemImportStructRelease(psMemDesc->psImport);
+               }
+
+               OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
+               OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+               OSLockDestroy(psMemDesc->hLock);
+               OSFreeMem(psMemDesc);
+       }
+}
+
+IMG_INTERNAL
+IMG_VOID _DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc)
+{
+       PVR_ASSERT(OSAtomicRead(&psMemDesc->hRefCount) == 0);
+
+       OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
+       OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+       OSLockDestroy(psMemDesc->hLock);
+       OSFreeMem(psMemDesc);
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
+                                                                  IMG_DEVMEM_ALIGN_T uiAlign,
+                                                                  DEVMEM_FLAGS_T uiFlags)
+{
+    if (!(uiFlags & PVRSRV_MEMALLOCFLAG_GPU_READABLE))
+    {
+        /* Don't support memory not GPU readable currently */
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    if ((uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
+        (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+    {
+        /* Zero on Alloc and Poison on Alloc are mutually exclusive */
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    if (uiAlign & (uiAlign-1))
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    /* Verify that size is a positive integer multiple of alignment */
+#if 0 // FIXME
+    if (uiSize & (uiAlign-1))
+    {
+        /* Size not a multiple of alignment */
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+#endif
+    if (uiSize == 0)
+    {
+        return PVRSRV_ERROR_INVALID_PARAMS;
+    }
+
+    return PVRSRV_OK;
+}
+
+/*
+       Allocate and init an import structure
+*/
+IMG_INTERNAL
+PVRSRV_ERROR _DevmemImportStructAlloc(IMG_HANDLE hBridge,
+                                                                         IMG_BOOL bExportable,
+                                                                         DEVMEM_IMPORT **ppsImport)
+{
+       DEVMEM_IMPORT *psImport;
+       PVRSRV_ERROR eError;
+
+    psImport = OSAllocMem(sizeof *psImport);
+    if (psImport == IMG_NULL)
+    {
+        return PVRSRV_ERROR_OUT_OF_MEMORY;
+    }
+
+       /* Setup some known bad values for things we don't have yet */
+       psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON;
+    psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON;
+    psImport->sDeviceImport.psHeap = IMG_NULL;
+    psImport->sDeviceImport.bMapped = IMG_FALSE;
+
+       eError = OSLockCreate(&psImport->sDeviceImport.hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failDIOSLockCreate;
+       }
+
+       psImport->sCPUImport.hOSMMapData = IMG_NULL;
+       psImport->sCPUImport.pvCPUVAddr = IMG_NULL;
+
+       eError = OSLockCreate(&psImport->sCPUImport.hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failCIOSLockCreate;
+       }
+
+       /* Set up common elements */
+    psImport->hBridge = hBridge;
+    psImport->bExportable = bExportable;
+
+       /* Setup refcounts */
+    psImport->sDeviceImport.ui32RefCount = 0;
+    psImport->sCPUImport.ui32RefCount = 0;
+    OSAtomicWrite(&psImport->hRefCount, 0);
+
+       /* Create the lock */
+       eError = OSLockCreate(&psImport->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto failILockAlloc;
+       }
+
+#if !defined(__KERNEL__) && defined(SUPPORT_ION)
+       psImport->sCPUImport.iDmaBufFd = -1;
+#endif
+
+    *ppsImport = psImport;
+    
+    return PVRSRV_OK;
+
+failILockAlloc:
+       OSLockDestroy(psImport->sCPUImport.hLock);
+failCIOSLockCreate:
+       OSLockDestroy(psImport->sDeviceImport.hLock);
+failDIOSLockCreate:
+       OSFreeMem(psImport);
+       PVR_ASSERT(eError != PVRSRV_OK);
+
+       return eError;
+}
+
+/*
+       Initialise the import structure
+*/
+IMG_INTERNAL
+IMG_VOID _DevmemImportStructInit(DEVMEM_IMPORT *psImport,
+                                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                                IMG_DEVMEM_ALIGN_T uiAlign,
+                                                                DEVMEM_FLAGS_T uiFlags,
+                                                                IMG_HANDLE hPMR)
+{
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       0,
+                                       1);
+
+       psImport->uiSize = uiSize;
+       psImport->uiAlign = uiAlign;
+       psImport->uiFlags = uiFlags;
+       psImport->hPMR = hPMR;
+       OSAtomicWrite(&psImport->hRefCount, 1);
+}
+
+/*
+       Map an import to the device
+*/
+IMG_INTERNAL
+PVRSRV_ERROR _DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
+                                                                          IMG_BOOL bMap,
+                                                                          DEVMEM_IMPORT *psImport)
+{
+       DEVMEM_DEVICE_IMPORT *psDeviceImport;
+       IMG_BOOL bStatus;
+    RA_BASE_T uiAllocatedAddr;
+    RA_LENGTH_T uiAllocatedSize;
+    IMG_DEV_VIRTADDR sBase;
+    IMG_HANDLE hReservation;
+    PVRSRV_ERROR eError;
+       IMG_UINT uiAlign;
+
+       /* Round the provided import alignment to the configured heap alignment */
+       uiAlign = 1ULL << psHeap->uiLog2ImportAlignment;
+       uiAlign = (psImport->uiAlign + uiAlign - 1) & ~(uiAlign-1);
+
+       psDeviceImport = &psImport->sDeviceImport;
+
+       OSLockAcquire(psDeviceImport->hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       psDeviceImport->ui32RefCount,
+                                       psDeviceImport->ui32RefCount+1);
+
+       if (psDeviceImport->ui32RefCount++ == 0)
+       {
+               _DevmemImportStructAcquire(psImport);
+
+               OSAtomicIncrement(&psHeap->hImportCount);
+
+               if (psHeap->psCtx->hBridge != psImport->hBridge)
+               {
+                       /*
+                               The import was done with a different connection then the
+                               memory context which means they are not compatible.
+                       */
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+                       goto failCheck;
+               }
+
+               /* Allocate space in the VM */
+           bStatus = RA_Alloc(psHeap->psQuantizedVMRA,
+                              psImport->uiSize,
+                              0, /* flags: this RA doesn't use flags*/
+                              uiAlign,
+                              &uiAllocatedAddr,
+                              &uiAllocatedSize,
+                              IMG_NULL /* don't care about per-import priv data */
+                              );
+           if (!bStatus)
+           {
+               eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM;
+               goto failVMRAAlloc;
+           }
+       
+           /* No reason for the allocated virtual size to be different from
+              the PMR's size */
+           PVR_ASSERT(uiAllocatedSize == psImport->uiSize);
+       
+           sBase.uiAddr = uiAllocatedAddr;
+       
+               /* Setup page tables for the allocated VM space */
+           eError = BridgeDevmemIntReserveRange(psHeap->psCtx->hBridge,
+                                                                                        psHeap->hDevMemServerHeap,
+                                                                                        sBase,
+                                                                                        uiAllocatedSize,
+                                                                                        &hReservation);
+           if (eError != PVRSRV_OK)
+           {
+               goto failReserve;
+           }
+
+               if (bMap)
+               {
+                       DEVMEM_FLAGS_T uiMapFlags;
+                       
+                       uiMapFlags = psImport->uiFlags & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK;
+
+                       /* Actually map the PMR to allocated VM space */
+                       eError = BridgeDevmemIntMapPMR(psHeap->psCtx->hBridge,
+                                                                                  psHeap->hDevMemServerHeap,
+                                                                                  hReservation,
+                                                                                  psImport->hPMR,
+                                                                                  uiMapFlags,
+                                                                                  &psDeviceImport->hMapping);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto failMap;
+                       }
+                       psDeviceImport->bMapped = IMG_TRUE;
+               }
+
+               /* Setup device mapping specific parts of the mapping info */
+           psDeviceImport->hReservation = hReservation;
+               psDeviceImport->sDevVAddr.uiAddr = uiAllocatedAddr;
+               psDeviceImport->psHeap = psHeap;
+       }
+       else
+       {
+               /*
+                       Check that we've been asked to map it into the
+                       same heap 2nd time around
+               */
+               if (psHeap != psDeviceImport->psHeap)
+               {
+                       eError = PVRSRV_ERROR_INVALID_HEAP;
+                       goto failParams;
+               }
+       }
+       OSLockRelease(psDeviceImport->hLock);
+
+       return PVRSRV_OK;
+
+failMap:
+       BridgeDevmemIntUnreserveRange(psHeap->psCtx->hBridge,
+                                                                 hReservation);
+failReserve:
+       RA_Free(psHeap->psQuantizedVMRA,
+            uiAllocatedAddr);
+failVMRAAlloc:
+failCheck:
+       _DevmemImportStructRelease(psImport);
+       OSAtomicDecrement(&psHeap->hImportCount);
+failParams:
+       OSLockRelease(psDeviceImport->hLock);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*
+       Unmap an import from the Device
+*/
+IMG_INTERNAL
+IMG_VOID _DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport)
+{
+       PVRSRV_ERROR eError;
+       DEVMEM_DEVICE_IMPORT *psDeviceImport;
+
+       psDeviceImport = &psImport->sDeviceImport;
+
+       OSLockAcquire(psDeviceImport->hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       psDeviceImport->ui32RefCount,
+                                       psDeviceImport->ui32RefCount-1);
+
+       if (--psDeviceImport->ui32RefCount == 0)
+       {
+               DEVMEM_HEAP *psHeap = psDeviceImport->psHeap;
+
+               if (psDeviceImport->bMapped)
+               {
+                       eError = BridgeDevmemIntUnmapPMR(psImport->hBridge,
+                                                                                       psDeviceImport->hMapping);
+                       PVR_ASSERT(eError == PVRSRV_OK);
+               }
+       
+           eError = BridgeDevmemIntUnreserveRange(psImport->hBridge,
+                                               psDeviceImport->hReservation);
+           PVR_ASSERT(eError == PVRSRV_OK);
+       
+           RA_Free(psHeap->psQuantizedVMRA,
+                   psDeviceImport->sDevVAddr.uiAddr);
+
+           OSLockRelease(psDeviceImport->hLock);
+
+               _DevmemImportStructRelease(psImport);
+
+               OSAtomicDecrement(&psHeap->hImportCount);
+       }
+       else
+       {
+               OSLockRelease(psDeviceImport->hLock);
+       }
+}
+
+/*
+       Map an import into the CPU
+*/
+IMG_INTERNAL
+PVRSRV_ERROR _DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport)
+{
+       PVRSRV_ERROR eError;
+       DEVMEM_CPU_IMPORT *psCPUImport;
+       IMG_SIZE_T uiMappingLength;
+
+       psCPUImport = &psImport->sCPUImport;
+
+       OSLockAcquire(psCPUImport->hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       psCPUImport->ui32RefCount,
+                                       psCPUImport->ui32RefCount+1);
+
+       if (psCPUImport->ui32RefCount++ == 0)
+       {
+               _DevmemImportStructAcquire(psImport);
+
+#if !defined(__KERNEL__) && defined(SUPPORT_ION)
+               if (psImport->sCPUImport.iDmaBufFd >= 0)
+               {
+                       void *pvCPUVAddr;
+                       int iProt = PROT_READ;
+
+                       iProt |= (psImport->uiFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) ? PROT_WRITE : 0;
+                       /* For ion imports, use the ion fd and mmap facility to map the
+                        * buffer to user space. We can bypass the services bridge in
+                        * this case and possibly save some time.
+                        */
+                       pvCPUVAddr = mmap(NULL, psImport->uiSize, iProt,
+                                         MAP_SHARED, psImport->sCPUImport.iDmaBufFd, 0);
+
+                       if (pvCPUVAddr == MAP_FAILED)
+                       {
+                               eError = PVRSRV_ERROR_DEVICEMEM_MAP_FAILED;
+                               goto failMap;
+                       }
+
+                       psCPUImport->hOSMMapData = pvCPUVAddr;
+                       psCPUImport->pvCPUVAddr = pvCPUVAddr;
+                       uiMappingLength = psImport->uiSize;
+               }
+               else
+#endif
+               {
+                       eError = OSMMapPMR(psImport->hBridge,
+                                                          psImport->hPMR,
+                                                          psImport->uiSize,
+                                                          psImport->uiFlags,
+                                                          &psCPUImport->hOSMMapData,
+                                                          &psCPUImport->pvCPUVAddr,
+                                                          &uiMappingLength);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto failMap;
+                       }
+               }
+
+               /* There is no reason the mapping length is different to the size */
+               PVR_ASSERT(uiMappingLength == psImport->uiSize);
+       }
+       OSLockRelease(psCPUImport->hLock);
+
+       return PVRSRV_OK;
+
+failMap:
+       psCPUImport->ui32RefCount--;
+       _DevmemImportStructRelease(psImport);
+       OSLockRelease(psCPUImport->hLock);
+       PVR_ASSERT(eError != PVRSRV_OK);
+       return eError;
+}
+
+/*
+       Unmap an import from the CPU
+*/
+IMG_INTERNAL
+IMG_VOID _DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport)
+{
+       DEVMEM_CPU_IMPORT *psCPUImport;
+
+       psCPUImport = &psImport->sCPUImport;
+
+       OSLockAcquire(psCPUImport->hLock);
+       DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+                                       __FUNCTION__,
+                                       psImport,
+                                       psCPUImport->ui32RefCount,
+                                       psCPUImport->ui32RefCount-1);
+
+       if (--psCPUImport->ui32RefCount == 0)
+       {
+               /* FIXME: psImport->uiSize is a 64-bit quantity where as the 5th
+                * argument to OSUnmapPMR is a 32-bit quantity on 32-bit systems
+                * hence a compiler warning of implicit cast and loss of data.
+                * Added explicit cast and assert to remove warning.
+                */
+#if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
+               PVR_ASSERT(psImport->uiSize<IMG_UINT32_MAX);
+#endif
+
+#if !defined(__KERNEL__) && defined(SUPPORT_ION)
+               if (psImport->sCPUImport.iDmaBufFd >= 0)
+               {
+                       munmap(psCPUImport->hOSMMapData, psImport->uiSize);
+               }
+               else
+#endif
+               {
+                       OSMUnmapPMR(psImport->hBridge,
+                                               psImport->hPMR,
+                                               psCPUImport->hOSMMapData,
+                                               psCPUImport->pvCPUVAddr,
+                                               (IMG_SIZE_T)psImport->uiSize);
+               }
+
+               OSLockRelease(psCPUImport->hLock);
+
+               _DevmemImportStructRelease(psImport);
+       }
+       else
+       {
+               OSLockRelease(psCPUImport->hLock);
+       }
+}
+
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/dllist.c b/drivers/gpu/rogue_m/services/shared/common/dllist.c
new file mode 100644 (file)
index 0000000..ef6db05
--- /dev/null
@@ -0,0 +1,81 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services implementation of double linked lists
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements a double linked list
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "dllist.h"
+
+#if defined(RGX_FIRMWARE)
+#include "rgxfw_cr_defs.h"
+#include "rgxfw_ctl.h"
+#endif
+
+/* Walk through all the nodes on the list until the end or a callback returns FALSE */
+#if defined(RGX_FIRMWARE)
+RGXFW_COREMEM_CODE
+#endif
+IMG_VOID dllist_foreach_node(PDLLIST_NODE psListHead,
+                                                         PFN_NODE_CALLBACK pfnCallBack,
+                                                         IMG_PVOID pvCallbackData)
+{
+       PDLLIST_NODE psWalker = psListHead->psNextNode;
+       PDLLIST_NODE psNextWalker;
+
+       while (psWalker != psListHead)
+       {
+               /*
+                       The callback function could remove itself from the list
+                       so to avoid NULL pointer deference save the next node pointer
+                       before calling the callback
+               */
+               psNextWalker = psWalker->psNextNode;
+               if (pfnCallBack(psWalker, pvCallbackData))
+               {
+                       psWalker = psNextWalker;
+               }
+               else
+               {
+                       break;
+               }
+       }
+}
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/hash.c b/drivers/gpu/rogue_m/services/shared/common/hash.c
new file mode 100644 (file)
index 0000000..c58c597
--- /dev/null
@@ -0,0 +1,708 @@
+/*************************************************************************/ /*!
+@File
+@Title          Self scaling hash tables.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description 
+   Implements simple self scaling hash tables. Hash collisions are
+   handled by chaining entries together. Hash tables are increased in
+   size when they become more than (50%?) full and decreased in size
+   when less than (25%?) full. Hash tables are never decreased below
+   their initial size.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* include/ */
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+/* services/shared/include/ */
+#include "hash.h"
+
+/* services/client/include/ or services/server/include/ */
+#include "osfunc.h"
+#include "allocmem.h"
+
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#endif
+
+#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)))
+
+/* Each entry in a hash table is placed into a bucket */
+struct _BUCKET_
+{
+       /* the next bucket on the same chain */
+       struct _BUCKET_ *pNext;
+
+       /* entry value */
+       IMG_UINTPTR_T v;
+
+       /* entry key */
+#if defined (WIN32)
+       IMG_UINTPTR_T k[1];
+#else
+       IMG_UINTPTR_T k[];              /* PRQA S 0642 */ /* override dynamic array declaration warning */
+#endif
+};
+typedef struct _BUCKET_ BUCKET;
+
+struct _HASH_TABLE_
+{
+       /* current size of the hash table */
+       IMG_UINT32 uSize;
+
+       /* number of entries currently in the hash table */
+       IMG_UINT32 uCount;
+
+       /* the minimum size that the hash table should be re-sized to */
+       IMG_UINT32 uMinimumSize;
+
+       /* size of key in bytes */
+       IMG_UINT32 uKeySize;
+
+       /* hash function */
+       HASH_FUNC *pfnHashFunc;
+
+       /* key comparison function */
+       HASH_KEY_COMP *pfnKeyComp;
+
+       /* the hash table array */
+       BUCKET **ppBucketTable;
+};
+
+/*************************************************************************/ /*!
+@Function       HASH_Func_Default
+@Description    Hash function intended for hashing keys composed of
+                IMG_UINTPTR_T arrays.
+@Input          uKeySize     The size of the hash key, in bytes.
+@Input          pKey         A pointer to the key to hash.
+@Input          uHashTabLen  The length of the hash table.
+@Return         The hash value.
+*/ /**************************************************************************/
+IMG_INTERNAL 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 = 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;
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Key_Comp_Default
+@Description    Compares keys composed of IMG_UINTPTR_T arrays.
+@Input          uKeySize    The size of the hash key, in bytes.
+@Input          pKey1       Pointer to first hash key to compare.
+@Input          pKey2       Pointer to second hash key to compare.
+@Return         IMG_TRUE    The keys match.
+                IMG_FALSE   The keys don't match.
+*/ /**************************************************************************/
+IMG_INTERNAL 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 = 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;
+}
+
+/*************************************************************************/ /*!
+@Function       _ChainInsert
+@Description    Insert a bucket into the appropriate hash table chain.
+@Input          pBucket       The bucket
+@Input          ppBucketTable The hash table
+@Input          uSize         The size of the hash table
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+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);        /* PRQA S 0432,0541 */ /* ignore dynamic array warning */
+       pBucket->pNext = ppBucketTable[uIndex];
+       ppBucketTable[uIndex] = pBucket;
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       _Rehash
+@Description    Iterate over every entry in an old hash table and
+                rehash into the new table.
+@Input          ppOldTable   The old hash table
+@Input          uOldSize     The size of the old hash table
+@Input          ppNewTable   The new hash table
+@Input          uNewSize     The size of the new hash table
+@Return         None
+*/ /**************************************************************************/
+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;
+}
+
+/*************************************************************************/ /*!
+@Function       _Resize
+@Description    Attempt to resize a hash table, failure to allocate a
+                new larger hash table is not considered a hard failure.
+                We simply continue and allow the table to fill up, the
+                effect is to allow hash chains to become longer.
+@Input          pHash      Hash table to resize.
+@Input          uNewSize   Required table size.
+@Return         IMG_TRUE Success
+                IMG_FALSE Failed
+*/ /**************************************************************************/
+static IMG_BOOL
+_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize)
+{
+       if (uNewSize != pHash->uSize)
+    {
+               BUCKET **ppNewTable;
+        IMG_UINT32 uIndex;
+
+#if defined(__linux__) && defined(__KERNEL__)
+               ppNewTable = OSAllocMemstatMem(sizeof (BUCKET *) * uNewSize);
+#else
+               ppNewTable = OSAllocMem(sizeof (BUCKET *) * uNewSize);
+#endif
+               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)
+               {
+                       /*
+                               If we fail the rehash then there is nothing we can do as we've already
+                               started to modify some of the entries if we just return FALSE here then
+                               we will have dropped some items off the hash table.
+                               The only reason the rehash can fail if is there is bug in another part
+                               of the driver so in reality we should never hit this
+                       */
+                       PVR_ASSERT(IMG_FALSE);
+                       return IMG_FALSE;
+               }
+
+#if defined(__linux__) && defined(__KERNEL__)
+        OSFreeMemstatMem(pHash->ppBucketTable);
+#else
+        OSFreeMem(pHash->ppBucketTable);
+#endif
+        /*not nulling pointer, being reassigned just below*/
+        pHash->ppBucketTable = ppNewTable;
+        pHash->uSize = uNewSize;
+    }
+    return IMG_TRUE;
+}
+
+
+/*************************************************************************/ /*!
+@Function       HASH_Create_Extended
+@Description    Create a self scaling hash table, using the supplied
+                key size, and the supplied hash and key comparsion
+                functions.
+@Input          uInitialLen   Initial and minimum length of the
+                              hash table, where the length refers to the number
+                              of entries in the hash table, not its size in
+                              bytes.
+@Input          uKeySize      The size of the key, in bytes.
+@Input          pfnHashFunc   Pointer to hash function.
+@Input          pfnKeyComp    Pointer to key comparsion function.
+@Return         IMG_NULL or hash table handle.
+*/ /**************************************************************************/
+IMG_INTERNAL 
+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 defined(__linux__) && defined(__KERNEL__)
+       pHash = OSAllocMemstatMem(sizeof(HASH_TABLE));
+#else
+       pHash = OSAllocMem(sizeof(HASH_TABLE));
+#endif
+    if (pHash == IMG_NULL)
+       {
+               return IMG_NULL;
+       }
+
+       pHash->uCount = 0;
+       pHash->uSize = uInitialLen;
+       pHash->uMinimumSize = uInitialLen;
+       pHash->uKeySize = uKeySize;
+       pHash->pfnHashFunc = pfnHashFunc;
+       pHash->pfnKeyComp = pfnKeyComp;
+
+#if defined(__linux__) && defined(__KERNEL__)
+    pHash->ppBucketTable = OSAllocMemstatMem(sizeof (BUCKET *) * pHash->uSize);
+#else
+    pHash->ppBucketTable = OSAllocMem(sizeof (BUCKET *) * pHash->uSize);
+#endif
+    if (pHash->ppBucketTable == IMG_NULL)
+    {
+#if defined(__linux__) && defined(__KERNEL__)
+               OSFreeMemstatMem(pHash);
+#else
+               OSFreeMem(pHash);
+#endif
+               /*not nulling pointer, out of scope*/
+               return IMG_NULL;
+    }
+
+       for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+               pHash->ppBucketTable[uIndex] = IMG_NULL;
+       return pHash;
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Create
+@Description    Create a self scaling hash table with a key
+                consisting of a single IMG_UINTPTR_T, and using
+                the default hash and key comparison functions.
+@Input          uInitialLen   Initial and minimum length of the
+                              hash table, where the length refers to the
+                              number of entries in the hash table, not its size
+                              in bytes.
+@Return         IMG_NULL or hash table handle.
+*/ /**************************************************************************/
+IMG_INTERNAL 
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
+{
+       return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
+               &HASH_Func_Default, &HASH_Key_Comp_Default);
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Delete
+@Description    Delete a hash table created by HASH_Create_Extended or
+                HASH_Create.  All entries in the table must have been
+                removed before calling this function.
+@Input          pHash     Hash table
+@Return         None
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_VOID
+HASH_Delete (HASH_TABLE *pHash)
+{
+       IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__) && !defined(__QNXNTO__)
+       PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+       if (psPVRSRVData != IMG_NULL)
+       {
+               if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+               {
+                       bDoCheck = IMG_FALSE;
+               }
+       }
+#endif
+       if (pHash != IMG_NULL)
+    {
+               if (bDoCheck)
+               {
+                       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"));
+               }
+#if defined(__linux__) && defined(__KERNEL__)
+               OSFreeMemstatMem(pHash->ppBucketTable);
+#else
+               OSFreeMem(pHash->ppBucketTable);
+#endif
+               pHash->ppBucketTable = IMG_NULL;
+#if defined(__linux__) && defined(__KERNEL__)
+               OSFreeMemstatMem(pHash);
+#else
+               OSFreeMem(pHash);
+#endif
+               /*not nulling pointer, copy on stack*/
+    }
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Insert_Extended
+@Description    Insert a key value pair into a hash table created
+                with HASH_Create_Extended.
+@Input          pHash     Hash table
+@Input          pKey      Pointer to the key.
+@Input          v         The value associated with the key.
+@Return         IMG_TRUE  - success
+                IMG_FALSE  - failure
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v)
+{
+       BUCKET *pBucket;
+
+       PVR_ASSERT (pHash != IMG_NULL);
+
+       if (pHash == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter"));
+               return IMG_FALSE;
+       }
+
+#if defined(__linux__) && defined(__KERNEL__)
+       pBucket = OSAllocMemstatMem(sizeof(BUCKET) + pHash->uKeySize);
+#else
+       pBucket = OSAllocMem(sizeof(BUCKET) + pHash->uKeySize);
+#endif
+    if (pBucket == IMG_NULL)
+       {
+               return IMG_FALSE;
+       }
+
+       pBucket->v = v;
+       /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/
+       OSCachedMemCopy(pBucket->k, pKey, pHash->uKeySize);
+       if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
+       {
+#if defined(__linux__) && defined(__KERNEL__)
+               OSFreeMemstatMem(pBucket);
+#else
+               OSFreeMem(pBucket);
+#endif
+               return IMG_FALSE;
+       }
+
+       pHash->uCount++;
+
+       /* check if we need to think about re-balancing */
+       if (pHash->uCount << 1 > pHash->uSize)
+    {
+        /* Ignore the return code from _Resize because the hash table is
+           still in a valid state and although not ideally sized, it is still
+           functional */
+        _Resize (pHash, pHash->uSize << 1);
+    }
+
+
+       return IMG_TRUE;
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Insert
+@Description    Insert a key value pair into a hash table created with
+                HASH_Create.
+@Input          pHash     Hash table
+@Input          k         The key value.
+@Input          v         The value associated with the key.
+@Return         IMG_TRUE - success.
+                IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+       return HASH_Insert_Extended(pHash, &k, v);
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Remove_Extended
+@Description    Remove a key from a hash table created with
+                HASH_Create_Extended.
+@Input          pHash     Hash table
+@Input          pKey      Pointer to key.
+@Return         0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_UINTPTR_T
+HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+       BUCKET **ppBucket;
+       IMG_UINT32 uIndex;
+
+       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 != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+       {
+               /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+               if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+               {
+                       BUCKET *pBucket = *ppBucket;
+                       IMG_UINTPTR_T v = pBucket->v;
+                       (*ppBucket) = pBucket->pNext;
+
+#if defined(__linux__) && defined(__KERNEL__)
+                       OSFreeMemstatMem(pBucket);
+#else
+                       OSFreeMem(pBucket);
+#endif
+                       /*not nulling original pointer, already overwritten*/
+
+                       pHash->uCount--;
+
+                       /* check if we need to think about re-balancing */
+                       if (pHash->uSize > (pHash->uCount << 2) &&
+                pHash->uSize > pHash->uMinimumSize)
+            {
+                /* Ignore the return code from _Resize because the
+                   hash table is still in a valid state and although
+                   not ideally sized, it is still functional */
+                               _Resize (pHash,
+                         PRIVATE_MAX (pHash->uSize >> 1,
+                                      pHash->uMinimumSize));
+            }
+
+                       return v;
+               }
+       }
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Remove
+@Description    Remove a key value pair from a hash table created
+                with HASH_Create.
+@Input          pHash     Hash table
+@Input          k         The key
+@Return         0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_UINTPTR_T
+HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+       return HASH_Remove_Extended(pHash, &k);
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Retrieve_Extended
+@Description    Retrieve a value from a hash table created with
+                HASH_Create_Extended.
+@Input          pHash     Hash table
+@Input          pKey      Pointer to the key.
+@Return         0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_UINTPTR_T
+HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+       BUCKET **ppBucket;
+       IMG_UINT32 uIndex;
+
+       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))
+       {
+               /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+               if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+               {
+                       BUCKET *pBucket = *ppBucket;
+                       IMG_UINTPTR_T v = pBucket->v;
+
+                       return v;
+               }
+       }
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Retrieve
+@Description    Retrieve a value from a hash table created with
+                HASH_Create.
+@Input          pHash     Hash table
+@Input          k         The key
+@Return         0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_UINTPTR_T
+HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+       return HASH_Retrieve_Extended(pHash, &k);
+}
+
+/*************************************************************************/ /*!
+@Function       HASH_Iterate
+@Description    Iterate over every entry in the hash table
+@Input          pHash - Hash table to iterate
+@Input          pfnCallback - Callback to call with the key and data for each
+                                                         entry in the hash table
+@Return         Callback error if any, otherwise PVRSRV_OK
+*/ /**************************************************************************/
+IMG_INTERNAL 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);
+
+            /* The callback might want us to break out early */
+            if (eError != PVRSRV_OK)
+                return eError;
+
+            pBucket = pNextBucket;
+        }
+    }
+    return PVRSRV_OK;
+}
+
+
+#ifdef HASH_TRACE
+/*************************************************************************/ /*!
+@Function       HASH_Dump
+@Description    To dump the contents of a hash table in human readable
+                form.
+@Input          pHash     Hash table
+*/ /**************************************************************************/
+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/gpu/rogue_m/services/shared/common/mem_utils.c b/drivers/gpu/rogue_m/services/shared/common/mem_utils.c
new file mode 100644 (file)
index 0000000..e206071
--- /dev/null
@@ -0,0 +1,257 @@
+/*************************************************************************/ /*!
+@File
+@Title          Memory manipulation functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Memory related functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#if defined(__KERNEL__)
+#include "osfunc.h"
+#include <linux/string.h>
+#else
+#include "services.h"
+#include <string.h>
+#endif
+
+#if (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_SAFE_MEMSETCPY)) && !defined(__QNXNTO__)
+
+#define ZERO_BUF_SIZE 1024
+
+#if defined(__GNUC__)
+#define PVRSRV_MEM_ALIGN __attribute__ ((aligned (0x8)))
+#define PVRSRV_MEM_64BIT_ALIGN_MASK (0x7)
+#define PVRSRV_MEM_32BIT_ALIGN_MASK (0x3)
+#else
+#error "PVRSRV Alignment macros need to be defined for this compiler"
+#endif
+
+/******************************************************************************
+ Function Name      : OSDeviceMemCopy / PVRSRVDeviceMemCopy
+ Inputs             : pvDst - pointer to the destination memory region
+                      pvSrc - pointer to the source memory region
+                      uiSize - size of the memory region that will be copied
+ Outputs            :
+ Returns            :
+ Description        : This is a counterpart of standard memcpy function for
+                      uncached memory. The reason for this function is that
+                      when uncached memory is used and the pointers are not
+                      64-bit aligned on Aarch64 architecture a memory
+                      exception will be thrown. This applies both to user and
+                      kernel space.
+******************************************************************************/
+IMG_EXPORT IMG_VOID PVRSRVDeviceMemCopy(
+        IMG_VOID* pvDst,
+        const IMG_VOID* pvSrc,
+        IMG_SIZE_T uiSize)
+{
+       /* Use volatile to avoid compiler optimisations */
+       volatile IMG_BYTE * pbySrc = (IMG_BYTE*)pvSrc;
+       volatile IMG_BYTE * pbyDst = (IMG_BYTE*)pvDst;
+       IMG_SIZE_T uiTailSize = uiSize;
+
+       /* If both pointers have same alignment we can optimise. */
+       if (((IMG_UINTPTR_T)pbySrc & PVRSRV_MEM_64BIT_ALIGN_MASK)
+               == ((IMG_UINTPTR_T)pbyDst & PVRSRV_MEM_64BIT_ALIGN_MASK))
+       {
+               IMG_SIZE_T uiAlignedSize;
+               IMG_UINT uiHeadSize;
+
+               uiHeadSize = (sizeof(void *)
+                       - ((IMG_UINTPTR_T)pbySrc & PVRSRV_MEM_64BIT_ALIGN_MASK))
+                       & PVRSRV_MEM_64BIT_ALIGN_MASK;
+
+               /* For 64bit aligned pointers we will almost always (not if uiSize is 0)
+                * go in and use memcpy if the size is large enough. For other aligned
+                * pointers if size is large enough we will copy first few bytes to
+                * align those pointers to 64bit then use memcpy and after that copy
+                * remaining bytes.
+                * If uiSize is less then uiHeadSize we will skip to byte-by-byte
+                * copy since we can't use memcpy in such case. */
+               if (uiSize > uiHeadSize)
+               {
+                       uiSize -= uiHeadSize;
+                       uiTailSize = uiSize & PVRSRV_MEM_64BIT_ALIGN_MASK;
+                       uiAlignedSize = uiSize - uiTailSize;
+
+                       /* Copy few leading bytes to align pointer to 64bit boundary. */
+                       while (uiHeadSize--)
+                       {
+                               *pbyDst++ = *pbySrc++;
+                       }
+
+                       /* here pointers are already 64bit aligned so we can use memcpy. */
+                       memcpy((IMG_VOID*)pbyDst, (IMG_VOID*)pbySrc, uiAlignedSize);
+
+                       /* skip over copied data */
+                       pbyDst += uiAlignedSize;
+                       pbySrc += uiAlignedSize;
+               }
+       }
+       /* If pointers are 32bit aligned but not aligned in relation to each
+        * other.*/
+       else if ((((IMG_UINTPTR_T)pbySrc | (IMG_UINTPTR_T)pbyDst)
+               & PVRSRV_MEM_32BIT_ALIGN_MASK) == 0)
+       {
+               volatile IMG_UINT32 * pui32Src = (IMG_UINT32*)pbySrc;
+               volatile IMG_UINT32 * pui32Dst = (IMG_UINT32*)pbyDst;
+               IMG_SIZE_T uiAlignedSize;
+
+               uiTailSize = uiSize & PVRSRV_MEM_32BIT_ALIGN_MASK;
+               uiAlignedSize = uiSize - uiTailSize;
+
+               /* do the 4 byte copy */
+               uiSize = uiSize >> 2;
+               while (uiSize--)
+               {
+                       *pui32Dst++ = *pui32Src++;
+               }
+
+               pbyDst += uiAlignedSize;
+               pbySrc += uiAlignedSize;
+       }
+
+       /* Copy either remaining memory if optimisation was performed but
+        * size was not aligned or all memory if we need to. */
+       while (uiTailSize--)
+       {
+               *pbyDst++ = *pbySrc++;
+       }
+
+}
+
+/******************************************************************************
+ Function Name      : OSDeviceMemSet / PVRSRVDeviceMemSet
+ Inputs             : pvDest - pointer to destination memory
+                      ui8Value - the 'set' value
+                      uiSize - size of the memory block
+ Outputs            :
+ Returns            :
+ Description        : This is a counterpart of standard memset function for
+                      uncached memory. The reason for this function is that
+                      when uncached memory is used and the pointer is not
+                      64-bit aligned on Aarch64 architecture an memory
+                      exception will be thrown. This applies both to user and
+                      kernel space.
+******************************************************************************/
+IMG_EXPORT IMG_VOID PVRSRVDeviceMemSet(
+        IMG_VOID *pvDest,
+        IMG_UINT8 ui8Value,
+        IMG_SIZE_T uiSize)
+{
+       /* Use volatile to avoid compiler optimisations */
+       volatile IMG_BYTE * pbyDst = (IMG_BYTE*)pvDest;
+       static IMG_BYTE gZeroBuf[ZERO_BUF_SIZE] PVRSRV_MEM_ALIGN = { 0 };
+
+       /* Run workaround if one of the address or size is not aligned, or
+        * we are zeroing */
+       if ((ui8Value == 0) || ((((IMG_SIZE_T)pbyDst | uiSize) & PVRSRV_MEM_64BIT_ALIGN_MASK) != 0))
+       {
+               IMG_UINT32 uiTailSize;
+
+               /* Buffer address unaligned */
+               if ((IMG_SIZE_T)pbyDst & PVRSRV_MEM_64BIT_ALIGN_MASK)
+               {
+                       /* Increment the buffer pointer */
+                       for (; uiSize > 0 && ((IMG_SIZE_T)pbyDst & PVRSRV_MEM_64BIT_ALIGN_MASK); uiSize--)
+                       {
+                               *pbyDst++ = ui8Value;
+                       }
+                       /* Did loop stop because size is zero? */
+                       if (uiSize == 0) return;
+               }
+
+               /* Set the remaining part of the buffer */
+               if (ui8Value)
+               {
+                       /* Non-zero set */
+                       uiTailSize = (uiSize & PVRSRV_MEM_64BIT_ALIGN_MASK);
+
+                       memset((IMG_VOID*) pbyDst, (IMG_INT) ui8Value, (size_t) uiSize-uiTailSize);
+                       pbyDst += uiSize-uiTailSize;
+               }
+               else
+               {
+                       /* Zero set */
+                       uiTailSize = (uiSize & PVRSRV_MEM_64BIT_ALIGN_MASK);
+                       uiSize -= uiTailSize;
+
+                       while (uiSize > 1024)
+                       {
+                               memcpy((IMG_VOID*) pbyDst, gZeroBuf, (size_t) ZERO_BUF_SIZE);
+                               pbyDst +=ZERO_BUF_SIZE;
+                               uiSize -= ZERO_BUF_SIZE;
+                       }
+                       memcpy((IMG_VOID*) pbyDst, gZeroBuf, (size_t) uiSize);
+                       pbyDst += uiSize;
+               }
+
+               /* Handle any tail bytes, loop skipped in tail is 0 */
+               for (; uiTailSize > 0; uiTailSize--)
+               {
+                       *pbyDst++ = ui8Value;
+               }
+       }
+       /* Alignment fine, non-zero set, no need to work around device memory
+        * use with ARM64 libc */
+       else
+       {
+               memset(pvDest, (IMG_INT) ui8Value, (size_t) uiSize);
+       }
+}
+
+#else /* (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_SAFE_MEMSETCPY)) && !defined(__QNXNTO__) */
+
+IMG_EXPORT IMG_VOID PVRSRVDeviceMemCopy(
+        IMG_VOID*       pvDst,
+        const IMG_VOID* pvSrc,
+        IMG_SIZE_T      uiSize)
+{
+       memcpy(pvDst, pvSrc, uiSize);
+}
+
+IMG_EXPORT IMG_VOID PVRSRVDeviceMemSet(
+        IMG_VOID *pvDest,
+        IMG_UINT8 ui8Value,
+        IMG_SIZE_T uiSize)
+{
+       memset(pvDest, ui8Value, uiSize);
+}
+
+#endif /* (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_SAFE_MEMSETCPY)) && !defined(__QNXNTO__) */
diff --git a/drivers/gpu/rogue_m/services/shared/common/ra.c b/drivers/gpu/rogue_m/services/shared/common/ra.c
new file mode 100644 (file)
index 0000000..5a0f8d2
--- /dev/null
@@ -0,0 +1,1357 @@
+/*************************************************************************/ /*!
+@File
+@Title          Resource Allocator
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+@Description
+ Implements generic resource allocation. The resource
+ allocator was originally intended to manage address spaces.  In
+ practice the resource allocator is generic and can manage arbitrary
+ sets of integers.
+
+ Resources are allocated from arenas. Arena's can be created with an
+ initial span of resources. Further resources spans can be added to
+ arenas. A call back mechanism allows an arena to request further
+ resource spans on demand.
+
+ Each arena maintains an ordered list of resource segments each
+ described by a boundary tag. Each boundary tag describes a segment
+ of resources which are either 'free', available for allocation, or
+ 'busy' currently allocated. Adjacent 'free' segments are always
+ coallesced to avoid fragmentation.
+
+ For allocation, all 'free' segments are kept on lists of 'free'
+ segments in a table index by pvr_log2(segment size). ie Each table index
+ n holds 'free' segments in the size range 2^n -> 2^(n+1) - 1.
+
+ Allocation policy is based on an *almost* good fit strategy. 
+
+ Allocated segments are inserted into a self scaling hash table which
+ maps the base resource of the span to the relevant boundary
+ tag. This allows the code to get back to the bounary tag without
+ exporting explicit boundary tag references through the API.
+
+ Each arena has an associated quantum size, all allocations from the
+ arena are made in multiples of the basic quantum.
+
+ On resource exhaustion in an arena, a callback if provided will be
+ used to request further resources. Resouces spans allocated by the
+ callback mechanism will be returned when freed (through one of the
+ two callbacks).
+*/ /**************************************************************************/
+
+/* Issues:
+ * - flags, flags are passed into the resource allocator but are not currently used.
+ * - determination, of import size, is currently braindead.
+ * - debug code should be moved out to own module and #ifdef'd
+ */
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "uniq_key_splay_tree.h"
+
+#include "hash.h"
+#include "ra.h"
+
+#include "osfunc.h"
+#include "allocmem.h"
+#include "lock.h"
+
+/* The initial, and minimum size of the live address -> boundary tag
+   structure hash table. The value 64 is a fairly arbitrary
+   choice. The hash table resizes on demand so the value choosen is
+   not critical. */
+#define MINIMUM_HASH_SIZE (64)
+
+
+/* #define RA_VALIDATE */
+
+#if defined(__KLOCWORK__)
+  /* make sure Klocworks analyse all the code (including the debug one) */
+  #if !defined(RA_VALIDATE)
+    #define RA_VALIDATE
+  #endif
+#endif
+
+#if (!defined(PVRSRV_NEED_PVR_ASSERT)) || (!defined(RA_VALIDATE))
+  /* Disable the asserts unless explicitly told otherwise.  They slow the driver
+     too much for other people */
+
+  #undef PVR_ASSERT
+  /* let's use a macro that really do not do anything when compiling in release
+     mode! */
+  #define PVR_ASSERT(x)
+#endif
+
+/* boundary tags, used to describe a resource segment */
+struct _BT_
+{
+       enum bt_type
+       {
+               btt_free,                               /* free resource segment */
+               btt_live                                /* allocated resource segment */
+       } type;
+
+       unsigned int is_leftmost;
+       unsigned int is_rightmost;
+       unsigned int free_import;
+
+       /* The base resource and extent of this segment */
+       RA_BASE_T base;
+       RA_LENGTH_T uSize;
+
+       /* doubly linked ordered list of all segments within the arena */
+       struct _BT_ *pNextSegment;
+       struct _BT_ *pPrevSegment;
+
+       /* doubly linked un-ordered list of free segments with the same flags. */
+       struct _BT_ * next_free;
+       struct _BT_ * prev_free;
+       
+       /* a user reference associated with this span, user references are
+        * currently only provided in the callback mechanism */
+    IMG_HANDLE hPriv;
+
+    /* Flags to match on this span */
+    IMG_UINT32 uFlags;
+
+};
+typedef struct _BT_ BT;
+
+
+/* resource allocation arena */
+struct _RA_ARENA_
+{
+       /* arena name for diagnostics output */
+       IMG_CHAR *name;
+
+       /* allocations within this arena are quantum sized */
+       RA_LENGTH_T uQuantum;
+
+       /* import interface, if provided */
+       IMG_BOOL (*pImportAlloc)(RA_PERARENA_HANDLE h,
+                                                        RA_LENGTH_T uSize,
+                                                        IMG_UINT32 uFlags,
+                                                        RA_BASE_T *pBase,
+                                                        RA_LENGTH_T *pActualSize,
+                             RA_PERISPAN_HANDLE *phPriv);
+       IMG_VOID (*pImportFree) (RA_PERARENA_HANDLE,
+                             RA_BASE_T,
+                             RA_PERISPAN_HANDLE hPriv);
+
+       /* arbitrary handle provided by arena owner to be passed into the
+        * import alloc and free hooks */
+       IMG_VOID *pImportHandle;
+
+       IMG_PSPLAY_TREE per_flags_buckets;
+       
+       /* resource segment list */
+       BT *pHeadSegment;
+
+       /* segment address to boundary tag hash table */
+       HASH_TABLE *pSegmentHash;
+
+       /* Lock for this arena */
+       POS_LOCK hLock;
+
+       /* LockClass of this arena. This is used within lockdep to decide if a
+        * recursive call sequence with the same lock class is allowed or not. */
+       IMG_UINT32 ui32LockClass;
+
+       /* If TRUE, imports will not be split up. Allocations will always get their
+        * own import
+        */
+       IMG_BOOL bNoSplit;
+};
+
+/*************************************************************************/ /*!
+@Function       _RequestAllocFail
+@Description    Default callback allocator used if no callback is
+                specified, always fails to allocate further resources to the
+                arena.
+@Input          _h - callback handle
+@Input          _uSize - requested allocation size
+@Output         _pActualSize - actual allocation size
+@Input          _pRef - user reference
+@Input          _uflags - allocation flags
+@Input          _pBase - receives allocated base
+@Return         IMG_FALSE, this function always fails to allocate.
+*/ /**************************************************************************/
+static IMG_BOOL
+_RequestAllocFail (RA_PERARENA_HANDLE _h,
+                   RA_LENGTH_T _uSize,
+                   IMG_UINT32 _uFlags,
+                   RA_BASE_T *_pBase,
+                   RA_LENGTH_T *_pActualSize,
+                   RA_PERISPAN_HANDLE *_phPriv)
+{
+       PVR_UNREFERENCED_PARAMETER (_h);
+       PVR_UNREFERENCED_PARAMETER (_uSize);
+       PVR_UNREFERENCED_PARAMETER (_pActualSize);
+       PVR_UNREFERENCED_PARAMETER (_phPriv);
+       PVR_UNREFERENCED_PARAMETER (_uFlags);
+       PVR_UNREFERENCED_PARAMETER (_pBase);
+
+       return IMG_FALSE;
+}
+
+
+#if defined (HAS_BUILTIN_CTZLL)
+    /* make sure to trigger an error if someone change the buckets or the bHasEltsMapping size
+       the bHasEltsMapping is used to quickly determine the smallest bucket containing elements.
+       therefore it must have at least as many bits has the buckets array have buckets. The RA
+       implementation actually uses one more bit. */
+    BLD_ASSERT((sizeof(((IMG_PSPLAY_TREE) 0)->buckets) / sizeof(((IMG_PSPLAY_TREE) 0)->buckets[0]))
+                          < 8 * sizeof(((IMG_PSPLAY_TREE) 0)->bHasEltsMapping), ra_c);
+#endif 
+
+
+/*************************************************************************/ /*!
+@Function       pvr_log2
+@Description    Computes the floor of the log base 2 of a unsigned integer
+@Input          n       Unsigned integer
+@Return         Floor(Log2(n))
+*/ /**************************************************************************/
+#if defined(__GNUC__)
+/* make sure to trigger a problem if someone changes the RA_LENGTH_T type
+   indeed the __builtin_clzll is for unsigned long long variables.
+
+   if someone changes RA_LENGTH to unsigned long, then use __builtin_clzl
+   if it changes to unsigned int, use __builtin_clz
+
+   if it changes for something bigger than unsigned long long, 
+   then revert the pvr_log2 to the classic implementation */
+BLD_ASSERT(sizeof(RA_LENGTH_T) == sizeof(unsigned long long), ra_c);
+
+static inline IMG_UINT32 pvr_log2(RA_LENGTH_T n)
+{
+       PVR_ASSERT( n != 0 ); /* Log2 is not defined on 0 */
+
+       return (8 * sizeof(RA_LENGTH_T)) - 1 - __builtin_clzll(n);
+}
+#else
+static IMG_UINT32
+pvr_log2 (RA_LENGTH_T n)
+{
+       IMG_UINT32 l = 0;
+
+       PVR_ASSERT( n != 0 ); /* Log2 is not defined on 0 */
+
+       n>>=1;
+       while (n>0)
+       {
+               n>>=1;
+               l++;
+       }
+       return l;
+}
+#endif
+
+
+#if defined(RA_VALIDATE)
+/*************************************************************************/ /*!
+@Function       _IsInSegmentList
+@Description    Tests if a BT is in the segment list.
+@Input          pArena           The arena.
+@Input          pBT              The boundary tag to look for.
+@Return         IMG_FALSE  BT was not in the arena's segment list.
+                IMG_TRUE   BT was in the arena's segment list.
+*/ /**************************************************************************/
+static IMG_BOOL
+_IsInSegmentList (RA_ARENA *pArena,
+                  BT *pBT)
+{
+       BT*  pBTScan;
+
+       PVR_ASSERT (pArena != IMG_NULL);
+       PVR_ASSERT (pBT != IMG_NULL);
+
+       /* Walk the segment list until we see the BT pointer... */
+       pBTScan = pArena->pHeadSegment;
+       while (pBTScan != IMG_NULL  &&  pBTScan != pBT)
+       {
+               pBTScan = pBTScan->pNextSegment;
+       }
+
+       /* Test if we found it and then return */
+       return (pBTScan == pBT);
+}
+
+/*************************************************************************/ /*!
+@Function       _IsInFreeList
+@Description    Tests if a BT is in the free list.
+@Input          pArena           The arena.
+@Input          pBT              The boundary tag to look for.
+@Return         IMG_FALSE  BT was not in the arena's free list.
+                IMG_TRUE   BT was in the arena's free list.
+*/ /**************************************************************************/
+static IMG_BOOL
+_IsInFreeList (RA_ARENA *pArena,
+               BT *pBT)
+{
+       BT*  pBTScan;
+       IMG_UINT32  uIndex;
+
+       PVR_ASSERT (pArena != IMG_NULL);
+       PVR_ASSERT (pBT != IMG_NULL);
+
+       /* Look for the free list that holds BTs of this size... */
+       uIndex  = pvr_log2 (pBT->uSize);
+       PVR_ASSERT (uIndex < FREE_TABLE_LIMIT);
+
+       pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets);
+       if ((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->flags != pBT->uFlags))
+       {
+               return 0;
+       }
+       else
+       {
+               pBTScan = pArena->per_flags_buckets->buckets[uIndex];
+               while (pBTScan != IMG_NULL  &&  pBTScan != pBT)
+               {
+                       pBTScan = pBTScan->next_free;
+               }
+
+               /* Test if we found it and then return */
+               return (pBTScan == pBT);
+       }
+}
+
+/* is_arena_valid should only be used in debug mode.
+   it checks that some properties an arena must have are verified */
+static int is_arena_valid(struct _RA_ARENA_ * arena)
+{
+       struct _BT_ * chunk;
+#if defined(HAS_BUILTIN_CTZLL)
+       unsigned int i;
+#endif
+
+       for (chunk = arena->pHeadSegment; chunk != NULL; chunk = chunk->pNextSegment)
+       {
+               /* if next segment is NULL, then it must be a rightmost */
+               PVR_ASSERT((chunk->pNextSegment != NULL) || (chunk->is_rightmost));
+               /* if prev segment is NULL, then it must be a leftmost */
+               PVR_ASSERT((chunk->pPrevSegment != NULL) || (chunk->is_leftmost));
+
+               if (chunk->type == btt_free)
+               {
+                       /* checks the correctness of the type field */
+                       PVR_ASSERT(_IsInFreeList(arena, chunk));
+
+                   /* check that there can't be two consecutive free chunks.
+                      Indeed, instead of having two consecutive free chunks,
+                          there should be only one that span the size of the two. */
+                       PVR_ASSERT((chunk->is_leftmost) || (chunk->pPrevSegment->type != btt_free));
+                       PVR_ASSERT((chunk->is_rightmost) || (chunk->pNextSegment->type != btt_free));
+               }
+               else
+               {
+                       /* checks the correctness of the type field */
+                       PVR_ASSERT(!_IsInFreeList(arena, chunk));
+               }
+
+               PVR_ASSERT((chunk->is_leftmost) || (chunk->pPrevSegment->base + chunk->pPrevSegment->uSize == chunk->base));
+               PVR_ASSERT((chunk->is_rightmost) || (chunk->base + chunk->uSize == chunk->pNextSegment->base));
+
+               /* all segments of the same imports must have the same flags ... */
+               PVR_ASSERT((chunk->is_rightmost) || (chunk->uFlags == chunk->pNextSegment->uFlags));
+               /* ... and the same import handle */
+               PVR_ASSERT((chunk->is_rightmost) || (chunk->hPriv == chunk->pNextSegment->hPriv));
+
+
+               /* if a free chunk spans a whole import, then it must be an 'not to free import'.
+                  Otherwise it should have been freed. */
+               PVR_ASSERT((!chunk->is_leftmost) || (!chunk->is_rightmost) || (chunk->type == btt_live) || (!chunk->free_import));
+       }
+
+#if defined(HAS_BUILTIN_CTZLL)
+    if (arena->per_flags_buckets != NULL)
+       {
+               for (i = 0; i < FREE_TABLE_LIMIT; ++i)
+               {
+                       /* verify that the bHasEltsMapping is correct for this flags bucket */
+                       PVR_ASSERT( 
+                               ((arena->per_flags_buckets->buckets[i] == NULL) &&
+                                (( (arena->per_flags_buckets->bHasEltsMapping & ((IMG_ELTS_MAPPINGS) 1 << i)) == 0)))
+                               ||
+                               ((arena->per_flags_buckets->buckets[i] != NULL) &&
+                                ((  (arena->per_flags_buckets->bHasEltsMapping & ((IMG_ELTS_MAPPINGS) 1 << i)) != 0)))
+                               );              
+               }
+       }
+#endif 
+
+       /* if arena was not valid, one of the assert before should have triggered */
+       return 1;
+}
+#endif
+/*************************************************************************/ /*!
+@Function       _SegmentListInsertAfter
+@Description    Insert a boundary tag into an arena segment list after a
+                specified boundary tag.
+@Input          pInsertionPoint  The insertion point.
+@Input          pBT              The boundary tag to insert.
+@Return         PVRSRV_OK (doesn't fail)
+*/ /**************************************************************************/
+static INLINE PVRSRV_ERROR
+_SegmentListInsertAfter (BT *pInsertionPoint,
+                                                BT *pBT)
+{
+       PVR_ASSERT (pBT != IMG_NULL);
+       PVR_ASSERT (pInsertionPoint != IMG_NULL);
+
+       pBT->pNextSegment = pInsertionPoint->pNextSegment;
+       pBT->pPrevSegment = pInsertionPoint;
+       if (pInsertionPoint->pNextSegment != IMG_NULL)
+       {
+               pInsertionPoint->pNextSegment->pPrevSegment = pBT;
+       }
+       pInsertionPoint->pNextSegment = pBT;
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       _SegmentListInsert
+@Description    Insert a boundary tag into an arena segment list
+@Input          pArena    The arena.
+@Input          pBT       The boundary tag to insert.
+@Return         PVRSRV_OK (doesn't fail)
+*/ /**************************************************************************/
+static INLINE PVRSRV_ERROR
+_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       PVR_ASSERT (!_IsInSegmentList(pArena, pBT));
+
+       /* insert into the segment chain */
+       pBT->pNextSegment = pArena->pHeadSegment;
+       pArena->pHeadSegment = pBT;
+       if (pBT->pNextSegment != NULL)
+       {
+               pBT->pNextSegment->pPrevSegment = pBT;
+       }
+
+       pBT->pPrevSegment = NULL;
+
+       return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       _SegmentListRemove
+@Description    Remove a boundary tag from an arena segment list.
+@Input          pArena    The arena.
+@Input          pBT       The boundary tag to remove.
+*/ /**************************************************************************/
+static IMG_VOID
+_SegmentListRemove (RA_ARENA *pArena, BT *pBT)
+{
+       PVR_ASSERT (_IsInSegmentList(pArena, pBT));
+       
+       if (pBT->pPrevSegment == IMG_NULL)
+               pArena->pHeadSegment = pBT->pNextSegment;
+       else
+               pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
+
+       if (pBT->pNextSegment != IMG_NULL)
+               pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _BuildBT
+@Description    Construct a boundary tag for a free segment.
+@Input          base     The base of the resource segment.
+@Input          uSize    The extent of the resouce segment.
+@Input          uFlags   The flags to give to the boundary tag
+@Return         Boundary tag or NULL
+*/ /**************************************************************************/
+static BT *
+_BuildBT (RA_BASE_T base,
+          RA_LENGTH_T uSize,
+          RA_FLAGS_T uFlags
+          )
+{
+       BT *pBT;
+
+       pBT = OSAllocMem(sizeof(BT));
+    if (pBT == IMG_NULL)
+       {
+               return IMG_NULL;
+       }
+
+       OSCachedMemSet(pBT, 0, sizeof(BT));
+
+       pBT->is_leftmost = 1;
+       pBT->is_rightmost = 1;
+       pBT->type = btt_live;
+       pBT->base = base;
+       pBT->uSize = uSize;
+    pBT->uFlags = uFlags;
+       pBT->free_import = 0;
+
+       return pBT;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _SegmentSplit
+@Description    Split a segment into two, maintain the arena segment list. The
+                boundary tag should not be in the free table. Neither the
+                original or the new neighbour bounary tag will be in the free
+                table.
+@Input          pBT       The boundary tag to split.
+@Input          uSize     The required segment size of boundary tag after
+                          splitting.
+@Return         New neighbour boundary tag or NULL.
+*/ /**************************************************************************/
+static BT *
+_SegmentSplit (BT *pBT, RA_LENGTH_T uSize)
+{
+       BT *pNeighbour;
+
+       pNeighbour = _BuildBT(pBT->base + uSize, pBT->uSize - uSize, pBT->uFlags);
+    if (pNeighbour == IMG_NULL)
+    {
+        return IMG_NULL;
+    }
+
+       _SegmentListInsertAfter(pBT, pNeighbour);
+
+       pNeighbour->is_leftmost = 0;
+       pNeighbour->is_rightmost = pBT->is_rightmost;
+       pNeighbour->free_import = pBT->free_import;
+       pBT->is_rightmost = 0;
+       pNeighbour->hPriv = pBT->hPriv;
+       pBT->uSize = uSize;
+       pNeighbour->uFlags = pBT->uFlags;
+
+       return pNeighbour;
+}
+
+/*************************************************************************/ /*!
+@Function       _FreeListInsert
+@Description    Insert a boundary tag into an arena free table.
+@Input          pArena    The arena.
+@Input          pBT       The boundary tag.
+*/ /**************************************************************************/
+static IMG_VOID
+_FreeListInsert (RA_ARENA *pArena, BT *pBT)
+{
+       IMG_UINT32 uIndex;
+       uIndex = pvr_log2 (pBT->uSize);
+
+       PVR_ASSERT (uIndex < FREE_TABLE_LIMIT);
+       PVR_ASSERT (!_IsInFreeList(pArena, pBT));
+
+       pBT->type = btt_free;
+
+       pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets);
+       /* the flags item in the splay tree must have been created before-hand by
+          _InsertResource */
+       PVR_ASSERT(pArena->per_flags_buckets != NULL);
+       PVR_ASSERT(pArena->per_flags_buckets->buckets != NULL);
+
+       pBT->next_free = pArena->per_flags_buckets->buckets[uIndex];
+       if (pBT->next_free != NULL)
+       {
+               pBT->next_free->prev_free = pBT;
+       }
+       pBT->prev_free = NULL;
+       pArena->per_flags_buckets->buckets[uIndex] = pBT;
+
+#if defined(HAS_BUILTIN_CTZLL)
+       /* tells that bucket[index] now contains elements */
+    pArena->per_flags_buckets->bHasEltsMapping |= ((IMG_ELTS_MAPPINGS) 1 << uIndex);
+#endif
+}
+
+/*************************************************************************/ /*!
+@Function       _FreeListRemove
+@Description    Remove a boundary tag from an arena free table.
+@Input          pArena    The arena.
+@Input          pBT       The boundary tag.
+*/ /**************************************************************************/
+static IMG_VOID
+_FreeListRemove (RA_ARENA *pArena, BT *pBT)
+{
+       IMG_UINT32 uIndex;
+       uIndex = pvr_log2 (pBT->uSize);
+
+       PVR_ASSERT (uIndex < FREE_TABLE_LIMIT);
+       PVR_ASSERT (_IsInFreeList(pArena, pBT));
+
+       if (pBT->next_free != NULL)
+       {
+               pBT->next_free->prev_free = pBT->prev_free;
+       }
+
+       if (pBT->prev_free != NULL)
+       {
+               pBT->prev_free->next_free = pBT->next_free;
+       }
+       else
+       {
+               pArena->per_flags_buckets = PVRSRVSplay(pBT->uFlags, pArena->per_flags_buckets);
+               /* the flags item in the splay tree must have already been created
+                  (otherwise how could there be a segment with these flags */
+               PVR_ASSERT(pArena->per_flags_buckets != NULL);
+               PVR_ASSERT(pArena->per_flags_buckets->buckets != NULL);
+
+               pArena->per_flags_buckets->buckets[uIndex] = pBT->next_free;
+#if defined(HAS_BUILTIN_CTZLL)
+               if (pArena->per_flags_buckets->buckets[uIndex] == NULL)
+               {
+                       /* there is no more elements in this bucket. Update the mapping. */
+                       pArena->per_flags_buckets->bHasEltsMapping &= ~((IMG_ELTS_MAPPINGS) 1 << uIndex);
+               }
+#endif
+       }
+       
+
+       PVR_ASSERT (!_IsInFreeList(pArena, pBT));
+       pBT->type = btt_live;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _InsertResource
+@Description    Add a free resource segment to an arena.
+@Input          pArena    The arena.
+@Input          base      The base of the resource segment.
+@Input          uSize     The extent of the resource segment.
+@Input          uFlags    The flags of the new resources.
+@Return         New bucket pointer
+                IMG_NULL on failure
+*/ /**************************************************************************/
+static BT *
+_InsertResource (RA_ARENA *pArena,
+                 RA_BASE_T base,
+                 RA_LENGTH_T uSize,
+                 RA_FLAGS_T uFlags
+                 )
+{
+       BT *pBT;
+       PVR_ASSERT (pArena!=IMG_NULL);
+
+       pBT = _BuildBT (base, uSize, uFlags);
+
+       if (pBT != IMG_NULL)
+       {
+               IMG_PSPLAY_TREE tmp = PVRSRVInsert(pBT->uFlags, pArena->per_flags_buckets);
+               if (tmp == NULL)
+               {
+                       OSFreeMem(pBT);
+                       return NULL;
+               }
+               
+               pArena->per_flags_buckets = tmp;
+               _SegmentListInsert (pArena, pBT);
+               _FreeListInsert (pArena, pBT);
+       }
+       return pBT;
+}
+
+/*************************************************************************/ /*!
+@Function       _InsertResourceSpan
+@Description    Add a free resource span to an arena, marked for free_import.
+@Input          pArena    The arena.
+@Input          base      The base of the resource segment.
+@Input          uSize     The extent of the resource segment.
+@Return         The boundary tag representing the free resource segment,
+                or IMG_NULL on failure.
+*/ /**************************************************************************/
+static INLINE BT *
+_InsertResourceSpan (RA_ARENA *pArena,
+                     RA_BASE_T base,
+                     RA_LENGTH_T uSize,
+                     RA_FLAGS_T uFlags)
+{
+       BT *pBT = _InsertResource(pArena, base, uSize, uFlags);
+       if (pBT != NULL)
+       {
+               pBT->free_import = 1;
+       }
+       return pBT;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _RemoveResourceSpan
+@Description    Frees a resource span from an arena, returning the imported
+                               span via the callback.
+@Input          pArena     The arena.
+@Input          pBT        The boundary tag to free.
+@Return         IMG_FALSE failure - span was still in use
+                IMG_TRUE  success - span was removed and returned
+*/ /**************************************************************************/
+static INLINE IMG_BOOL
+_RemoveResourceSpan (RA_ARENA *pArena, BT *pBT)
+{
+       PVR_ASSERT (pArena!=IMG_NULL);
+       PVR_ASSERT (pBT!=IMG_NULL);
+
+       if (pBT->free_import &&
+               pBT->is_leftmost &&
+               pBT->is_rightmost)
+       {
+               _SegmentListRemove (pArena, pBT);
+               pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->hPriv);
+               OSFreeMem(pBT);
+
+               return IMG_TRUE;
+       }
+
+
+       return IMG_FALSE;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _FreeBT
+@Description    Free a boundary tag taking care of the segment list and the
+                boundary tag free table.
+@Input          pArena     The arena.
+@Input          pBT        The boundary tag to free.
+*/ /**************************************************************************/
+static IMG_VOID
+_FreeBT (RA_ARENA *pArena, BT *pBT)
+{
+       BT *pNeighbour;
+
+       PVR_ASSERT (pArena!=IMG_NULL);
+       PVR_ASSERT (pBT!=IMG_NULL);
+       PVR_ASSERT (!_IsInFreeList(pArena, pBT));
+
+       /* try and coalesce with left neighbour */
+       pNeighbour = pBT->pPrevSegment;
+       if ((!pBT->is_leftmost) && (pNeighbour->type == btt_free))
+       {
+               /* Sanity check. */
+               PVR_ASSERT(pNeighbour->base + pNeighbour->uSize == pBT->base);
+
+               _FreeListRemove (pArena, pNeighbour);
+               _SegmentListRemove (pArena, pNeighbour);
+               pBT->base = pNeighbour->base;
+
+               pBT->uSize += pNeighbour->uSize;
+               pBT->is_leftmost = pNeighbour->is_leftmost;
+        OSFreeMem(pNeighbour);
+       }
+
+       /* try to coalesce with right neighbour */
+       pNeighbour = pBT->pNextSegment;
+       if ((!pBT->is_rightmost) && (pNeighbour->type == btt_free))
+       {
+               /* sanity check */
+               PVR_ASSERT(pBT->base + pBT->uSize == pNeighbour->base);
+
+               _FreeListRemove (pArena, pNeighbour);
+               _SegmentListRemove (pArena, pNeighbour);
+               pBT->uSize += pNeighbour->uSize;
+               pBT->is_rightmost = pNeighbour->is_rightmost;
+               OSFreeMem(pNeighbour);
+       }
+
+       if (_RemoveResourceSpan(pArena, pBT) == IMG_FALSE)
+       {
+               _FreeListInsert (pArena, pBT);
+               PVR_ASSERT( (!pBT->is_rightmost) || (!pBT->is_leftmost) || (!pBT->free_import) );
+       }
+       
+       PVR_ASSERT(is_arena_valid(pArena));
+}
+
+
+/*
+  This function returns the first element in a bucket that can be split
+  in a way that one of the subsegment can meet the size and alignment
+  criteria.
+
+  The first_elt is the bucket to look into. Remember that a bucket is
+  implemented as a pointer to the first element of the linked list.
+
+  nb_max_try is used to limit the number of elements considered.
+  This is used to only consider the first nb_max_try elements in the
+  free-list. The special value ~0 is used to say unlimited i.e. consider
+  all elements in the free list 
+ */
+static INLINE
+struct _BT_ * find_chunk_in_bucket(struct _BT_ * first_elt,
+                                                                  RA_LENGTH_T uSize,
+                                                                  RA_LENGTH_T uAlignment,
+                                                                  unsigned int nb_max_try)
+{
+       struct _BT_ * walker;
+
+       for (walker = first_elt; (walker != NULL) && (nb_max_try != 0); walker = walker->next_free)
+       {
+               const RA_BASE_T aligned_base = (uAlignment > 1) ?
+                       (walker->base + uAlignment - 1) & ~(uAlignment - 1)
+                       : walker->base;
+               
+               if (walker->base + walker->uSize >= aligned_base + uSize)
+               {
+                       return walker;
+               }
+
+               /* 0xFFFF...FFFF is used has nb_max_try = infinity. */
+               if (nb_max_try != (unsigned int) ~0)
+               {
+                       nb_max_try--;
+               }
+       }
+
+       return NULL;
+}
+
+
+/*************************************************************************/ /*!
+@Function       _AttemptAllocAligned
+@Description    Attempt an allocation from an arena.
+@Input          pArena       The arena.
+@Input          uSize        The requested allocation size.
+@Output         phPriv          The user references associated with
+                             the imported segment. (optional)
+@Input          flags        Allocation flags
+@Input          uAlignment   Required uAlignment, or 0. 
+                             Must be a power of 2 if not 0
+@Output         base         Allocated resource base (non optional, must not be NULL)
+@Return         IMG_FALSE failure
+                IMG_TRUE success
+*/ /**************************************************************************/
+static IMG_BOOL
+_AttemptAllocAligned (RA_ARENA *pArena,
+                                         RA_LENGTH_T uSize,
+                                         IMG_UINT32 uFlags,
+                                         RA_LENGTH_T uAlignment,
+                                         RA_BASE_T *base,
+                      RA_PERISPAN_HANDLE *phPriv) /* this is the "per-import" private data */
+{
+
+       IMG_UINT32 index_low;
+       IMG_UINT32 index_high; 
+       IMG_UINT32 i; 
+       struct _BT_ * pBT = NULL;
+       RA_BASE_T aligned_base;
+
+       PVR_ASSERT (pArena!=IMG_NULL);
+       PVR_ASSERT (base != NULL);
+
+       pArena->per_flags_buckets = PVRSRVSplay(uFlags, pArena->per_flags_buckets);
+       if ((pArena->per_flags_buckets == NULL) || (pArena->per_flags_buckets->ui32Flags != uFlags))
+       {
+               /* no chunks with these flags. */
+               return IMG_FALSE;
+       }
+
+       index_low = pvr_log2(uSize);
+       index_high = pvr_log2(uSize + uAlignment - 1);
+       
+       PVR_ASSERT(index_low < FREE_TABLE_LIMIT);
+       PVR_ASSERT(index_high < FREE_TABLE_LIMIT);
+       PVR_ASSERT(index_low <= index_high);
+
+#if defined(HAS_BUILTIN_CTZLL)
+       i = __builtin_ctzll((IMG_ELTS_MAPPINGS) (~((1 << (index_high + 1)) - 1)) & pArena->per_flags_buckets->bHasEltsMapping);
+#else
+       for (i = index_high + 1; (i < FREE_TABLE_LIMIT) && (pArena->per_flags_buckets->buckets[i] == NULL); ++i)
+       {
+       }
+#endif
+       PVR_ASSERT(i <= FREE_TABLE_LIMIT);
+
+       if (i != FREE_TABLE_LIMIT)
+       {
+               /* since we start at index_high + 1, we are guarantee to exit */
+               pBT = find_chunk_in_bucket(pArena->per_flags_buckets->buckets[i], uSize, uAlignment, 1);
+       }
+       else
+       {
+               for (i = index_high; (i != index_low - 1) && (pBT == NULL); --i)
+               {
+                       pBT = find_chunk_in_bucket(pArena->per_flags_buckets->buckets[i], uSize, uAlignment, (unsigned int) ~0);                        
+               }
+       }
+
+       if (pBT == NULL)
+       {
+               return IMG_FALSE;
+       }
+
+       aligned_base = (uAlignment > 1) ? (pBT->base + uAlignment - 1) & ~(uAlignment - 1) : pBT->base;
+
+       _FreeListRemove (pArena, pBT);
+
+       if(pArena->bNoSplit)
+       {
+               goto nosplit;
+       }
+
+       /* with uAlignment we might need to discard the front of this segment */
+       if (aligned_base > pBT->base)
+       {
+               BT *pNeighbour;
+               pNeighbour = _SegmentSplit (pBT, (RA_LENGTH_T)(aligned_base - pBT->base));
+               /* partition the buffer, create a new boundary tag */
+               if (pNeighbour == NULL)
+               {
+                       PVR_DPF ((PVR_DBG_ERROR, "%s: Front split failed", __FUNCTION__));
+                       /* Put pBT back in the list */
+                       _FreeListInsert (pArena, pBT);
+                       return IMG_FALSE;
+               }
+
+               _FreeListInsert(pArena, pBT);
+               pBT = pNeighbour;
+       }
+
+       /* the segment might be too big, if so, discard the back of the segment */
+       if (pBT->uSize > uSize)
+       {
+               BT *pNeighbour;
+               pNeighbour = _SegmentSplit(pBT, uSize);
+               /* partition the buffer, create a new boundary tag */
+               if (pNeighbour == NULL)
+               {
+                       PVR_DPF ((PVR_DBG_ERROR, "%s: Back split failed", __FUNCTION__));
+                       /* Put pBT back in the list */
+                       _FreeListInsert (pArena, pBT);
+                       return IMG_FALSE;
+               }
+       
+               _FreeListInsert (pArena, pNeighbour);
+       }
+nosplit:
+       pBT->type = btt_live;
+       
+       if (!HASH_Insert_Extended (pArena->pSegmentHash, &pBT->base, (IMG_UINTPTR_T)pBT))
+       {
+               _FreeBT (pArena, pBT);
+               return IMG_FALSE;
+       }
+       
+       if (phPriv != IMG_NULL)
+               *phPriv = pBT->hPriv;
+       
+       *base = pBT->base;
+       
+       return IMG_TRUE;
+}
+
+
+
+/*************************************************************************/ /*!
+@Function       RA_Create
+@Description    To create a resource arena.
+@Input          name          The name of the arena for diagnostic purposes.
+@Input          base          The base of an initial resource span or 0.
+@Input          uSize         The size of an initial resource span or 0.
+@Input          uFlags        The flags of an initial resource span or 0.
+@Input          ulog2Quantum  The arena allocation quantum.
+@Input          imp_alloc     A resource allocation callback or 0.
+@Input          imp_free      A resource de-allocation callback or 0.
+@Input          pImportHandle Handle passed to alloc and free or 0.
+@Input          bNoSplit      Disable splitting up imports.
+@Return         arena handle, or IMG_NULL.
+*/ /**************************************************************************/
+IMG_INTERNAL RA_ARENA *
+RA_Create (IMG_CHAR *name,
+                  RA_LOG2QUANTUM_T uLog2Quantum,
+                  IMG_UINT32 ui32LockClass,
+                  IMG_BOOL (*imp_alloc)(RA_PERARENA_HANDLE h, 
+                                 RA_LENGTH_T uSize,
+                                 RA_FLAGS_T _flags, 
+                                 /* returned data */
+                                 RA_BASE_T *pBase,
+                                 RA_LENGTH_T *pActualSize,
+                                 RA_PERISPAN_HANDLE *phPriv),
+                  IMG_VOID (*imp_free) (RA_PERARENA_HANDLE,
+                                 RA_BASE_T,
+                                 RA_PERISPAN_HANDLE),
+                  RA_PERARENA_HANDLE arena_handle,
+                  IMG_BOOL bNoSplit)
+{
+       RA_ARENA *pArena;
+       PVRSRV_ERROR eError;
+
+       if (name == NULL)
+       {
+               PVR_DPF ((PVR_DBG_ERROR, "RA_Create: invalid parameter 'name' (NULL not accepted)"));
+               return NULL;
+       }
+       
+       PVR_DPF ((PVR_DBG_MESSAGE, "RA_Create: name='%s'", name));
+
+       pArena = OSAllocMem(sizeof (*pArena));
+    if (pArena == IMG_NULL)
+       {
+               goto arena_fail;
+       }
+
+       eError = OSLockCreate(&pArena->hLock, LOCK_TYPE_PASSIVE);
+       if (eError != PVRSRV_OK)
+       {
+               goto lock_fail;
+       }
+
+       pArena->pSegmentHash = HASH_Create_Extended(MINIMUM_HASH_SIZE, sizeof(RA_BASE_T), HASH_Func_Default, HASH_Key_Comp_Default);
+
+       if (pArena->pSegmentHash==IMG_NULL)
+       {
+               goto hash_fail;
+       }
+
+       pArena->name = name;
+       pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail;
+       pArena->pImportFree = imp_free;
+       pArena->pImportHandle = arena_handle;
+       pArena->pHeadSegment = IMG_NULL;
+       pArena->uQuantum = (IMG_UINT64) (1 << uLog2Quantum);
+       pArena->per_flags_buckets = NULL;
+       pArena->ui32LockClass = ui32LockClass;
+       pArena->bNoSplit = bNoSplit;
+
+       PVR_ASSERT(is_arena_valid(pArena));
+       return pArena;
+
+hash_fail:
+       OSLockDestroy(pArena->hLock);
+lock_fail:
+       OSFreeMem(pArena);
+       /*not nulling pointer, out of scope*/
+arena_fail:
+       return IMG_NULL;
+}
+
+/*************************************************************************/ /*!
+@Function       RA_Delete
+@Description    To delete a resource arena. All resources allocated from
+                the arena must be freed before deleting the arena.
+@Input          pArena        The arena to delete.
+*/ /**************************************************************************/
+IMG_INTERNAL 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_ASSERT(is_arena_valid(pArena));
+
+       PVR_DPF ((PVR_DBG_MESSAGE,
+                         "RA_Delete: name='%s'", pArena->name));
+
+       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%llx size=0x%llx",
+                                         (unsigned long long)pBT->base, (unsigned long long)pBT->uSize));
+               }
+               else
+               {
+                       _FreeListRemove(pArena, pBT);
+               }
+
+               _SegmentListRemove (pArena, pBT);
+               OSFreeMem(pBT);
+               /*not nulling original pointer, it has changed*/
+       }
+
+       while (pArena->per_flags_buckets != NULL)
+       {
+               for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
+               {
+                       PVR_ASSERT(pArena->per_flags_buckets->buckets[uIndex] == IMG_NULL);
+               }
+
+               pArena->per_flags_buckets = PVRSRVDelete(pArena->per_flags_buckets->ui32Flags, pArena->per_flags_buckets);
+       }
+
+       HASH_Delete (pArena->pSegmentHash);
+       OSLockDestroy(pArena->hLock);
+       OSFreeMem(pArena);
+       /*not nulling pointer, copy on stack*/
+}
+
+/*************************************************************************/ /*!
+@Function       RA_Add
+@Description    To add a resource span to an arena. The span must not
+                overlapp with any span previously added to the arena.
+@Input          pArena     The arena to add a span into.
+@Input          base       The base of the span.
+@Input          uSize      The extent of the span.
+@Input                 uFlags     the flags of the new import
+@Input                 hPriv      a private handle associate to the span. (reserved for user)
+@Return         IMG_TRUE - Success
+                IMG_FALSE - failure
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+RA_Add (RA_ARENA *pArena,
+               RA_BASE_T base,
+               RA_LENGTH_T uSize,
+               RA_FLAGS_T uFlags,
+               RA_PERISPAN_HANDLE hPriv)
+{
+       struct _BT_* bt;
+       PVR_ASSERT (pArena != IMG_NULL);
+       PVR_ASSERT (uSize != 0);
+
+       if (pArena == IMG_NULL)
+       {
+               PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena"));
+               return IMG_FALSE;
+       }
+
+       OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass);
+       PVR_ASSERT(is_arena_valid(pArena));
+       PVR_DPF ((PVR_DBG_MESSAGE, "RA_Add: name='%s', "
+              "base=0x%llx, size=0x%llx", pArena->name,
+                         (unsigned long long)base, (unsigned long long)uSize));
+
+       uSize = (uSize + pArena->uQuantum - 1) & ~(pArena->uQuantum - 1);
+       bt = _InsertResource(pArena, base, uSize, uFlags);
+       if (bt != NULL)
+       {
+               bt->hPriv = hPriv;
+       }
+
+       PVR_ASSERT(is_arena_valid(pArena));
+       OSLockRelease(pArena->hLock);
+
+       return bt != NULL;
+}
+
+/*************************************************************************/ /*!
+@Function       RA_Alloc
+@Description    To allocate resource from an arena.
+@Input          pArena         The arena
+@Input          uRequestSize   The size of resource segment requested.
+@Output         pActualSize    The actual size of resource segment
+                               allocated, typcially rounded up by quantum.
+@Output         phPriv         The user reference associated with allocated resource span.
+@Input          uFlags         Flags influencing allocation policy.
+@Input          uAlignment     The uAlignment constraint required for the
+                               allocated segment, use 0 if uAlignment not required, otherwise
+                               must be a power of 2.
+@Output         base           Allocated base resource
+@Return         IMG_TRUE - success
+                IMG_FALSE - failure
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+RA_Alloc (RA_ARENA *pArena,
+                 RA_LENGTH_T uRequestSize,
+                 RA_FLAGS_T uFlags,
+                 RA_LENGTH_T uAlignment,
+                 RA_BASE_T *base,
+                 RA_LENGTH_T *pActualSize,
+          RA_PERISPAN_HANDLE *phPriv)
+{
+       IMG_BOOL bResult;
+       RA_LENGTH_T uSize = uRequestSize;
+
+       PVR_ASSERT (pArena!=IMG_NULL);
+       PVR_ASSERT (uSize > 0);
+
+       if (pArena == IMG_NULL)
+       {
+               PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena"));
+               return IMG_FALSE;
+       }
+
+       OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass);
+       PVR_ASSERT(is_arena_valid(pArena));
+
+       if (pActualSize != IMG_NULL)
+       {
+               *pActualSize = uSize;
+       }
+
+       /* Must be a power of 2 or 0 */
+       PVR_ASSERT((uAlignment == 0) || (uAlignment & (uAlignment - 1)) == 0);
+
+       PVR_DPF ((PVR_DBG_MESSAGE,
+                         "RA_Alloc: arena='%s', size=0x%llx(0x%llx), "
+              "alignment=0x%llx", pArena->name,
+                         (unsigned long long)uSize, (unsigned long long)uRequestSize,
+                         (unsigned long long)uAlignment));
+
+       /* if allocation failed then we might have an import source which
+          can provide more resource, else we will have to fail the
+          allocation to the caller. */
+       bResult = _AttemptAllocAligned (pArena, uSize, uFlags, uAlignment, base, phPriv);
+       if (!bResult)
+       {
+        IMG_HANDLE hPriv;
+               RA_BASE_T import_base;
+               RA_LENGTH_T uImportSize = uSize;
+
+               /*
+                       Ensure that we allocate sufficient space to meet the uAlignment
+                       constraint
+                */
+               if (uAlignment > pArena->uQuantum)
+               {
+                       uImportSize += (uAlignment - pArena->uQuantum);
+               }
+
+               /* ensure that we import according to the quanta of this arena */
+               uImportSize = (uImportSize + pArena->uQuantum - 1) & ~(pArena->uQuantum - 1);
+
+               bResult =
+                       pArena->pImportAlloc (pArena->pImportHandle, uImportSize, uFlags,
+                                  &import_base, &uImportSize, &hPriv);
+               if (bResult)
+               {
+                       BT *pBT;
+                       pBT = _InsertResourceSpan (pArena, import_base, uImportSize, uFlags);
+                       /* successfully import more resource, create a span to
+                          represent it and retry the allocation attempt */
+                       if (pBT == IMG_NULL)
+                       {
+                               /* insufficient resources to insert the newly acquired span,
+                                  so free it back again */
+                               pArena->pImportFree(pArena->pImportHandle, import_base, hPriv);
+
+                               PVR_DPF ((PVR_DBG_MESSAGE, "RA_Alloc: name='%s', "
+                          "size=0x%llx failed!", pArena->name,
+                                                 (unsigned long long)uSize));
+                               /* RA_Dump (arena); */
+                               OSLockRelease(pArena->hLock);
+                               return IMG_FALSE;
+                       }
+
+
+            pBT->hPriv = hPriv;
+
+                       bResult = _AttemptAllocAligned(pArena, uSize, uFlags, uAlignment, base, phPriv);
+                       if (!bResult)
+                       {
+                               PVR_DPF ((PVR_DBG_ERROR,
+                                                 "RA_Alloc: name='%s' second alloc failed!",
+                                                 pArena->name));
+
+                               /*
+                                 On failure of _AttemptAllocAligned() depending on the exact point
+                                 of failure, the imported segment may have been used and freed, or
+                                 left untouched. If the later, we need to return it.
+                               */
+                               _FreeBT(pArena, pBT);
+                       }
+                       else
+                       {
+                               /* Check if the new allocation was in the span we just added... */
+                               if (*base < import_base  ||  *base > (import_base + uImportSize))
+                               {
+                                       PVR_DPF ((PVR_DBG_ERROR,
+                                                         "RA_Alloc: name='%s' alloc did not occur in the imported span!",
+                                                         pArena->name));
+
+                                       /*
+                                         Remove the imported span which should not be in use (if it is then
+                                         that is okay, but essentially no span should exist that is not used).
+                                       */
+                                       _FreeBT(pArena, pBT);
+                               }
+                       }
+               }
+       }
+
+       PVR_DPF ((PVR_DBG_MESSAGE, "RA_Alloc: name='%s', size=0x%llx, "
+              "*base=0x%llx = %d",pArena->name, (unsigned long long)uSize,
+                         (unsigned long long)*base, bResult));
+
+       PVR_ASSERT(is_arena_valid(pArena));
+
+       OSLockRelease(pArena->hLock);
+       return bResult;
+}
+
+
+
+
+/*************************************************************************/ /*!
+@Function       RA_Free
+@Description    To free a resource segment.
+@Input          pArena     The arena the segment was originally allocated from.
+@Input          base       The base of the resource span to free.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_VOID
+RA_Free (RA_ARENA *pArena, RA_BASE_T base)
+{
+       BT *pBT;
+
+       PVR_ASSERT (pArena != IMG_NULL);
+
+       if (pArena == IMG_NULL)
+       {
+               PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena"));
+               return;
+       }
+
+       OSLockAcquireNested(pArena->hLock, pArena->ui32LockClass);
+       PVR_ASSERT(is_arena_valid(pArena));
+
+       PVR_DPF ((PVR_DBG_MESSAGE, "RA_Free: name='%s', base=0x%llx", pArena->name,
+                         (unsigned long long)base));
+
+       pBT = (BT *) HASH_Remove_Extended (pArena->pSegmentHash, &base);
+       PVR_ASSERT (pBT != IMG_NULL);
+
+       if (pBT)
+       {
+               PVR_ASSERT (pBT->base == base);
+               _FreeBT (pArena, pBT);
+       }
+
+       PVR_ASSERT(is_arena_valid(pArena));
+       OSLockRelease(pArena->hLock);
+}
diff --git a/drivers/gpu/rogue_m/services/shared/common/sync.c b/drivers/gpu/rogue_m/services/shared/common/sync.c
new file mode 100644 (file)
index 0000000..5de433a
--- /dev/null
@@ -0,0 +1,1959 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services synchronisation interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements client side code for services synchronisation
+                interface
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "client_sync_bridge.h"
+#include "allocmem.h"
+#include "osfunc.h"
+#include "devicemem.h"
+#include "devicemem_pdump.h"
+#include "pvr_debug.h"
+#include "dllist.h"
+#include "sync.h"
+#include "sync_internal.h"
+#include "lock.h"
+#include "pvr_debug.h"
+/* FIXME */
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#endif
+
+
+#define SYNC_BLOCK_LIST_CHUNCK_SIZE    10
+#define LOCAL_SYNC_PRIM_RESET_VALUE 0
+
+/*
+       This defines the maximum amount of synchronisation memory
+       that can be allocated per SyncPrim context.
+       In reality this number is meaningless as we would run out
+       of synchronisation memory before we reach this limit, but
+       we need to provide a size to the span RA.
+*/
+#define MAX_SYNC_MEM                           (4 * 1024 * 1024)
+
+typedef struct _SYNC_BLOCK_LIST_
+{
+       IMG_UINT32                      ui32BlockCount;                 /*!< Number of contexts in the list */
+       IMG_UINT32                      ui32BlockListSize;              /*!< Size of the array contexts */
+       SYNC_PRIM_BLOCK         **papsSyncPrimBlock;    /*!< Array of syncprim blocks */
+} SYNC_BLOCK_LIST;
+
+typedef struct _SYNC_OP_COOKIE_
+{
+       IMG_UINT32                              ui32SyncCount;
+       IMG_UINT32                              ui32ClientSyncCount;
+       IMG_UINT32                              ui32ServerSyncCount;
+       IMG_BOOL                                bHaveServerSync;
+       IMG_HANDLE                              hBridge;
+       IMG_HANDLE                              hServerCookie;
+
+       SYNC_BLOCK_LIST                 *psSyncBlockList;
+       PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim;
+       /*
+               Client sync(s) info.
+               If this changes update the calculation of ui32ClientAllocSize
+       */
+       IMG_UINT32                              *paui32SyncBlockIndex;
+       IMG_UINT32                              *paui32Index;
+       IMG_UINT32                              *paui32Flags;
+       IMG_UINT32                              *paui32FenceValue;
+       IMG_UINT32                              *paui32UpdateValue;
+
+       /*
+               Server sync(s) info
+               If this changes update the calculation of ui32ServerAllocSize
+       */
+       IMG_HANDLE                              *pahServerSync;
+       IMG_UINT32              *paui32ServerFlags;
+} SYNC_OP_COOKIE;
+
+/* forward declaration */
+static IMG_VOID
+_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value);
+
+/*
+       Internal interfaces for management of SYNC_PRIM_CONTEXT
+*/
+static IMG_VOID
+_SyncPrimContextUnref(SYNC_PRIM_CONTEXT *psContext)
+{
+       if (!OSAtomicRead(&psContext->hRefCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_SyncPrimContextUnref context already freed"));
+       }
+       else if (0 == OSAtomicDecrement(&psContext->hRefCount))
+       {
+               /* SyncPrimContextDestroy only when no longer referenced */
+               RA_Delete(psContext->psSpanRA);
+               RA_Delete(psContext->psSubAllocRA);
+               OSFreeMem(psContext);
+       }
+}
+
+static IMG_VOID
+_SyncPrimContextRef(SYNC_PRIM_CONTEXT *psContext)
+{
+       if (!OSAtomicRead(&psContext->hRefCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_SyncPrimContextRef context use after free"));
+       }
+       else
+       {
+               OSAtomicIncrement(&psContext->hRefCount);
+       }
+}
+
+/*
+       Internal interfaces for management of synchronisation block memory
+*/
+static PVRSRV_ERROR
+AllocSyncPrimitiveBlock(SYNC_PRIM_CONTEXT *psContext,
+                                               SYNC_PRIM_BLOCK **ppsSyncBlock)
+{
+       SYNC_PRIM_BLOCK *psSyncBlk;
+       DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie;
+       DEVMEM_EXPORTCOOKIE sExportCookie;
+       PVRSRV_ERROR eError;
+
+       psSyncBlk = OSAllocMem(sizeof(SYNC_PRIM_BLOCK));
+       if (psSyncBlk == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+       psSyncBlk->psContext = psContext;
+
+       /* Allocate sync prim block */
+       eError = BridgeAllocSyncPrimitiveBlock(psContext->hBridge,
+                                                                                  psContext->hDeviceNode,
+                                                                                  &psSyncBlk->hServerSyncPrimBlock,
+                                                                                  &psSyncBlk->ui32FirmwareAddr,
+                                                                                  &psSyncBlk->ui32SyncBlockSize,
+                                                                                  &hServerExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_blockalloc;
+       }
+
+       /* Make it mappable by the client */
+       eError = DevmemMakeServerExportClientExport(psContext->hBridge,
+                                                                                               hServerExportCookie,
+                                                                                               &sExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_export;
+       }
+
+       /* Get CPU mapping of the memory block */
+       eError = DevmemImport(psContext->hBridge,
+                                                 &sExportCookie,
+                                                 PVRSRV_MEMALLOCFLAG_CPU_READABLE,
+                                                 &psSyncBlk->hMemDesc);
+
+       /*
+               Regardless of success or failure we "undo" the export
+       */
+       DevmemUnmakeServerExportClientExport(psContext->hBridge,
+                                                                                &sExportCookie);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_import;
+       }
+
+       eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc,
+                                                                         (IMG_PVOID *) &psSyncBlk->pui32LinAddr);
+       if (eError != PVRSRV_OK)
+       {
+               goto fail_cpuvaddr;
+       }
+
+       *ppsSyncBlock = psSyncBlk;
+       return PVRSRV_OK;
+
+fail_cpuvaddr:
+       DevmemFree(psSyncBlk->hMemDesc);
+fail_import:
+fail_export:
+       BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
+                                                                psSyncBlk->hServerSyncPrimBlock);
+fail_blockalloc:
+       OSFreeMem(psSyncBlk);
+fail_alloc:
+       return eError;
+}
+
+static IMG_VOID
+FreeSyncPrimitiveBlock(SYNC_PRIM_BLOCK *psSyncBlk)
+{
+       SYNC_PRIM_CONTEXT *psContext = psSyncBlk->psContext;
+
+       DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc);
+       DevmemFree(psSyncBlk->hMemDesc);
+       BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
+                                                                psSyncBlk->hServerSyncPrimBlock);
+       OSFreeMem(psSyncBlk);
+}
+
+static IMG_BOOL
+SyncPrimBlockImport(RA_PERARENA_HANDLE hArena,
+                                       RA_LENGTH_T uSize,
+                                       RA_FLAGS_T uFlags,
+                                       RA_BASE_T *puiBase,
+                                       RA_LENGTH_T *puiActualSize,
+                                       RA_PERISPAN_HANDLE *phImport)
+{
+       SYNC_PRIM_CONTEXT *psContext = hArena;
+       SYNC_PRIM_BLOCK *psSyncBlock = IMG_NULL;
+       RA_LENGTH_T uiSpanSize;
+       PVRSRV_ERROR eError;
+       IMG_BOOL bRet;
+       PVR_UNREFERENCED_PARAMETER(uFlags);
+
+       /* Check we've not be called with an unexpected size */
+       if (!hArena || sizeof(IMG_UINT32) != uSize)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input params", __FUNCTION__));
+               goto e0;
+       }
+
+       /*
+               Ensure the synprim context doesn't go away while we have sync blocks
+               attached to it
+       */
+       _SyncPrimContextRef(psContext);
+
+       /* Allocate the block of memory */
+       eError = AllocSyncPrimitiveBlock(psContext, &psSyncBlock);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to allocation syncprim block (%d)", eError));
+               goto fail_syncblockalloc;
+       }
+
+       /* Allocate a span for it */
+       bRet = RA_Alloc(psContext->psSpanRA,
+                                       psSyncBlock->ui32SyncBlockSize,
+                                       0,
+                                       psSyncBlock->ui32SyncBlockSize,
+                                       &psSyncBlock->uiSpanBase,
+                                       &uiSpanSize,
+                                       IMG_NULL);
+
+       /*
+               There is no reason the span RA should return an allocation larger
+               then we request
+       */
+       if (bRet == IMG_FALSE || uiSpanSize != psSyncBlock->ui32SyncBlockSize)
+       {
+               goto fail_spanalloc;
+       }
+
+       *puiBase = psSyncBlock->uiSpanBase;
+       *puiActualSize = psSyncBlock->ui32SyncBlockSize;
+       *phImport = psSyncBlock;
+       return IMG_TRUE;
+
+fail_spanalloc:
+       FreeSyncPrimitiveBlock(psSyncBlock);
+fail_syncblockalloc:
+       _SyncPrimContextUnref(psContext);
+e0:
+       return IMG_FALSE;
+}
+
+static IMG_VOID
+SyncPrimBlockUnimport(RA_PERARENA_HANDLE hArena,
+                                         RA_BASE_T uiBase,
+                                         RA_PERISPAN_HANDLE hImport)
+{
+       SYNC_PRIM_CONTEXT *psContext = hArena;
+       SYNC_PRIM_BLOCK *psSyncBlock = hImport;
+
+       if (!psContext || !psSyncBlock || uiBase != psSyncBlock->uiSpanBase)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input params", __FUNCTION__));
+               return;
+       }
+
+       /* Free the span this import is using */
+       RA_Free(psContext->psSpanRA, uiBase);
+
+       /* Free the syncpim block */
+       FreeSyncPrimitiveBlock(psSyncBlock);
+
+       /*      Drop our reference to the syncprim context */
+       _SyncPrimContextUnref(psContext);
+}
+
+static INLINE IMG_UINT32 SyncPrimGetOffset(SYNC_PRIM *psSyncInt)
+{
+       IMG_UINT64 ui64Temp;
+       
+       PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);
+
+       /* FIXME: Subtracting a 64-bit address from another and then implicit
+        * cast to 32-bit number. Need to review all call sequences that use this
+        * function, added explicit casting for now.
+        */
+       ui64Temp =  psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
+       PVR_ASSERT(ui64Temp<IMG_UINT32_MAX);
+       return (IMG_UINT32)ui64Temp;
+}
+
+static IMG_VOID SyncPrimGetCPULinAddr(SYNC_PRIM *psSyncInt)
+{
+       SYNC_PRIM_BLOCK *psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+
+       psSyncInt->sCommon.pui32LinAddr = psSyncBlock->pui32LinAddr +
+                                                                         (SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32));
+}
+
+static IMG_VOID SyncPrimLocalFree(SYNC_PRIM *psSyncInt)
+{
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM_CONTEXT *psContext;
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+       {
+               PVRSRV_ERROR eError;
+               /* remove this sync record */
+               eError = BridgeSyncRecordRemoveByHandle(
+                                               psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge,
+                                               psSyncInt->u.sLocal.hRecord);
+               if (PVRSRV_OK != eError)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: failed to remove SyncRecord", __FUNCTION__));
+               }
+       }
+#endif
+       /* reset the sync prim value as it is freed.
+        * this guarantees the client sync allocated to the client will
+        * have a value of zero and the client does not need to
+        * explicitly initialise the sync value to zero.
+        * the allocation of the backing memory for the sync prim block
+        * is done with ZERO_ON_ALLOC so the memory is initially all zero.
+        */
+        _SyncPrimSetValue(psSyncInt, LOCAL_SYNC_PRIM_RESET_VALUE);
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       psContext = psSyncBlock->psContext;
+
+       RA_Free(psContext->psSubAllocRA, psSyncInt->u.sLocal.uiSpanAddr);
+       OSFreeMem(psSyncInt);
+       _SyncPrimContextUnref(psContext);
+}
+
+static IMG_VOID SyncPrimServerFree(SYNC_PRIM *psSyncInt)
+{
+       PVRSRV_ERROR eError;
+
+       eError = BridgeServerSyncFree(psSyncInt->u.sServer.hBridge,
+                                                                 psSyncInt->u.sServer.hServerSync);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimServerFree failed"));
+       }
+       OSFreeMem(psSyncInt);
+}
+
+static IMG_VOID SyncPrimLocalUnref(SYNC_PRIM *psSyncInt)
+{
+       if (!OSAtomicRead(&psSyncInt->u.sLocal.hRefCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimLocalUnref sync already freed"));
+       }
+       else if (0 == OSAtomicDecrement(&psSyncInt->u.sLocal.hRefCount))
+       {
+               SyncPrimLocalFree(psSyncInt);
+       }
+}
+
+static IMG_VOID SyncPrimLocalRef(SYNC_PRIM *psSyncInt)
+{
+       if (!OSAtomicRead(&psSyncInt->u.sLocal.hRefCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimLocalRef sync use after free"));
+       }
+       else
+       {
+               OSAtomicIncrement(&psSyncInt->u.sLocal.hRefCount);
+       }
+}
+
+static IMG_UINT32 SyncPrimGetFirmwareAddrLocal(SYNC_PRIM *psSyncInt)
+{
+       SYNC_PRIM_BLOCK *psSyncBlock;
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       return psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psSyncInt);    
+}
+
+static IMG_UINT32 SyncPrimGetFirmwareAddrServer(SYNC_PRIM *psSyncInt)
+{
+       return psSyncInt->u.sServer.ui32FirmwareAddr;
+}
+
+#if !defined(__KERNEL__)
+static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleLocal(SYNC_PRIM *psSyncInt)
+{
+       return psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge;
+}
+
+static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleServer(SYNC_PRIM *psSyncInt)
+{
+       return psSyncInt->u.sServer.hBridge;
+}
+
+static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+       {
+               return _SyncPrimGetBridgeHandleLocal(psSyncInt);
+       }
+       else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+       {
+               return _SyncPrimGetBridgeHandleServer(psSyncInt);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "_SyncPrimGetBridgeHandle: Invalid sync type"));
+               /*
+                       Either the client has given us a bad pointer or there is an
+                       error in this module
+               */
+               return 0;
+       }
+}
+#endif
+
+/*
+       Internal interfaces for management of syncprim block lists
+*/
+static SYNC_BLOCK_LIST *_SyncPrimBlockListCreate(IMG_VOID)
+{
+       SYNC_BLOCK_LIST *psBlockList;
+
+       psBlockList = OSAllocMem(sizeof(SYNC_BLOCK_LIST));
+       if (!psBlockList)
+       {
+               return IMG_NULL;
+       }
+
+       psBlockList->ui32BlockCount = 0;
+       psBlockList->ui32BlockListSize = SYNC_BLOCK_LIST_CHUNCK_SIZE;
+
+       psBlockList->papsSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *)
+                                                                                                       * SYNC_BLOCK_LIST_CHUNCK_SIZE);
+       if (!psBlockList->papsSyncPrimBlock)
+       {
+               OSFreeMem(psBlockList);
+               return IMG_NULL;
+       }
+
+       OSCachedMemSet(psBlockList->papsSyncPrimBlock,
+                        0,
+                        sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);
+
+       return psBlockList;
+}
+
+static PVRSRV_ERROR _SyncPrimBlockListAdd(SYNC_BLOCK_LIST *psBlockList,
+                                                                                       SYNC_PRIM_BLOCK *psSyncPrimBlock)
+{
+       IMG_UINT32 i;
+
+       /* Check the context isn't already on the list */
+       for (i=0;i<psBlockList->ui32BlockCount;i++)
+       {
+               if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
+               {
+                       return PVRSRV_OK;
+               }
+       }
+
+       /* Check we have space for a new item */
+       if (psBlockList->ui32BlockCount == psBlockList->ui32BlockListSize)
+       {
+               SYNC_PRIM_BLOCK **papsNewSyncPrimBlock;
+
+               papsNewSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *) *
+                                                                                       (psBlockList->ui32BlockListSize +
+                                                                                       SYNC_BLOCK_LIST_CHUNCK_SIZE));
+               if (!papsNewSyncPrimBlock)
+               {
+                       return PVRSRV_ERROR_OUT_OF_MEMORY;
+               }
+
+               OSCachedMemCopy(papsNewSyncPrimBlock,
+                                 psBlockList->papsSyncPrimBlock,
+                                 sizeof(SYNC_PRIM_CONTEXT *) *
+                                 psBlockList->ui32BlockListSize);
+
+               OSFreeMem(psBlockList->papsSyncPrimBlock);
+
+               psBlockList->papsSyncPrimBlock = papsNewSyncPrimBlock;
+               psBlockList->ui32BlockListSize += SYNC_BLOCK_LIST_CHUNCK_SIZE;
+       }
+
+       /* Add the context to the list */
+       psBlockList->papsSyncPrimBlock[psBlockList->ui32BlockCount++] = psSyncPrimBlock;
+       return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _SyncPrimBlockListBlockToIndex(SYNC_BLOCK_LIST *psBlockList,
+                                                                                                  SYNC_PRIM_BLOCK *psSyncPrimBlock,
+                                                                                                  IMG_UINT32 *pui32Index)
+{
+       IMG_UINT32 i;
+
+       for (i=0;i<psBlockList->ui32BlockCount;i++)
+       {
+               if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
+               {
+                       *pui32Index = i;
+                       return PVRSRV_OK;
+               }
+       }
+
+       return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+static PVRSRV_ERROR _SyncPrimBlockListHandleArrayCreate(SYNC_BLOCK_LIST *psBlockList,
+                                                                                                               IMG_UINT32 *pui32BlockHandleCount,
+                                                                                                               IMG_HANDLE **ppahHandleList)
+{
+       IMG_HANDLE *pahHandleList;
+       IMG_UINT32 i;
+
+       pahHandleList = OSAllocMem(sizeof(IMG_HANDLE) *
+                                                          psBlockList->ui32BlockCount);
+       if (!pahHandleList)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (i=0;i<psBlockList->ui32BlockCount;i++)
+       {
+               pahHandleList[i] = psBlockList->papsSyncPrimBlock[i]->hServerSyncPrimBlock;
+       }
+
+       *ppahHandleList = pahHandleList;
+       *pui32BlockHandleCount = psBlockList->ui32BlockCount;
+
+       return PVRSRV_OK;
+}
+
+static IMG_VOID _SyncPrimBlockListHandleArrayDestroy(IMG_HANDLE *pahHandleList)
+{
+       OSFreeMem(pahHandleList);
+}
+
+static IMG_UINT32 _SyncPrimBlockListGetClientValue(SYNC_BLOCK_LIST *psBlockList,
+                                                                                                  IMG_UINT32 ui32BlockIndex,
+                                                                                                  IMG_UINT32 ui32Index)
+{
+       return psBlockList->papsSyncPrimBlock[ui32BlockIndex]->pui32LinAddr[ui32Index];
+}
+
+static IMG_VOID _SyncPrimBlockListDestroy(SYNC_BLOCK_LIST *psBlockList)
+{
+       OSFreeMem(psBlockList->papsSyncPrimBlock);
+       OSFreeMem(psBlockList);
+}
+
+
+/* TODO: implement _Log2 using __builtin_clz gcc's builtin */
+/* TODO: factorise the log2 functions (there is a similar one in services/shared/common/ra.c) */
+static INLINE IMG_UINT32 _Log2(IMG_UINT32 ui32Align)
+{
+       IMG_UINT32 ui32Log2Align = 0;
+       PVR_ASSERT(ui32Align != 0); /* Log2 isn't defined on 0 (triggers an assert instead of an infinite loop) */
+
+       while (!(ui32Align & 1))
+       {
+               ui32Log2Align++;
+               ui32Align = ui32Align >> 1;
+       }
+       PVR_ASSERT(ui32Align == 1);
+
+       return ui32Log2Align;
+}
+
+/*
+       External interfaces
+*/
+
+IMG_INTERNAL PVRSRV_ERROR
+SyncPrimContextCreate(SYNC_BRIDGE_HANDLE hBridge,
+                                         IMG_HANDLE hDeviceNode,
+                                         PSYNC_PRIM_CONTEXT *phSyncPrimContext)
+{
+       SYNC_PRIM_CONTEXT *psContext;
+       PVRSRV_ERROR eError;
+
+       psContext = OSAllocMem(sizeof(SYNC_PRIM_CONTEXT));
+       if (psContext == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       psContext->hBridge = hBridge;
+       psContext->hDeviceNode = hDeviceNode;
+
+       OSSNPrintf(psContext->azName, SYNC_PRIM_NAME_SIZE, "Sync Prim RA-%p", psContext);
+       OSSNPrintf(psContext->azSpanName, SYNC_PRIM_NAME_SIZE, "Sync Prim span RA-%p", psContext);
+
+       /*
+               Create the RA for sub-allocations of the SynPrim's
+
+               Note:
+               The import size doesn't matter here as the server will pass
+               back the blocksize when does the import which overrides
+               what we specify here.
+       */
+
+       psContext->psSubAllocRA = RA_Create(psContext->azName,
+                                                                               /* Params for imports */
+                                                                               _Log2(sizeof(IMG_UINT32)),
+                                                                               RA_LOCKCLASS_2,
+                                                                               SyncPrimBlockImport,
+                                                                               SyncPrimBlockUnimport,
+                                                                               psContext,
+                                                                               IMG_FALSE);
+       if (psContext->psSubAllocRA == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_suballoc;
+       }
+
+       /*
+               Create the span-management RA
+
+               The RA requires that we work with linear spans. For our use
+               here we don't require this behaviour as we're always working
+               within offsets of blocks (imports). However, we need to keep
+               the RA happy so we create the "span" management RA which
+               ensures that all are imports are added to the RA in a linear
+               fashion
+       */
+       psContext->psSpanRA = RA_Create(psContext->azSpanName,
+                                                                       /* Params for imports */
+                                                                       0,
+                                                                       RA_LOCKCLASS_1,
+                                                                       IMG_NULL,
+                                                                       IMG_NULL,
+                                                                       IMG_NULL,
+                                                                       IMG_FALSE);
+       if (psContext->psSpanRA == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_span;
+       }
+
+       if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_MEM, 0, IMG_NULL))
+       {
+               RA_Delete(psContext->psSpanRA);
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_span;
+       }
+
+       OSAtomicWrite(&psContext->hRefCount, 1);
+
+       *phSyncPrimContext = psContext;
+       return PVRSRV_OK;
+fail_span:
+       RA_Delete(psContext->psSubAllocRA);
+fail_suballoc:
+       OSFreeMem(psContext);
+fail_alloc:
+       return eError;
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext)
+{
+       SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
+       if (1 != OSAtomicRead(&psContext->hRefCount))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s attempted with active references, may be the result of a race", __FUNCTION__));
+       }
+       _SyncPrimContextUnref(psContext);
+}
+
+static PVRSRV_ERROR _SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
+                                                                               PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                                                               const IMG_CHAR *pszClassName,
+                                                                               IMG_BOOL bServerSync)
+{
+       SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM *psNewSync;
+       PVRSRV_ERROR eError;
+       RA_BASE_T uiSpanAddr;
+
+       psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
+       if (psNewSync == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_alloc;
+       }
+
+       if (!RA_Alloc(psContext->psSubAllocRA,
+                                 sizeof(IMG_UINT32),
+                                 0,
+                                 sizeof(IMG_UINT32),
+                                 &uiSpanAddr,
+                                 IMG_NULL,
+                                 (RA_PERISPAN_HANDLE *) &psSyncBlock))
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto fail_raalloc;
+       }
+       psNewSync->eType = SYNC_PRIM_TYPE_LOCAL;
+       OSAtomicWrite(&psNewSync->u.sLocal.hRefCount, 1);
+       psNewSync->u.sLocal.uiSpanAddr = uiSpanAddr;
+       psNewSync->u.sLocal.psSyncBlock = psSyncBlock;
+       SyncPrimGetCPULinAddr(psNewSync);
+       *ppsSync = &psNewSync->sCommon;
+       _SyncPrimContextRef(psContext);
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+       {
+               IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
+               if(pszClassName)
+               {
+                       /* Copy the class name annotation into a fixed-size array */
+                       OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
+                       szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
+               }
+               else
+               {
+                       /* No class name annotation */
+                       szClassName[0] = 0;
+               }
+               /* record this sync */
+               eError = BridgeSyncRecordAdd(
+                                       psSyncBlock->psContext->hBridge,
+                                       &psNewSync->u.sLocal.hRecord,
+                                       psSyncBlock->hServerSyncPrimBlock,
+                                       psSyncBlock->ui32FirmwareAddr,
+                                       SyncPrimGetOffset(psNewSync),
+                                       bServerSync,
+                                       OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
+                                       szClassName);
+               if (PVRSRV_OK != eError)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: failed to add SyncRecord", __FUNCTION__));
+               }
+       }
+#else
+       PVR_UNREFERENCED_PARAMETER(pszClassName);
+       PVR_UNREFERENCED_PARAMETER(bServerSync);
+#endif /* if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
+
+       return PVRSRV_OK;
+
+fail_raalloc:
+       OSFreeMem(psNewSync);
+fail_alloc:
+       return eError;
+}
+
+#if defined(__KERNEL__)
+IMG_INTERNAL PVRSRV_ERROR SyncPrimAllocForServerSync(PSYNC_PRIM_CONTEXT hSyncPrimContext,
+                                                                               PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                                                               const IMG_CHAR *pszClassName)
+{
+       return _SyncPrimAlloc(hSyncPrimContext,
+                                         ppsSync,
+                                         pszClassName,
+                                         IMG_TRUE);
+}
+#endif
+
+IMG_INTERNAL PVRSRV_ERROR SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
+                                                                               PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                                                               const IMG_CHAR *pszClassName)
+{
+       return _SyncPrimAlloc(hSyncPrimContext,
+                                         ppsSync,
+                                         pszClassName,
+                                         IMG_FALSE);
+}
+
+static IMG_VOID
+_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value)
+{
+       PVRSRV_ERROR eError;
+
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+       {
+               SYNC_PRIM_BLOCK *psSyncBlock;
+               SYNC_PRIM_CONTEXT *psContext;
+
+               psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+               psContext = psSyncBlock->psContext;
+
+               eError = BridgeSyncPrimSet(psContext->hBridge,
+                                                                       psSyncBlock->hServerSyncPrimBlock,
+                                                                       SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32),
+                                                                       ui32Value);
+       }
+       else
+       {
+               eError = BridgeServerSyncPrimSet(psSyncInt->u.sServer.hBridge,
+                                                                       psSyncInt->u.sServer.hServerSync,
+                                                                       ui32Value);
+       }
+       /* These functions don't actually fail */
+       if (PVRSRV_OK != eError)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
+       }
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
+               return;
+       }
+
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+       {
+               SyncPrimLocalUnref(psSyncInt);
+       }
+       else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+       {
+               SyncPrimServerFree(psSyncInt);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimFree: Invalid sync type"));
+               /*
+                       Either the client has given us a bad pointer or there is an
+                       error in this module
+               */
+               return;
+       }
+}
+
+#if defined(NO_HARDWARE)
+IMG_INTERNAL IMG_VOID
+SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
+{
+       SYNC_PRIM *psSyncInt;
+
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
+               return;
+       }
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       /* There is no check for the psSyncInt to be LOCAL as this call
+          substitutes the Firmware updating a sync and that sync could
+          be a server one */
+
+       _SyncPrimSetValue(psSyncInt, ui32Value);
+}
+#endif
+
+IMG_INTERNAL IMG_VOID
+SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
+{
+       SYNC_PRIM *psSyncInt;
+
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
+               return;
+       }
+
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimSet: Invalid sync type"));
+               return;
+       }
+
+       _SyncPrimSetValue(psSyncInt, ui32Value);
+
+#if defined(PDUMP)
+       SyncPrimPDump(psSync);
+#endif
+
+}
+
+IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                       IMG_HANDLE *phBlock,
+                                                       IMG_UINT32 *pui32Offset)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       SYNC_PRIM *psSyncInt;
+
+       if(!psSync || !phBlock || !pui32Offset)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetHandleAndOffset: invalid input pointer"));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto err_out;
+       }
+
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+       {
+               *phBlock = psSyncInt->u.sLocal.psSyncBlock->hServerSyncPrimBlock;
+               *pui32Offset = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: psSync not a Local sync prim (%d)",
+                       __FUNCTION__, psSyncInt->eType));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto err_out;
+       }
+
+err_out:
+       return eError;
+}
+
+IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
+               goto err_out;
+       }
+
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+       {
+               return SyncPrimGetFirmwareAddrLocal(psSyncInt);
+       }
+       else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+       {
+               return SyncPrimGetFirmwareAddrServer(psSyncInt);
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetFirmwareAddr: Invalid sync type"));
+               /*
+                       Either the client has given us a bad pointer or there is an
+                       error in this module
+               */
+               goto err_out;
+       }
+err_out:
+       return 0;
+}
+
+#if !defined(__KERNEL__)
+IMG_INTERNAL PVRSRV_ERROR SyncPrimDumpSyncs(IMG_UINT32 ui32SyncCount, PVRSRV_CLIENT_SYNC_PRIM **papsSync, const IMG_CHAR *pcszExtraInfo)
+{
+#if defined(PVRSRV_NEED_PVR_DPF)
+       SYNC_PRIM *psSyncInt;
+       PVRSRV_CLIENT_SYNC_PRIM **papsServerSync;
+       IMG_UINT32 ui32ServerSyncs = 0;
+       IMG_UINT32 *pui32UID = IMG_NULL;
+       IMG_UINT32 *pui32FWAddr = IMG_NULL;
+       IMG_UINT32 *pui32CurrentOp = IMG_NULL;
+       IMG_UINT32 *pui32NextOp = IMG_NULL;
+       IMG_UINT32 i;
+       PVRSRV_ERROR eError = PVRSRV_OK;
+
+       papsServerSync = OSAllocMem(ui32SyncCount * sizeof(PVRSRV_CLIENT_SYNC_PRIM *));
+       if (!papsServerSync)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (i = 0; i < ui32SyncCount; i++)
+       {
+               psSyncInt = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
+               if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: sync=local  fw=0x%x curr=0x%04x",
+                                        pcszExtraInfo,
+                                        SyncPrimGetFirmwareAddrLocal(psSyncInt),
+                                        *psSyncInt->sCommon.pui32LinAddr));
+               }
+               else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+               {
+                       papsServerSync[ui32ServerSyncs++] = papsSync[i];
+               }
+               else
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Invalid sync type"));
+                       /*
+                          Either the client has given us a bad pointer or there is an
+                          error in this module
+                          */
+                       eError = PVRSRV_ERROR_INVALID_PARAMS;
+                       goto err_free;
+               }
+       }
+
+       if (ui32ServerSyncs > 0)
+       {
+               pui32UID = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
+               if (!pui32UID)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto err_free;
+               }
+               pui32FWAddr = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
+               if (!pui32FWAddr)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto err_free;
+               }
+               pui32CurrentOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
+               if (!pui32CurrentOp)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto err_free;
+               }
+               pui32NextOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
+               if (!pui32NextOp)
+               {
+                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+                       goto err_free;
+               }
+               eError = SyncPrimServerGetStatus(ui32ServerSyncs, papsServerSync,
+                                                                                pui32UID,
+                                                                                pui32FWAddr,
+                                                                                pui32CurrentOp,
+                                                                                pui32NextOp);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Error querying server sync status (%d)",
+                                        eError));
+                       goto err_free;
+               }
+               for (i = 0; i < ui32ServerSyncs; i++)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "%s: sync=server fw=0x%x curr=0x%04x next=0x%04x id=%u%s",
+                                        pcszExtraInfo,
+                                        pui32FWAddr[i],
+                                        pui32CurrentOp[i],
+                                        pui32NextOp[i],
+                                        pui32UID[i],
+                                        (pui32NextOp[i] - pui32CurrentOp[i] == 1) ? " *" : 
+                                        (pui32NextOp[i] - pui32CurrentOp[i] >  1) ? " **" : 
+                                        ""));
+               }
+       }
+
+err_free:
+       OSFreeMem(papsServerSync);
+       if (pui32UID)
+       {
+               OSFreeMem(pui32UID);
+       }
+       if (pui32FWAddr)
+       {
+               OSFreeMem(pui32FWAddr);
+       }
+       if (pui32CurrentOp)
+       {
+               OSFreeMem(pui32CurrentOp);
+       }
+       if (pui32NextOp)
+       {
+               OSFreeMem(pui32NextOp);
+       }
+       return eError;
+#else
+       PVR_UNREFERENCED_PARAMETER(ui32SyncCount);
+       PVR_UNREFERENCED_PARAMETER(papsSync);
+       PVR_UNREFERENCED_PARAMETER(pcszExtraInfo);
+       return PVRSRV_OK;
+#endif
+}
+#endif
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimOpCreate(IMG_UINT32 ui32SyncCount,
+                                                         PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim,
+                                                         PSYNC_OP_COOKIE *ppsCookie)
+{
+       SYNC_OP_COOKIE *psNewCookie;
+       SYNC_BLOCK_LIST *psSyncBlockList;
+       IMG_UINT32 ui32ServerSyncCount = 0;
+       IMG_UINT32 ui32ClientSyncCount = 0;
+       IMG_UINT32 ui32ServerAllocSize;
+       IMG_UINT32 ui32ClientAllocSize;
+       IMG_UINT32 ui32TotalAllocSize;
+       IMG_UINT32 ui32ServerIndex = 0;
+       IMG_UINT32 ui32ClientIndex = 0;
+       IMG_UINT32 i;
+       IMG_UINT32 ui32SyncBlockCount;
+       IMG_HANDLE hBridge;
+       IMG_HANDLE *pahHandleList;
+       IMG_CHAR *pcPtr;
+       PVRSRV_ERROR eError;
+
+       psSyncBlockList = _SyncPrimBlockListCreate();
+       
+       if (!psSyncBlockList)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               if (SyncPrimIsServerSync(papsSyncPrim[i]))
+               {
+                       ui32ServerSyncCount++;
+               }
+               else
+               {
+                       SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
+
+                       ui32ClientSyncCount++;
+                       eError = _SyncPrimBlockListAdd(psSyncBlockList, psSync->u.sLocal.psSyncBlock);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto e1;
+                       }
+               }
+       }
+
+       ui32ServerAllocSize = ui32ServerSyncCount * (sizeof(IMG_HANDLE) + sizeof(IMG_UINT32));
+       ui32ClientAllocSize = ui32ClientSyncCount * (5 * sizeof(IMG_UINT32));
+       ui32TotalAllocSize = sizeof(SYNC_OP_COOKIE) +
+                                                        (sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount) +
+                                                        ui32ServerAllocSize + 
+                                                        ui32ClientAllocSize;
+
+       psNewCookie = OSAllocMem(ui32TotalAllocSize);
+       pcPtr = (IMG_CHAR *) psNewCookie;
+
+       if (!psNewCookie)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e1;
+       }
+
+       /* Setup the pointers */
+       pcPtr += sizeof(SYNC_OP_COOKIE);
+       psNewCookie->papsSyncPrim = (PVRSRV_CLIENT_SYNC_PRIM **) pcPtr;
+
+       pcPtr += sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount;
+       psNewCookie->paui32SyncBlockIndex = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32Index = (IMG_UINT32 *) pcPtr;
+       
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32Flags = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32FenceValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->paui32UpdateValue = (IMG_UINT32 *) pcPtr;
+
+       pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
+       psNewCookie->pahServerSync =(IMG_HANDLE *) pcPtr;
+       pcPtr += sizeof(IMG_HANDLE) * ui32ServerSyncCount;
+
+       psNewCookie->paui32ServerFlags =(IMG_UINT32 *) pcPtr;
+       pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;
+
+       /* Check the pointer setup went ok */
+       if (!(pcPtr == (((IMG_CHAR *) psNewCookie) + ui32TotalAllocSize)))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: cookie setup failed", __FUNCTION__));
+               eError = PVRSRV_ERROR_INTERNAL_ERROR;
+               goto e1;
+       }
+
+       psNewCookie->ui32SyncCount = ui32SyncCount;
+       psNewCookie->ui32ServerSyncCount = ui32ServerSyncCount;
+       psNewCookie->ui32ClientSyncCount = ui32ClientSyncCount;
+       psNewCookie->psSyncBlockList = psSyncBlockList;
+
+       /*
+               Get the bridge handle from the 1st sync.
+
+               Note: We assume the all syncs have been created with the same
+                         services connection.
+       */
+       if (SyncPrimIsServerSync(papsSyncPrim[0]))
+       {
+               SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
+
+               hBridge = psSync->u.sServer.hBridge;
+       }
+       else
+       {
+               SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
+
+               hBridge = psSync->u.sLocal.psSyncBlock->psContext->hBridge;             
+       }
+
+       psNewCookie->hBridge = hBridge;
+
+       if (ui32ServerSyncCount)
+       {
+               psNewCookie->bHaveServerSync = IMG_TRUE;
+       }
+       else
+       {
+               psNewCookie->bHaveServerSync = IMG_FALSE;
+       }
+
+       /* Fill in the server and client sync data */
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
+
+               if (SyncPrimIsServerSync(papsSyncPrim[i]))
+               {
+                       psNewCookie->pahServerSync[ui32ServerIndex] = psSync->u.sServer.hServerSync;
+
+                       ui32ServerIndex++;
+               }
+               else
+               {
+                       /* Location of sync */
+                       eError = _SyncPrimBlockListBlockToIndex(psSyncBlockList,
+                                                                                                       psSync->u.sLocal.psSyncBlock,
+                                                                                                       &psNewCookie->paui32SyncBlockIndex[ui32ClientIndex]);
+                       if (eError != PVRSRV_OK)
+                       {
+                               goto e2;
+                       }
+
+                       /* Workout the index to sync */
+                       psNewCookie->paui32Index[ui32ClientIndex] =
+                                       SyncPrimGetOffset(psSync)/sizeof(IMG_UINT32);
+
+                       ui32ClientIndex++;
+               }
+
+               psNewCookie->papsSyncPrim[i] = papsSyncPrim[i];
+       }
+
+       eError = _SyncPrimBlockListHandleArrayCreate(psSyncBlockList,
+                                                                                                &ui32SyncBlockCount,
+                                                                                                &pahHandleList);
+       if (eError !=PVRSRV_OK)
+       {
+               goto e2;
+       }
+
+       /*
+               Create the server side cookie. Here we pass in all the unchanging
+               data so we only need to pass in the minimum at takeop time
+       */
+       eError = BridgeSyncPrimOpCreate(hBridge,
+                                                                       ui32SyncBlockCount,
+                                                                       pahHandleList,
+                                                                       psNewCookie->ui32ClientSyncCount,
+                                                                       psNewCookie->paui32SyncBlockIndex,
+                                                                       psNewCookie->paui32Index,
+                                                                       psNewCookie->ui32ServerSyncCount,
+                                                                       psNewCookie->pahServerSync,
+                                                                       &psNewCookie->hServerCookie);
+
+       /* Free the handle list regardless of error */
+       _SyncPrimBlockListHandleArrayDestroy(pahHandleList);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto e2;
+       }
+
+       /* Increase the reference count on all referenced local sync prims
+        * so that they cannot be freed until this Op is finished with
+        */
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               SYNC_PRIM *psSyncInt;
+               psSyncInt = IMG_CONTAINER_OF(papsSyncPrim[i], SYNC_PRIM, sCommon);
+               if (SYNC_PRIM_TYPE_LOCAL == psSyncInt->eType)
+               {
+                       SyncPrimLocalRef(psSyncInt);
+               }
+       }
+
+       *ppsCookie = psNewCookie;
+       return PVRSRV_OK;
+
+e2:
+       OSFreeMem(psNewCookie);
+e1:
+       _SyncPrimBlockListDestroy(psSyncBlockList);
+e0:
+       return eError;
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimOpTake(PSYNC_OP_COOKIE psCookie,
+                                                       IMG_UINT32 ui32SyncCount,
+                                                       PVRSRV_CLIENT_SYNC_PRIM_OP *pasSyncOp)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 ui32ServerIndex = 0;
+       IMG_UINT32 ui32ClientIndex = 0;
+       IMG_UINT32 i;
+
+       /* Copy client sync operations */
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               /*
+                       Sanity check the client passes in the same syncs as the
+                       ones we got at create time
+               */
+               if (psCookie->papsSyncPrim[i] != pasSyncOp[i].psSync)
+               {
+                       return PVRSRV_ERROR_INVALID_PARAMS;
+               }
+
+               if (SyncPrimIsServerSync(pasSyncOp[i].psSync))
+               {
+                       psCookie->paui32ServerFlags[ui32ServerIndex] =
+                                       pasSyncOp[i].ui32Flags;
+
+                       ui32ServerIndex++;
+               }
+               else
+               {
+                       /* Client operation information */
+                       psCookie->paui32Flags[ui32ClientIndex] =
+                                       pasSyncOp[i].ui32Flags;
+                       psCookie->paui32FenceValue[ui32ClientIndex] =
+                                       pasSyncOp[i].ui32FenceValue;
+                       psCookie->paui32UpdateValue[ui32ClientIndex] =
+                                       pasSyncOp[i].ui32UpdateValue;
+
+                       ui32ClientIndex++;
+               }
+       }
+
+       eError = BridgeSyncPrimOpTake(psCookie->hBridge,
+                                                                 psCookie->hServerCookie,
+                                                                 psCookie->ui32ClientSyncCount,
+                                                                 psCookie->paui32Flags,
+                                                                 psCookie->paui32FenceValue,
+                                                                 psCookie->paui32UpdateValue,
+                                                                 psCookie->ui32ServerSyncCount,
+                                                                 psCookie->paui32ServerFlags);
+
+       return eError;
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimOpReady(PSYNC_OP_COOKIE psCookie,
+                                                        IMG_BOOL *pbReady)
+{
+       PVRSRV_ERROR eError;
+       if (!psCookie)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       /*
+               If we have a server sync we have no choice
+               but to do the check in the server
+       */
+       if (psCookie->bHaveServerSync)
+       {
+               eError = BridgeSyncPrimOpReady(psCookie->hBridge,
+                                                                          psCookie->hServerCookie,
+                                                                          pbReady);
+               if (eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,
+                                        "%s: Failed to do sync check in server (Error = %d)",
+                                        __FUNCTION__, eError));
+                       goto e0;
+               }
+       }
+       else
+       {
+               IMG_UINT32 i;
+               IMG_UINT32 ui32SnapShot;
+               IMG_BOOL bReady = IMG_TRUE;
+
+               for (i=0;i<psCookie->ui32ClientSyncCount;i++)
+               {
+                       if ((psCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK) == 0)
+                       {
+                               continue;
+                       }
+
+                       ui32SnapShot = _SyncPrimBlockListGetClientValue(psCookie->psSyncBlockList,
+                                                                                                                       psCookie->paui32SyncBlockIndex[i],
+                                                                                                                       psCookie->paui32Index[i]);
+                       if (ui32SnapShot != psCookie->paui32FenceValue[i])
+                       {
+                               bReady = IMG_FALSE;
+                               break;
+                       }
+               }
+
+               *pbReady = bReady;
+       }
+
+       return PVRSRV_OK;
+e0:
+       return eError;
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimOpComplete(PSYNC_OP_COOKIE psCookie)
+{
+       PVRSRV_ERROR eError;
+
+       eError = BridgeSyncPrimOpComplete(psCookie->hBridge,
+                                                                         psCookie->hServerCookie);
+
+       return eError;
+}
+
+IMG_INTERNAL
+IMG_VOID SyncPrimOpDestroy(PSYNC_OP_COOKIE psCookie)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 i;
+
+       /* Decrease the reference count on all referenced local sync prims
+        * so that they can be freed now this Op is finished with
+        */
+       for (i=0;i<psCookie->ui32SyncCount;i++)
+       {
+               SYNC_PRIM *psSyncInt;
+               psSyncInt = IMG_CONTAINER_OF(psCookie->papsSyncPrim[i], SYNC_PRIM, sCommon);
+               if (SYNC_PRIM_TYPE_LOCAL == psSyncInt->eType)
+               {
+                       SyncPrimLocalUnref(psSyncInt);
+               }
+       }
+
+       eError = BridgeSyncPrimOpDestroy(psCookie->hBridge, psCookie->hServerCookie);
+       if (PVRSRV_OK != eError)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                       "%s: Failed to destroy SyncPrimOp (Error = %d)",
+                        __FUNCTION__, eError));
+       }
+
+       _SyncPrimBlockListDestroy(psCookie->psSyncBlockList);
+       OSFreeMem(psCookie);
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimOpResolve(PSYNC_OP_COOKIE psCookie,
+                                                          IMG_UINT32 *pui32SyncCount,
+                                                          PVRSRV_CLIENT_SYNC_PRIM_OP **ppsSyncOp)
+{
+       IMG_UINT32 ui32ServerIndex = 0;
+       IMG_UINT32 ui32ClientIndex = 0;
+       PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOps;
+       IMG_UINT32 i;
+
+       psSyncOps = OSAllocMem(sizeof(PVRSRV_CLIENT_SYNC_PRIM_OP) * 
+                                                  psCookie->ui32SyncCount);
+       if (!psSyncOps)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+       
+       for (i=0; i<psCookie->ui32SyncCount; i++)
+       {
+               psSyncOps[i].psSync = psCookie->papsSyncPrim[i];
+               if (SyncPrimIsServerSync(psCookie->papsSyncPrim[i]))
+               {
+                       psSyncOps[i].ui32FenceValue = 0;
+                       psSyncOps[i].ui32UpdateValue = 0;
+                       psSyncOps[i].ui32Flags = psCookie->paui32ServerFlags[ui32ServerIndex];
+                       ui32ServerIndex++;
+               }
+               else
+               {
+                       psSyncOps[i].ui32FenceValue = psCookie->paui32FenceValue[ui32ClientIndex]; 
+                       psSyncOps[i].ui32UpdateValue = psCookie->paui32UpdateValue[ui32ClientIndex]; 
+                       psSyncOps[i].ui32Flags = psCookie->paui32Flags[ui32ClientIndex];
+                       ui32ClientIndex++;
+               }
+       }
+
+       *ppsSyncOp = psSyncOps;
+       *pui32SyncCount = psCookie->ui32SyncCount;
+
+       return PVRSRV_OK;
+}
+
+#if !defined(__KERNEL__)
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimServerAlloc(SYNC_BRIDGE_HANDLE hBridge,
+                                                                IMG_HANDLE hDeviceNode,
+                                                                PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                                                const IMG_CHAR *pszClassName
+                                                                PVR_DBG_FILELINE_PARAM)
+{
+       IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
+       SYNC_PRIM *psNewSync;
+       PVRSRV_ERROR eError;
+
+#if !defined(PVR_SYNC_PRIM_ALLOC_TRACE)
+       PVR_DBG_FILELINE_UNREF();
+#endif
+       psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
+       if (psNewSync == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+       OSCachedMemSet(psNewSync, 0, sizeof(SYNC_PRIM));
+
+       if(pszClassName)
+       {
+               /* Copy the class name annotation into a fixed-size array */
+               OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
+               szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
+       }
+       else
+       {
+               /* No class name annotation */
+               szClassName[0] = 0;
+       }
+
+       eError = BridgeServerSyncAlloc(hBridge,
+                                                                  hDeviceNode,
+                                                                  &psNewSync->u.sServer.hServerSync,
+                                                                  &psNewSync->u.sServer.ui32FirmwareAddr,
+                                                                  OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
+                                                                  szClassName);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto e1;
+       }
+
+#if defined(PVR_SYNC_PRIM_ALLOC_TRACE)
+       PVR_DPF((PVR_DBG_WARNING, "Allocated sync=server fw=0x%x [%p]" PVR_DBG_FILELINE_FMT,
+                        psNewSync->u.sServer.ui32FirmwareAddr, &psNewSync->sCommon PVR_DBG_FILELINE_ARG));
+#endif
+
+       psNewSync->eType = SYNC_PRIM_TYPE_SERVER;
+       psNewSync->u.sServer.hBridge = hBridge;
+       *ppsSync = &psNewSync->sCommon;
+
+       return PVRSRV_OK;
+e1:
+       OSFreeMem(psNewSync);
+e0:
+       return eError;
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimServerGetStatus(IMG_UINT32 ui32SyncCount,
+                                                                        PVRSRV_CLIENT_SYNC_PRIM **papsSync,
+                                                                        IMG_UINT32 *pui32UID,
+                                                                        IMG_UINT32 *pui32FWAddr,
+                                                                        IMG_UINT32 *pui32CurrentOp,
+                                                                        IMG_UINT32 *pui32NextOp)
+{
+       PVRSRV_ERROR eError;
+       IMG_UINT32 i;
+       SYNC_BRIDGE_HANDLE hBridge = NULL;
+       IMG_HANDLE *pahServerHandle;
+
+       if (papsSync[0])
+       {
+               hBridge = _SyncPrimGetBridgeHandle(papsSync[0]);
+       }
+       if (!hBridge)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid Sync connection\n", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
+               goto e0;
+       }
+
+       pahServerHandle = OSAllocMem(sizeof(IMG_HANDLE) * ui32SyncCount);
+       if (pahServerHandle == IMG_NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto e0;
+       }
+
+       /*
+               Check that all the sync we've been passed are server syncs
+               and that they all are on the same connection.
+       */
+       for (i=0;i<ui32SyncCount;i++)
+       {
+               SYNC_PRIM *psIntSync = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
+
+               if (!SyncPrimIsServerSync(papsSync[i]))
+               {
+                       eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
+                       goto e1;
+               }
+
+               if (!papsSync[i] || hBridge != _SyncPrimGetBridgeHandle(papsSync[i]))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "SyncServerGetStatus: Sync connection is different\n"));
+                       eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
+                       goto e1;
+               }
+
+               pahServerHandle[i] = psIntSync->u.sServer.hServerSync;
+       }
+
+       eError = BridgeServerSyncGetStatus(hBridge,
+                                                                          ui32SyncCount,
+                                                                          pahServerHandle,
+                                                                          pui32UID,
+                                                                          pui32FWAddr,
+                                                                          pui32CurrentOp,
+                                                                          pui32NextOp);
+       OSFreeMem(pahServerHandle);
+
+       if (eError != PVRSRV_OK)
+       {
+               goto e0;
+       }
+       return PVRSRV_OK;
+
+e1:
+       OSFreeMem(pahServerHandle);
+e0:
+       return eError;
+}
+
+#endif
+
+IMG_INTERNAL
+IMG_BOOL SyncPrimIsServerSync(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
+               goto e0;
+       }
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+       {
+               return IMG_TRUE;
+       }
+
+e0:
+       return IMG_FALSE;
+}
+
+IMG_INTERNAL
+IMG_HANDLE SyncPrimGetServerHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+
+       if (!psSync)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
+               goto e0;
+       }
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
+       {
+               return psSyncInt->u.sServer.hServerSync;
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid sync type (%d)",
+                       __FUNCTION__, psSyncInt->eType));
+               goto e0;
+       }
+e0:
+       return 0;
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SyncPrimServerQueueOp(PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOp)
+{
+       SYNC_PRIM *psSyncInt;
+       IMG_BOOL bUpdate;
+       PVRSRV_ERROR eError;
+
+       if (!psSyncOp)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_PARAMS;
+               goto e0;
+       }
+
+       psSyncInt = IMG_CONTAINER_OF(psSyncOp->psSync, SYNC_PRIM, sCommon);
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_SERVER)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: invalid sync type (%d)",
+                       __FUNCTION__, psSyncInt->eType));
+               eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
+               goto e0;
+       }
+       if (0 == psSyncOp->ui32Flags)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: no sync flags", __FUNCTION__));
+               eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
+               goto e0;
+       }
+
+       if (psSyncOp->ui32Flags & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
+       {
+               bUpdate = IMG_TRUE;
+       }else
+       {
+               bUpdate = IMG_FALSE;
+       }
+
+       eError = BridgeServerSyncQueueHWOp(psSyncInt->u.sServer.hBridge,
+                                                                             psSyncInt->u.sServer.hServerSync,
+                                                                                 bUpdate,
+                                                                             &psSyncOp->ui32FenceValue,
+                                                                             &psSyncOp->ui32UpdateValue);
+e0:
+       return eError;
+}
+
+#if defined(PDUMP)
+IMG_INTERNAL IMG_VOID SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       SYNC_PRIM *psSyncInt;
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM_CONTEXT *psContext;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psSync != IMG_NULL);
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
+               PVR_ASSERT(IMG_FALSE);
+               return;
+       }
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       psContext = psSyncBlock->psContext;
+
+       eError = BridgeSyncPrimPDump(psContext->hBridge,
+                                                                psSyncBlock->hServerSyncPrimBlock,
+                                                                SyncPrimGetOffset(psSyncInt));
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
+{
+       SYNC_PRIM *psSyncInt;
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM_CONTEXT *psContext;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psSync != IMG_NULL);
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
+               PVR_ASSERT(IMG_FALSE);
+               return;
+       }
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       psContext = psSyncBlock->psContext;
+
+       eError = BridgeSyncPrimPDumpValue(psContext->hBridge,
+                                                                psSyncBlock->hServerSyncPrimBlock,
+                                                                SyncPrimGetOffset(psSyncInt),
+                                                                ui32Value);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                          IMG_UINT32 ui32Value,
+                                                                          IMG_UINT32 ui32Mask,
+                                                                          PDUMP_POLL_OPERATOR eOperator,
+                                                                          IMG_UINT32 ui32PDumpFlags)
+{
+       SYNC_PRIM *psSyncInt;
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM_CONTEXT *psContext;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psSync != IMG_NULL);
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpPol: Invalid sync type (expected SYNC_PRIM_TYPE_LOCAL)"));
+               PVR_ASSERT(IMG_FALSE);
+               return;
+       }
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       psContext = psSyncBlock->psContext;
+
+       eError = BridgeSyncPrimPDumpPol(psContext->hBridge,
+                                                                       psSyncBlock->hServerSyncPrimBlock,
+                                                                       SyncPrimGetOffset(psSyncInt),
+                                                                       ui32Value,
+                                                                       ui32Mask,
+                                                                       eOperator,
+                                                                       ui32PDumpFlags);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimOpPDumpPol(PSYNC_OP_COOKIE psCookie,
+                                                                          PDUMP_POLL_OPERATOR eOperator,
+                                                                          IMG_UINT32 ui32PDumpFlags)
+{
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psCookie != IMG_NULL);
+
+       eError = BridgeSyncPrimOpPDumpPol(psCookie->hBridge,
+                                                                       psCookie->hServerCookie,
+                                                                       eOperator,
+                                                                       ui32PDumpFlags);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+       
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL IMG_VOID SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                                          IMG_UINT64 uiWriteOffset,
+                                                                          IMG_UINT64 uiPacketSize,
+                                                                          IMG_UINT64 uiBufferSize)
+{
+       SYNC_PRIM *psSyncInt;
+       SYNC_PRIM_BLOCK *psSyncBlock;
+       SYNC_PRIM_CONTEXT *psContext;
+       PVRSRV_ERROR eError;
+
+       PVR_ASSERT(psSync != IMG_NULL);
+       psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
+
+       if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpCBP: Invalid sync type"));
+               PVR_ASSERT(IMG_FALSE);
+               return;
+       }
+
+       psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
+       psContext = psSyncBlock->psContext;
+
+       /* FIXME: uiWriteOffset, uiPacketSize, uiBufferSize were changed to
+        * 64-bit quantities to resolve Windows compiler warnings.
+        * However the bridge is only 32-bit hence compiler warnings
+        * of implicit cast and loss of data.
+        * Added explicit cast and assert to remove warning.
+        */
+#if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
+       PVR_ASSERT(uiWriteOffset<IMG_UINT32_MAX);
+       PVR_ASSERT(uiPacketSize<IMG_UINT32_MAX);
+       PVR_ASSERT(uiBufferSize<IMG_UINT32_MAX);
+#endif
+       eError = BridgeSyncPrimPDumpCBP(psContext->hBridge,
+                                                                       psSyncBlock->hServerSyncPrimBlock,
+                                                                       SyncPrimGetOffset(psSyncInt),
+                                                                       (IMG_UINT32)uiWriteOffset,
+                                                                       (IMG_UINT32)uiPacketSize,
+                                                                       (IMG_UINT32)uiBufferSize);
+
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                               "%s: failed with error %d",
+                               __FUNCTION__, eError));
+       }
+    PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+#endif
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/tlclient.c b/drivers/gpu/rogue_m/services/shared/common/tlclient.c
new file mode 100644 (file)
index 0000000..f21a6a3
--- /dev/null
@@ -0,0 +1,365 @@
+/*************************************************************************/ /*!
+@File                  tlclient.c
+@Title          Services Transport Layer shared API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport layer common API used in both clients and server
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* DESIGN NOTE
+ * This transport layer consumer-role API was created as a shared API when a
+ * client wanted to read the data of a TL stream from within the KM server
+ * driver. This was in addition to the existing clients supported externally
+ * by the UM client library component via PVR API layer.
+ * This shared API is thus used by the PVR TL API in the client library and
+ * by clients internal to the server driver module. It depends on
+ * client entry points of the TL and DEVMEM bridge modules. These entry points
+ * encapsulate from the TL shared API whether a direct bridge or an indirect
+ * (ioctl) bridge is used.
+ * One reason for needing this layer centres around the fact that some of the
+ * API functions make multiple bridge calls and the logic that glues these
+ * together is common regardless of client location. Further this layer has
+ * allowed the defensive coding that checks parameters to move into the PVR
+ * API layer where untrusted clients enter giving a more efficient KM code path.
+ */
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "pvr_debug.h"
+#include "osfunc.h"
+
+#include "allocmem.h"
+#include "devicemem.h"
+
+#include "tlclient.h"
+#include "client_pvrtl_bridge.h"
+
+/* Defines/Constants
+ */
+
+#define PVR_CONNECT_NO_FLAGS   0x00U
+#define NO_ACQUIRE                             0xffffffffU
+#define DIRECT_BRIDGE_HANDLE   ((IMG_HANDLE)0xDEADBEEFU)
+
+/* User-side stream descriptor structure.
+ */
+typedef struct _TL_STREAM_DESC_
+{
+       /* Handle on kernel-side stream descriptor*/
+       IMG_HANDLE              hServerSD;
+
+       /* Stream data buffer variables */
+       DEVMEM_EXPORTCOOKIE             sExportCookie;
+       DEVMEM_MEMDESC*                 psUMmemDesc;
+       IMG_PBYTE                               pBaseAddr;
+
+       /* Offset in bytes into the circular buffer and valid only after
+        * an Acquire call and undefined after a release. */
+       IMG_UINT32      uiReadOffset;
+
+       /* Always a positive integer when the Acquire call returns and a release
+        * is outstanding. Undefined at all other times. */
+       IMG_UINT32      uiReadLen;
+
+} TL_STREAM_DESC, *PTL_STREAM_DESC;
+
+
+/* Used in direct connections only */
+IMG_INTERNAL
+PVRSRV_ERROR TLClientConnect(IMG_HANDLE* phSrvHandle)
+{
+       /* Check the caller provided valid pointer*/
+       if(!phSrvHandle)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLClientConnect: Null connection handle"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *phSrvHandle = DIRECT_BRIDGE_HANDLE;
+
+       return PVRSRV_OK;
+
+
+}
+
+
+/* Used in direct connections only */
+IMG_INTERNAL
+PVRSRV_ERROR IMG_CALLCONV TLClientDisconnect(IMG_HANDLE hSrvHandle)
+{
+       if (hSrvHandle != (IMG_HANDLE)0xDEADBEEF)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLClientDisconnect: Invalid connection handle"));
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       return PVRSRV_OK;
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR TLClientOpenStream(IMG_HANDLE hSrvHandle,
+               IMG_PCHAR    pszName,
+               IMG_UINT32   ui32Mode,
+               IMG_HANDLE*  phSD)
+{
+       PVRSRV_ERROR                            eError = PVRSRV_OK;
+       TL_STREAM_DESC*                         psSD = 0;
+       DEVMEM_SERVER_EXPORTCOOKIE      hServerExportCookie;
+
+       PVR_ASSERT(hSrvHandle);
+       PVR_ASSERT(pszName);
+       PVR_ASSERT(phSD);
+       *phSD = NULL;
+
+       /* Allocate memory for the stream descriptor object, initialise with
+        * "no data read" yet. */
+       psSD = OSAllocZMem(sizeof(TL_STREAM_DESC));
+       if (psSD == NULL)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               PVR_DPF((PVR_DBG_ERROR, "BridgeTLOpenStream: KM returned %d", eError));
+               goto e0;
+       }
+       psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE;
+
+       /* Send open stream request to kernel server to get stream handle and
+        * buffer cookie so we can get access to the buffer in this process. */
+       eError = BridgeTLOpenStream(hSrvHandle, pszName, ui32Mode,
+                                                                               &psSD->hServerSD, &hServerExportCookie);
+       if (eError != PVRSRV_OK)
+       {
+           if ((ui32Mode & PVRSRV_STREAM_FLAG_OPEN_WAIT) &&
+                   (eError == PVRSRV_ERROR_TIMEOUT))
+           {
+               goto e1;
+           }
+           PVR_LOGG_IF_ERROR(eError, "BridgeTLOpenStream", e1);
+       }
+
+       /* Convert server export cookie into a cookie for use by this client */
+       eError = DevmemMakeServerExportClientExport(hSrvHandle,
+                                                                       hServerExportCookie, &psSD->sExportCookie);
+       PVR_LOGG_IF_ERROR(eError, "DevmemMakeServerExportClientExport", e2);
+
+       /* Now convert client cookie into a client handle on the buffer's
+        * physical memory region */
+       eError = DevmemImport(hSrvHandle, &psSD->sExportCookie,
+                                               PVRSRV_MEMALLOCFLAG_CPU_READABLE, &psSD->psUMmemDesc);
+       PVR_LOGG_IF_ERROR(eError, "DevmemImport", e3);
+
+       /* Now map the memory into the virtual address space of this process. */
+       eError = DevmemAcquireCpuVirtAddr(psSD->psUMmemDesc, (IMG_PVOID *)
+                                                                                                                       &psSD->pBaseAddr);
+       PVR_LOGG_IF_ERROR(eError, "DevmemAcquireCpuVirtAddr", e4);
+
+       /* Return client descriptor handle to caller */
+       *phSD = psSD;
+       return PVRSRV_OK;
+
+/* Clean up post buffer setup */
+e4:
+       DevmemFree(psSD->psUMmemDesc);
+e3:
+       (void) DevmemUnmakeServerExportClientExport(hSrvHandle,
+                               &psSD->sExportCookie);
+/* Clean up post stream open */
+e2:
+       BridgeTLCloseStream(hSrvHandle, psSD->hServerSD);
+
+/* Cleanup post allocation of the descriptor object */
+e1:
+       OSFreeMem(psSD);
+
+e0:
+       return eError;
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR TLClientCloseStream(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE hSD)
+{
+       PVRSRV_ERROR          eError = PVRSRV_OK;
+       TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD;
+
+       PVR_ASSERT(hSrvHandle);
+       PVR_ASSERT(hSD);
+
+       /* Check the caller provided connection is valid */
+       if(!psSD->hServerSD)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLClientCloseStream: descriptor already closed/not open"));
+               return PVRSRV_ERROR_HANDLE_NOT_FOUND;
+       }
+
+       /* Check if acquire is outstanding, perform release if it is, ignore result
+        * as there is not much we can do if it is an error other than close */
+       if (psSD->uiReadLen != NO_ACQUIRE)
+       {
+               (void) BridgeTLReleaseData(hSrvHandle, psSD->hServerSD,
+                                                                       psSD->uiReadOffset, psSD->uiReadLen);
+               psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE;
+       }
+
+       /* Clean up DevMem resources used for this stream in this client */
+       DevmemReleaseCpuVirtAddr(psSD->psUMmemDesc);
+
+       DevmemFree(psSD->psUMmemDesc);
+
+       /* Ignore error, not much that can be done */
+       (void) DevmemUnmakeServerExportClientExport(hSrvHandle,
+                       &psSD->sExportCookie);
+
+
+       /* Send close to server to clean up kernel mode resources for this
+        * handle and release the memory. */
+       eError = BridgeTLCloseStream(hSrvHandle, psSD->hServerSD);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "BridgeTLCloseStream: KM returned %d", eError));
+               /*/ Not much we can do with error, fall through to clean up
+                * return eError; */
+       }
+
+       OSCachedMemSet(psSD, 0x00, sizeof(TL_STREAM_DESC));
+       OSFreeMem (psSD);
+
+       return eError;
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR TLClientAcquireData(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE  hSD,
+               IMG_PBYTE*  ppPacketBuf,
+               IMG_UINT32* pui32BufLen)
+{
+       PVRSRV_ERROR              eError = PVRSRV_OK;
+       TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD;
+
+       PVR_ASSERT(hSrvHandle);
+       PVR_ASSERT(hSD);
+       PVR_ASSERT(ppPacketBuf);
+       PVR_ASSERT(pui32BufLen);
+
+       /* Check Acquire has not been called twice in a row without a release */
+       if (psSD->uiReadOffset != NO_ACQUIRE)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLClientAcquireData: acquire already outstanding"));
+               return PVRSRV_ERROR_RETRY;
+       }
+
+       *pui32BufLen = 0;
+       /* Ask the kernel server for the next chunk of data to read */
+       eError = BridgeTLAcquireData(hSrvHandle, psSD->hServerSD,
+                                                                       &psSD->uiReadOffset, &psSD->uiReadLen);
+       if (eError != PVRSRV_OK)
+       {
+               if ((eError != PVRSRV_ERROR_RESOURCE_UNAVAILABLE) &&
+                       (eError != PVRSRV_ERROR_TIMEOUT))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "BridgeTLAcquireData: KM returned %d", eError));
+               }
+               psSD->uiReadOffset = psSD->uiReadLen = NO_ACQUIRE;
+               return eError;
+       }
+
+       /* Return the data offset and length to the caller if bytes are available
+        * to be read. Could be zero for non-blocking mode. */
+       if (psSD->uiReadLen)
+       {
+               *ppPacketBuf = psSD->pBaseAddr + psSD->uiReadOffset;
+               *pui32BufLen = psSD->uiReadLen;
+       }
+       else
+       {
+               /* On non blocking, zero length data could be returned from server
+                * Which is basically a no-acquire operation */
+               *ppPacketBuf = 0;
+               *pui32BufLen = 0;
+       }
+
+       return eError;
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR TLClientReleaseData(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE hSD)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       TL_STREAM_DESC* psSD = (TL_STREAM_DESC*) hSD;
+
+       PVR_ASSERT(hSrvHandle);
+       PVR_ASSERT(hSD);
+
+       /* the previous acquire did not return any data, this is a no-operation */
+       if (psSD->uiReadLen == 0)
+       {
+               return PVRSRV_OK;
+       }
+
+       /* Check release has not been called twice in a row without an acquire */
+       if (psSD->uiReadOffset == NO_ACQUIRE)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "TLClientReleaseData_: no acquire to release"));
+               return PVRSRV_ERROR_RETRY;
+       }
+
+       /* Inform the kernel to release the data from the buffer */
+       eError = BridgeTLReleaseData(hSrvHandle, psSD->hServerSD,
+                                                                               psSD->uiReadOffset, psSD->uiReadLen);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "BridgeTLReleaseData: KM returned %d", eError));
+               /* Need to continue to keep client data consistent, fall through
+                * return eError */
+       }
+
+       /* Reset state to indicate no outstanding acquire */
+       psSD->uiReadLen = psSD->uiReadOffset = NO_ACQUIRE;
+
+       return eError;
+}
+
+
+/******************************************************************************
+ End of file (tlclient.c)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.c b/drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.c
new file mode 100644 (file)
index 0000000..8429609
--- /dev/null
@@ -0,0 +1,244 @@
+/*************************************************************************/ /*!
+@File
+@Title          Provides splay-trees.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implementation of splay-trees.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "allocmem.h" /* for OSMemAlloc / OSMemFree */
+#include "osfunc.h" /* for OSMemFree */
+#include "pvr_debug.h"
+#include "uniq_key_splay_tree.h"
+
+/**
+ * This function performs a simple top down splay
+ *
+ * @param ui32Flags the flags that must splayed to the root (if possible).
+ * @param psTree The tree to splay.
+ * @return the resulting tree after the splay operation.
+ */
+IMG_INTERNAL
+IMG_PSPLAY_TREE PVRSRVSplay (IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree) 
+{
+       IMG_SPLAY_TREE sTmp1;
+       IMG_PSPLAY_TREE psLeft;
+       IMG_PSPLAY_TREE psRight;
+       IMG_PSPLAY_TREE psTmp2;
+
+       if (psTree == IMG_NULL)
+       {
+               return IMG_NULL;
+       }
+       
+       sTmp1.psLeft = IMG_NULL;
+       sTmp1.psRight = IMG_NULL;
+
+       psLeft = &sTmp1;
+       psRight = &sTmp1;
+       
+    for (;;)
+       {
+               if (ui32Flags < psTree->ui32Flags)
+               {
+                       if (psTree->psLeft == IMG_NULL)
+                       {
+                               break;
+                       }
+                       
+                       if (ui32Flags < psTree->psLeft->ui32Flags)
+                       {
+                               /* if we get to this point, we need to rotate right the tree */
+                               psTmp2 = psTree->psLeft;
+                               psTree->psLeft = psTmp2->psRight;
+                               psTmp2->psRight = psTree;
+                               psTree = psTmp2;
+                               if (psTree->psLeft == IMG_NULL)
+                               {
+                                       break;
+                               }
+                       }
+
+                       /* if we get to this point, we need to link right */
+                       psRight->psLeft = psTree;
+                       psRight = psTree;
+                       psTree = psTree->psLeft;
+               }
+               else
+               {
+                       if (ui32Flags > psTree->ui32Flags)
+                       {
+                               if (psTree->psRight == IMG_NULL)
+                               {
+                                       break;
+                               }
+
+                               if (ui32Flags > psTree->psRight->ui32Flags)
+                               {
+                                       /* if we get to this point, we need to rotate left the tree */
+                                       psTmp2 = psTree->psRight;
+                                       psTree->psRight = psTmp2->psLeft;
+                                       psTmp2->psLeft = psTree;
+                                       psTree = psTmp2;
+                                       if (psTree->psRight == IMG_NULL)
+                                       {
+                                               break;
+                                       }
+                               }
+
+                               /* if we get to this point, we need to link left */
+                               psLeft->psRight = psTree;
+                               psLeft = psTree;
+                               psTree = psTree->psRight;
+                       }
+                       else
+                       {
+                               break;
+                       }
+               }
+    }
+
+       /* at this point re-assemble the tree */
+    psLeft->psRight = psTree->psLeft;
+    psRight->psLeft = psTree->psRight;
+    psTree->psLeft = sTmp1.psRight;
+    psTree->psRight = sTmp1.psLeft;
+    return psTree;
+}
+
+
+/**
+ * This function inserts a node into the Tree (unless it is already present, in
+ * which case it is equivalent to performing only a splay operation
+ *
+ * @param ui32Flags the key of the new node
+ * @param psTree The tree into which one wants to add a new node
+ * @return The resulting with the node in it
+ */
+IMG_INTERNAL
+IMG_PSPLAY_TREE PVRSRVInsert(IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree) 
+{
+    IMG_PSPLAY_TREE psNew;
+
+       if (psTree != IMG_NULL)
+       {
+               psTree = PVRSRVSplay(ui32Flags, psTree);
+               if (psTree->ui32Flags == ui32Flags)
+               {
+                       return psTree;
+               }
+       }
+       
+       psNew = (IMG_PSPLAY_TREE) OSAllocMem(sizeof(IMG_SPLAY_TREE));
+       if (psNew == IMG_NULL)
+       {
+               PVR_DPF ((PVR_DBG_ERROR, "Error: failed to allocate memory to add a node to the splay tree."));
+               return IMG_NULL;
+       }
+       
+       psNew->ui32Flags = ui32Flags;
+       OSCachedMemSet(&(psNew->buckets[0]), 0, sizeof(psNew->buckets));
+
+#if defined(HAS_BUILTIN_CTZLL)
+       psNew->bHasEltsMapping = ~(((IMG_ELTS_MAPPINGS) 1 << (sizeof(psNew->buckets) / (sizeof(psNew->buckets[0])))) - 1);
+#endif
+
+    if (psTree == IMG_NULL)
+       {
+               psNew->psLeft  = IMG_NULL;
+               psNew->psRight = IMG_NULL;
+               return psNew;
+    }
+
+    if (ui32Flags < psTree->ui32Flags)
+       {
+               psNew->psLeft  = psTree->psLeft;
+               psNew->psRight = psTree;
+               psTree->psLeft = IMG_NULL;
+    }
+       else 
+       {
+               psNew->psRight  = psTree->psRight;
+               psNew->psLeft   = psTree;
+               psTree->psRight = IMG_NULL;
+    }
+
+       return psNew;
+}
+
+
+/**
+ * Deletes a node from the tree (unless it is not there, in which case it is
+ * equivalent to a splay operation)
+ * 
+ * @param ui32Flags the value of the node to remove
+ * @param psTree the tree into which the node must be removed 
+ * @return the resulting tree
+ */
+IMG_INTERNAL
+IMG_PSPLAY_TREE PVRSRVDelete(IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree)
+{
+    IMG_PSPLAY_TREE psTmp;
+    if (psTree == IMG_NULL)
+       {
+               return IMG_NULL;
+       }
+
+    psTree = PVRSRVSplay(ui32Flags, psTree);
+    if (ui32Flags == psTree->ui32Flags)
+       {
+               /* The value was present in the tree */
+               if (psTree->psLeft == IMG_NULL)
+               {
+                       psTmp = psTree->psRight;
+               }
+               else
+               {
+                       psTmp = PVRSRVSplay(ui32Flags, psTree->psLeft);
+                       psTmp->psRight = psTree->psRight;
+               }
+               OSFreeMem(psTree);
+               return psTmp;
+    }
+
+       /* the value was not present in the tree, so just return it as is (after the
+        * splay) */
+    return psTree;
+}
+
+
diff --git a/drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.h b/drivers/gpu/rogue_m/services/shared/common/uniq_key_splay_tree.h
new file mode 100644 (file)
index 0000000..e58c0b7
--- /dev/null
@@ -0,0 +1,95 @@
+/*************************************************************************/ /*!
+@File
+@Title          Splay trees interface
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Provides debug functionality
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef UNIQ_KEY_SPLAY_TREE_H_
+#define UNIQ_KEY_SPLAY_TREE_H_
+
+#include "img_types.h"
+
+#if defined(__GNUC__) && defined(__x86_64__)
+  /* note, the 64 bits requirements should not be necessary.
+     Unfortunately, linking against the __ctzdi function (in 32bits) failed.  */
+
+  #define HAS_BUILTIN_CTZLL
+#endif
+
+#if defined(HAS_BUILTIN_CTZLL)
+  /* if the compiler can provide this builtin, then map the is_bucket_n_free?
+     into an int. This way, the driver can find the first non empty without loop */
+
+  typedef IMG_UINT64 IMG_ELTS_MAPPINGS;
+#endif
+
+
+/* head of list of free boundary tags for indexed by pvr_log2 of the
+   boundary tag size */
+#define FREE_TABLE_LIMIT 40
+
+struct _BT_;
+
+typedef struct img_splay_tree 
+{
+       /* left child/subtree */
+    struct img_splay_tree * psLeft;
+
+       /* right child/subtree */
+    struct img_splay_tree * psRight;
+
+    /* Flags to match on this span, used as the key. */
+    IMG_UINT32 ui32Flags;
+
+#if defined(HAS_BUILTIN_CTZLL)
+       /* each bit of this int is a boolean telling if the corresponding
+          bucket is empty or not */
+    IMG_ELTS_MAPPINGS bHasEltsMapping;
+#endif
+       
+       struct _BT_ * buckets[FREE_TABLE_LIMIT];
+} IMG_SPLAY_TREE, *IMG_PSPLAY_TREE;
+
+IMG_PSPLAY_TREE PVRSRVSplay (IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree);
+IMG_PSPLAY_TREE PVRSRVInsert(IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree);
+IMG_PSPLAY_TREE PVRSRVDelete(IMG_UINT32 ui32Flags, IMG_PSPLAY_TREE psTree);
+
+
+#endif /* !UNIQ_KEY_SPLAY_TREE_H_ */
diff --git a/drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.c b/drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.c
new file mode 100644 (file)
index 0000000..c045270
--- /dev/null
@@ -0,0 +1,150 @@
+/*************************************************************************/ /*!
+@File
+@Title          Functions for BVNC manipulating
+
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Utility functions used internally by device memory management
+                code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/******************************************************************************
+ * RGX Version packed into 24-bit (BNC) and string (V) to be used by Compatibility Check
+ *****************************************************************************/
+
+#include "rgx_compat_bvnc.h"
+
+IMG_VOID rgx_bvnc_packed(IMG_UINT32 *pui32OutBNC, IMG_CHAR *pszOutV, IMG_UINT32 ui32OutVMaxLen, 
+                                                               IMG_UINT32 ui32B, IMG_CHAR *pszV, IMG_UINT32 ui32N, IMG_UINT32 ui32C)
+{
+#if 0
+       IMG_UINT32 i = ui32OutVMaxLen;
+#endif
+       IMG_UINT32 ui32InVLen = 0;
+       IMG_UINT32 ui32V = 0;
+
+       *pui32OutBNC = (((ui32B & 0xFF) << 16) | ((ui32N & 0xFF) << 8) |
+                                                                                               (ui32C & 0xFF));
+
+       /* Using dword accesses instead of byte accesses when forming V part of BVNC */
+       ui32OutVMaxLen = ui32OutVMaxLen;
+       while (pszV[ui32InVLen])
+       {
+               ui32V |= ((((IMG_UINT32)pszV[ui32InVLen]) & 0xFF) << (ui32InVLen*8));
+               ui32InVLen++;
+       }
+
+       *((IMG_UINT32 *)pszOutV) = ui32V;
+
+#if 0
+       for (i = 0; i < (ui32OutVMaxLen + 1); i++)
+               pszOutV[i] = '\0';
+
+       while ((ui32OutVMaxLen > 0) && *pszV)
+       {
+               *pszOutV++ = *pszV++;
+               ui32OutVMaxLen--;
+       }
+#endif
+}
+
+IMG_VOID rgx_bvnc_pack_hw(IMG_UINT32 *pui32OutBNC, IMG_CHAR *pszOutV, IMG_UINT32 ui32OutVMaxLen, 
+                                                               IMG_UINT32 ui32B, IMG_CHAR *pszFwV, IMG_UINT32 ui32V, IMG_UINT32 ui32N, IMG_UINT32 ui32C)
+{
+       IMG_UINT32 i = ui32OutVMaxLen;
+       IMG_CHAR *pszPointer;
+
+       *pui32OutBNC = (((ui32B & 0xFF) << 16) | ((ui32N & 0xFF) << 8) |
+                                                                                               (ui32C & 0xFF));
+
+       for (i = 0; i < (ui32OutVMaxLen + 1); i++)
+               pszOutV[i] = '\0';
+
+       /* find out whether pszFwV is integer number or not */
+       pszPointer = pszFwV;
+       while (*pszPointer)
+       {
+               if ((*pszPointer < '0') || (*pszPointer > '9'))
+               {
+                       break;
+               }
+               pszPointer++;
+       }
+
+       if (*pszPointer)
+       {
+               /* pszFwV is not a number, so taking V from it */
+               pszPointer = pszFwV;
+               while ((ui32OutVMaxLen > 0) && *pszPointer)
+               {
+                       *pszOutV++ = *pszPointer++;
+                       ui32OutVMaxLen--;
+               }
+       }
+       else
+       {
+               /* pszFwV is a number, taking V from ui32V */
+               IMG_CHAR aszBuf[4];
+
+               pszPointer = aszBuf;
+
+               if (ui32V > 99)
+                       pszPointer+=3;
+               else if (ui32V > 9)
+                       pszPointer+=2;
+               else
+                       pszPointer+=1;
+
+               *pszPointer-- = '\0';
+               *pszPointer = '0';
+
+               while (ui32V > 0)
+               {
+                       *pszPointer-- = (ui32V % 10) + '0';
+                       ui32V /= 10;
+               }
+               
+               pszPointer = aszBuf;
+               while ((ui32OutVMaxLen > 0) && *pszPointer)
+               {
+                       *pszOutV++ = *pszPointer++;
+                       ui32OutVMaxLen--;
+               }
+       }
+}
+
diff --git a/drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.h b/drivers/gpu/rogue_m/services/shared/devices/rgx/rgx_compat_bvnc.h
new file mode 100644 (file)
index 0000000..61e11f0
--- /dev/null
@@ -0,0 +1,96 @@
+/*************************************************************************/ /*!
+@File
+@Title          Functions for BVNC manipulating
+
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Utility functions used internally by device memory management
+                code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__RGX_COMPAT_BVNC_H__)
+#define __RGX_COMPAT_BVNC_H__
+
+#include "img_types.h"
+
+/******************************************************************************
+ * RGX Version packed into 24-bit (BNC) and string (V) to be used by Compatibility Check
+ *****************************************************************************/
+
+#define RGX_BVNC_PACK_MASK_B 0x00FF0000
+#define RGX_BVNC_PACK_MASK_N 0x0000FF00
+#define RGX_BVNC_PACK_MASK_C 0x000000FF
+
+#define RGX_BVNC_PACKED_EXTR_B(BVNC) (((BVNC).ui32BNC >> 16) & 0xFF)
+#define RGX_BVNC_PACKED_EXTR_V(BVNC) ((BVNC).aszV)
+#define RGX_BVNC_PACKED_EXTR_N(BVNC) (((BVNC).ui32BNC >> 8) & 0xFF)
+#define RGX_BVNC_PACKED_EXTR_C(BVNC) (((BVNC).ui32BNC >> 0) & 0xFF)
+
+#define RGX_BVNC_EQUAL(L,R,all,version,lenmax,bnc,v) do {                                                                                                      \
+                                                                               (lenmax) = IMG_FALSE;                                                                                           \
+                                                                               (bnc) = IMG_FALSE;                                                                                                      \
+                                                                               (v) = IMG_FALSE;                                                                                                        \
+                                                                               (version) = ((L).ui32LayoutVersion == (R).ui32LayoutVersion);           \
+                                                                               if (version)                                                                                                            \
+                                                                               {                                                                                                                                       \
+                                                                                       (lenmax) = ((L).ui32VLenMax == (R).ui32VLenMax);                                \
+                                                                               }                                                                                                                                       \
+                                                                               if (lenmax)                                                                                                                     \
+                                                                               {                                                                                                                                       \
+                                                                                       (bnc) = ((L).ui32BNC == (R).ui32BNC);                                                   \
+                                                                               }                                                                                                                                       \
+                                                                               if (bnc)                                                                                                                        \
+                                                                               {                                                                                                                                       \
+                                                                                       (L).aszV[(L).ui32VLenMax] = '\0';                                                               \
+                                                                                       (R).aszV[(R).ui32VLenMax] = '\0';                                                               \
+                                                                                       (v) = (OSStringCompare((L).aszV, (R).aszV)==0);                                 \
+                                                                               }                                                                                                                                       \
+                                                                               (all) = (version) && (lenmax) && (bnc) && (v);                                          \
+                                                                       } while (0)
+
+IMG_VOID rgx_bvnc_packed(IMG_UINT32 *pui32OutBNC, IMG_CHAR *pszOutV, IMG_UINT32 ui32OutVMaxLen,
+                                                       IMG_UINT32 ui32B, IMG_CHAR *pszV, IMG_UINT32 ui32N, IMG_UINT32 ui32C);
+IMG_VOID rgx_bvnc_pack_hw(IMG_UINT32 *pui32OutBNC, IMG_CHAR *pszOutV, IMG_UINT32 ui32OutVMaxLen,
+                                                       IMG_UINT32 ui32B, IMG_CHAR *pszFwV, IMG_UINT32 ui32V, IMG_UINT32 ui32N, IMG_UINT32 ui32C);
+
+#endif /*  __RGX_COMPAT_BVNC_H__ */
+
+/******************************************************************************
+ End of file (rgx_compat_bvnc.h)
+******************************************************************************/
+
diff --git a/drivers/gpu/rogue_m/services/shared/include/cache_internal.h b/drivers/gpu/rogue_m/services/shared/include/cache_internal.h
new file mode 100644 (file)
index 0000000..8326724
--- /dev/null
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services cache management header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines for cache management which are visible internally only.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _CACHE_INTERNAL_H_
+#define _CACHE_INTERNAL_H_
+#include "img_types.h"
+#include "pvrsrv_devmem.h"
+#include "cache_external.h"
+
+typedef struct _CACHE_BATCH_OP_ENTRY_
+{
+       IMG_UINT32                      ui32PMREntryIndex;
+       PVRSRV_CACHE_OP         eCacheOp;
+       IMG_DEVMEM_SIZE_T       uiSize;
+    IMG_DEVMEM_OFFSET_T uiOffset;
+} CACHE_BATCH_OP_ENTRY;
+
+#endif /* _CACHE_INTERNAL_H_ */
diff --git a/drivers/gpu/rogue_m/services/shared/include/devicemem.h b/drivers/gpu/rogue_m/services/shared/include/devicemem.h
new file mode 100644 (file)
index 0000000..6ee2c9d
--- /dev/null
@@ -0,0 +1,559 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management core internal
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Services internal interface to core device memory management
+                functions that are shared between client and server code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef SRVCLIENT_DEVICEMEM_H
+#define SRVCLIENT_DEVICEMEM_H
+
+/********************************************************************************
+ *                                                                              *
+ *   +------------+   +------------+    +--------------+      +--------------+  *
+ *   | a   sub-   |   | a   sub-   |    |  an          |      | allocation   |  *
+ *   | allocation |   | allocation |    |  allocation  |      | also mapped  |  *
+ *   |            |   |            |    |  in proc 1   |      | into proc 2  |  *
+ *   +------------+   +------------+    +--------------+      +--------------+  *
+ *             |         |                     |                     |          *
+ *          +--------------+            +--------------+      +--------------+  *
+ *          | page   gran- |            | page   gran- |      | page   gran- |  *
+ *          | ular mapping |            | ular mapping |      | ular mapping |  *
+ *          +--------------+            +--------------+      +--------------+  *
+ *                 |                                 |          |               *
+ *                 |                                 |          |               *
+ *                 |                                 |          |               *
+ *          +--------------+                       +--------------+             *
+ *          |              |                       |              |             *
+ *          | A  "P.M.R."  |                       | A  "P.M.R."  |             *
+ *          |              |                       |              |             *
+ *          +--------------+                       +--------------+             *
+ *                                                                              *
+ ********************************************************************************/
+
+/*
+    All device memory allocations are ultimately a view upon (not
+    necessarily the whole of) a "PMR".
+
+    A PMR is a "Physical Memory Resource", which may be a
+    "pre-faulted" lump of physical memory, or it may be a
+    representation of some physical memory that will be instantiated
+    at some future time.
+
+    PMRs always represent multiple of some power-of-2 "contiguity"
+    promised by the PMR, which will allow them to be mapped in whole
+    pages into the device MMU.  As memory allocations may be smaller
+    than a page, these mappings may be suballocated and thus shared
+    between multiple allocations in one process.  A PMR may also be
+    mapped simultaneously into multiple device memory contexts
+    (cross-process scenario), however, for security reasons, it is not
+    legal to share a PMR "both ways" at once, that is, mapped into
+    multiple processes and divided up amongst several suballocations.
+
+    This PMR terminology is introduced here for background
+    information, but is generally of little concern to the caller of
+    this API.  This API handles suballocations and mappings, and the
+    caller thus deals primarily with MEMORY DESCRIPTORS representing
+    an allocation or suballocation, HEAPS representing ranges of
+    virtual addresses in a CONTEXT.
+*/
+
+/*
+   |<---------------------------context------------------------------>|
+   |<-------heap------->|   |<-------heap------->|<-------heap------->|
+   |<-alloc->|          |   |<-alloc->|<-alloc->||   |<-alloc->|      |
+*/
+
+#include "img_types.h"
+#include "devicemem_typedefs.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+#include "pdump.h"
+
+/* Use GET and SET function to access this */
+IMG_INTERNAL extern IMG_UINT32  g_uiLog2PageSize;
+
+#define GET_LOG2_PAGESIZE() ( (const IMG_UINT32) g_uiLog2PageSize )
+#define SET_LOG2_PAGESIZE(ui32Log2PageSize) \
+       { \
+               PVR_ASSERT( (ui32Log2PageSize > 11) && (ui32Log2PageSize < 22) ); \
+               g_uiLog2PageSize = (IMG_UINT32) ui32Log2PageSize; \
+       }
+
+typedef IMG_UINT32 DEVMEM_HEAPCFGID;
+#define DEVMEM_HEAPCFG_FORCLIENTS 0
+#define DEVMEM_HEAPCFG_META 1
+
+/*
+  In order to call the server side functions, we need a bridge handle.
+  We abstract that here, as we may wish to change its form.
+ */
+
+typedef IMG_HANDLE DEVMEM_BRIDGE_HANDLE;
+
+/*
+ * DevmemCreateContext()
+ *
+ * Create a device memory context
+ *
+ * This must be called before any heap is created in this context
+ *
+ * Caller to provide bridge handle which will be squirreled away
+ * internally and used for all future operations on items from this
+ * memory context.  Caller also to provide devicenode handle, as this
+ * is used for MMU configuration and also to determine the heap
+ * configuration for the auto-instantiated heaps.
+ *
+ * Note that when compiled in services/server, the hBridge is not used
+ * and is thrown away by the "fake" direct bridge.  (This may change.
+ * It is recommended that IMG_NULL be passed for the handle for now)
+ *
+ * hDeviceNode and uiHeapBlueprintID shall together dictate which
+ * heap-config to use.
+ *
+ * This will cause the server side counterpart to be created also.
+ *
+ * If you call DevmemCreateContext() (and the call succeeds) you
+ * are promising that you will later call Devmem_ContextDestroy(),
+ * except for abnormal process termination in which case it is
+ * expected it will be destroyed as part of handle clean up.
+ *
+ * Caller to provide storage for the pointer to the NEWDEVMEM_CONTEXT
+ * object thusly created.
+ */
+extern PVRSRV_ERROR
+DevmemCreateContext(DEVMEM_BRIDGE_HANDLE hBridge,
+                    IMG_HANDLE hDeviceNode,
+                    DEVMEM_HEAPCFGID uiHeapBlueprintID,
+                    DEVMEM_CONTEXT **ppsCtxPtr);
+
+/*
+ * DevmemAcquireDevPrivData()
+ * 
+ * Acquire the device private data for this memory context
+ */
+PVRSRV_ERROR
+DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx,
+                         IMG_HANDLE *hPrivData);
+
+/*
+ * DevmemReleaseDevPrivData()
+ * 
+ * Release the device private data for this memory context
+ */
+PVRSRV_ERROR
+DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx);
+
+/*
+ * DevmemDestroyContext()
+ *
+ * Undoes that done by DevmemCreateContext()
+ */
+extern PVRSRV_ERROR
+DevmemDestroyContext(DEVMEM_CONTEXT *psCtx);
+
+/*
+ * DevmemCreateHeap()
+ *
+ * Create a heap in the given context.
+ *
+ * N.B.  Not intended to be called directly, though it can be.
+ * Normally, heaps are instantiated at context creation time according
+ * to the specified blueprint.  See DevmemCreateContext() for details.
+ *
+ * This will cause MMU code to set up data structures for the heap,
+ * but may not cause page tables to be modified until allocations are
+ * made from the heap.
+ *
+ * The "Quantum" is both the device MMU page size to be configured for
+ * this heap, and the unit multiples of which "quantized" allocations
+ * are made (allocations smaller than this, known as "suballocations"
+ * will be made from a "sub alloc RA" and will "import" chunks
+ * according to this quantum)
+ *
+ * Where imported PMRs (or, for example, PMRs created by device class
+ * buffers) are mapped into this heap, it is important that the
+ * physical contiguity guarantee offered by the PMR is greater than or
+ * equal to the quantum size specified here, otherwise the attempt to
+ * map it will fail.  "Normal" allocations via Devmem_Allocate
+ * shall automatically meet this requirement, as each "import" will
+ * trigger the creation of a PMR with the desired contiguity.  The
+ * supported quantum sizes in that case shall be dictated by the OS
+ * specific implementation of PhysmemNewOSRamBackedPMR() (see)
+ */
+extern PVRSRV_ERROR
+DevmemCreateHeap(DEVMEM_CONTEXT *psCtxPtr,
+                 /* base and length of heap */
+                 IMG_DEV_VIRTADDR sBaseAddress,
+                 IMG_DEVMEM_SIZE_T uiLength,
+                 /* log2 of allocation quantum, i.e. "page" size.
+                    All allocations (that go to server side) are
+                    multiples of this.  We use a client-side RA to
+                    make sub-allocations from this */
+                 IMG_UINT32 ui32Log2Quantum,
+                 /* The minimum import alignment for this heap */
+                 IMG_UINT32 ui32Log2ImportAlignment,
+                 /* Name of heap for debug */
+                 /* N.B.  Okay to exist on caller's stack - this
+                    func takes a copy if it needs it. */
+                 const IMG_CHAR *pszName,
+                 DEVMEM_HEAPCFGID uiHeapBlueprintID,
+                 DEVMEM_HEAP **ppsHeapPtr);
+/*
+ * DevmemDestroyHeap()
+ *
+ * Reverses DevmemCreateHeap()
+ *
+ * N.B. All allocations must have been freed and all mappings must
+ * have been unmapped before invoking this call
+ */
+extern PVRSRV_ERROR
+DevmemDestroyHeap(DEVMEM_HEAP *psHeap);
+
+/*
+ * DevmemExportalignAdjustSizeAndAlign()
+ * Compute the Size and Align passed to avoid suballocations (used when allocation with PVRSRV_MEMALLOCFLAG_EXPORTALIGN)
+ */
+IMG_INTERNAL IMG_VOID
+DevmemExportalignAdjustSizeAndAlign(DEVMEM_HEAP *psHeap, IMG_DEVMEM_SIZE_T *puiSize, IMG_DEVMEM_ALIGN_T *puiAlign);
+
+/*
+ * DevmemAllocate()
+ *
+ * Makes an allocation (possibly a "suballocation", as described
+ * below) of device virtual memory from this heap.
+ *
+ * The size and alignment of the allocation will be honoured by the RA
+ * that allocates the "suballocation".  The resulting allocation will
+ * be mapped into GPU virtual memory and the physical memory to back
+ * it will exist, by the time this call successfully completes.
+ * 
+ * The size must be a positive integer multiple of the alignment.
+ * (i.e. the aligment specifies the alignment of both the start and
+ * the end of the resulting allocation.)
+ *
+ * Allocations made via this API are routed though a "suballocation
+ * RA" which is responsible for ensuring that small allocations can be
+ * made without wasting physical memory in the server.  Furthermore,
+ * such suballocations can be made entirely client side without
+ * needing to go to the server unless the allocation spills into a new
+ * page.
+ *
+ * Such suballocations cause many allocations to share the same "PMR".
+ * This happens only when the flags match exactly.
+ *
+ */
+
+PVRSRV_ERROR DevmemAllocate(DEVMEM_HEAP *psHeap,
+                            IMG_DEVMEM_SIZE_T uiSize,
+                            IMG_DEVMEM_ALIGN_T uiAlign,
+                            DEVMEM_FLAGS_T uiFlags,
+                            const IMG_PCHAR pszText,
+                            DEVMEM_MEMDESC **ppsMemDescPtr);
+
+PVRSRV_ERROR
+DevmemAllocateExportable(IMG_HANDLE hBridge,
+                                                IMG_HANDLE hDeviceNode,
+                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                IMG_DEVMEM_ALIGN_T uiAlign,
+                                                DEVMEM_FLAGS_T uiFlags,
+                                                const IMG_PCHAR pszText,
+                                                DEVMEM_MEMDESC **ppsMemDescPtr);
+
+PVRSRV_ERROR
+DevmemAllocateSparse(IMG_HANDLE hBridge,
+                                        IMG_HANDLE hDeviceNode,
+                                        IMG_DEVMEM_SIZE_T uiSize,
+                                        IMG_DEVMEM_SIZE_T uiChunkSize,
+                                        IMG_UINT32 ui32NumPhysChunks,
+                                        IMG_UINT32 ui32NumVirtChunks,
+                                        IMG_BOOL *pabMappingTable,
+                                        IMG_DEVMEM_ALIGN_T uiAlign,
+                                        DEVMEM_FLAGS_T uiFlags,
+                                        const IMG_PCHAR pszText,
+                                        DEVMEM_MEMDESC **ppsMemDescPtr);
+
+/*
+ * DevmemFree()
+ *
+ * Reverses that done by DevmemAllocate() N.B.  The underlying
+ * mapping and server side allocation _may_ not be torn down, for
+ * example, if the allocation has been exported, or if multiple
+ * allocations were suballocated from the same mapping, but this is
+ * properly refcounted, so the caller does not have to care.
+ */
+
+extern IMG_VOID
+DevmemFree(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+       DevmemMapToDevice:
+
+       Map an allocation to the device is was allocated from.
+       This function _must_ be called before any call to 
+       DevmemAcquireDevVirtAddr is made as it binds the allocation
+       to the heap.
+       DevmemReleaseDevVirtAddr is used to release the reference
+       to the device mapping this function created, but it doesn't
+       mean that the memory will actually be unmapped from the
+       device as other references to the mapping obtained via
+       DevmemAcquireDevVirtAddr could still be active.
+*/
+PVRSRV_ERROR DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc,
+                                                          DEVMEM_HEAP *psHeap,
+                                                          IMG_DEV_VIRTADDR *psDevVirtAddr);
+
+/*
+       DevmemAcquireDevVirtAddr
+
+       Acquire the MemDesc's device virtual address.
+       This function _must_ be called after DevmemMapToDevice
+       and is expected to be used be functions which didn't allocate
+       the MemDesc but need to know it's address
+ */
+PVRSRV_ERROR DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+                                      IMG_DEV_VIRTADDR *psDevVirtAddrRet);
+/*
+ * DevmemReleaseDevVirtAddr()
+ *
+ * give up the licence to use the device virtual address that was
+ * acquired by "Acquire" or "MapToDevice"
+ */
+extern IMG_VOID
+DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+ * DevmemAcquireCpuVirtAddr()
+ *
+ * Acquires a license to use the cpu virtual address of this mapping.
+ * Note that the memory may not have been mapped into cpu virtual
+ * memory prior to this call.  On first "acquire" the memory will be
+ * mapped in (if it wasn't statically mapped in) and on last put it
+ * _may_ become unmapped.  Later calling "Acquire" again, _may_ cause
+ * the memory to be mapped at a different address.
+ */
+PVRSRV_ERROR DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+                                      IMG_VOID **ppvCpuVirtAddr);
+/*
+ * DevmemReleaseDevVirtAddr()
+ *
+ * give up the licence to use the cpu virtual address that was granted
+ * with the "Get" call.
+ */
+extern IMG_VOID
+DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+ * DevmemExport()
+ *
+ * Given a memory allocation allocated with DevmemAllocateExportable()
+ * create a "cookie" that can be passed intact by the caller's own choice
+ * of secure IPC to another process and used as the argument to "map"
+ * to map this memory into a heap in the target processes.  N.B.  This can
+ * also be used to map into multiple heaps in one process, though that's not
+ * the intention.
+ *
+ * Note, the caller must later call Unexport before freeing the
+ * memory.
+ */
+PVRSRV_ERROR DevmemExport(DEVMEM_MEMDESC *psMemDesc,
+                          DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+
+IMG_VOID DevmemUnexport(DEVMEM_MEMDESC *psMemDesc,
+                                               DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+PVRSRV_ERROR
+DevmemImport(IMG_HANDLE hBridge,
+                        DEVMEM_EXPORTCOOKIE *psCookie,
+                        DEVMEM_FLAGS_T uiFlags,
+                        DEVMEM_MEMDESC **ppsMemDescPtr);
+
+/*
+ * DevmemIsValidExportCookie()
+ * Check whether the Export Cookie contains a valid export */
+IMG_BOOL
+DevmemIsValidExportCookie(DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+/*
+ * DevmemMakeServerExportClientExport()
+ * 
+ * This is a "special case" function for making a server export cookie
+ * which went through the direct bridge into an export cookie that can
+ * be passed through the client bridge.
+ */
+PVRSRV_ERROR
+DevmemMakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
+                                   DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie,
+                                   DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+/*
+ * DevmemUnmakeServerExportClientExport()
+ * 
+ * Free any resource associated with the Make operation
+ */
+PVRSRV_ERROR
+DevmemUnmakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
+                                   DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+/*
+ *
+ * The following set of functions is specific to the heap "blueprint"
+ * stuff, for automatic creation of heaps when a context is created
+ *
+ */
+
+
+/* Devmem_HeapConfigCount: returns the number of heap configs that
+   this device has.  Note that there is no acquire/release semantics
+   required, as this data is guaranteed to be constant for the
+   lifetime of the device node */
+extern PVRSRV_ERROR
+DevmemHeapConfigCount(DEVMEM_BRIDGE_HANDLE hBridge,
+                      IMG_HANDLE hDeviceNode,
+                      IMG_UINT32 *puiNumHeapConfigsOut);
+
+/* Devmem_HeapCount: returns the number of heaps that a given heap
+   config on this device has.  Note that there is no acquire/release
+   semantics required, as this data is guaranteed to be constant for
+   the lifetime of the device node */
+extern PVRSRV_ERROR
+DevmemHeapCount(DEVMEM_BRIDGE_HANDLE hBridge,
+                IMG_HANDLE hDeviceNode,
+                IMG_UINT32 uiHeapConfigIndex,
+                IMG_UINT32 *puiNumHeapsOut);
+/* Devmem_HeapConfigName: return the name of the given heap config.
+   The caller is to provide the storage for the returned string and
+   indicate the number of bytes (including null terminator) for such
+   string in the BufSz arg.  Note that there is no acquire/release
+   semantics required, as this data is guaranteed to be constant for
+   the lifetime of the device node.
+ */
+extern PVRSRV_ERROR
+DevmemHeapConfigName(DEVMEM_BRIDGE_HANDLE hBridge,
+                     IMG_HANDLE hDeviceNode,
+                     IMG_UINT32 uiHeapConfigIndex,
+                     IMG_CHAR *pszConfigNameOut,
+                     IMG_UINT32 uiConfigNameBufSz);
+
+/* Devmem_HeapDetails: fetches all the metadata that is recorded in
+   this heap "blueprint".  Namely: heap name (caller to provide
+   storage, and indicate buffer size (including null terminator) in
+   BufSz arg), device virtual address and length, log2 of data page
+   size (will be one of 12, 14, 16, 18, 20, 21, at time of writing).
+   Note that there is no acquire/release semantics required, as this
+   data is guaranteed to be constant for the lifetime of the device
+   node. */
+extern PVRSRV_ERROR
+DevmemHeapDetails(DEVMEM_BRIDGE_HANDLE hBridge,
+                  IMG_HANDLE hDeviceNode,
+                  IMG_UINT32 uiHeapConfigIndex,
+                  IMG_UINT32 uiHeapIndex,
+                  IMG_CHAR *pszHeapNameOut,
+                  IMG_UINT32 uiHeapNameBufSz,
+                  IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+                  IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+                  IMG_UINT32 *puiLog2DataPageSize,
+                  IMG_UINT32 *puiLog2ImportAlignmentOut);
+
+/*
+ * Devmem_FindHeapByName()
+ *
+ * returns the heap handle for the named _automagic_ heap in this
+ * context.  "automagic" heaps are those that are born with the
+ * context from a blueprint
+ */
+extern PVRSRV_ERROR
+DevmemFindHeapByName(const DEVMEM_CONTEXT *psCtx,
+                     const IMG_CHAR *pszHeapName,
+                     DEVMEM_HEAP **ppsHeapRet);
+
+/*
+ * DevmemGetHeapBaseDevVAddr()
+ *
+ * returns the device virtual address of the base of the heap.
+ */
+
+PVRSRV_ERROR
+DevmemGetHeapBaseDevVAddr(DEVMEM_HEAP *psHeap,
+                         IMG_DEV_VIRTADDR *pDevVAddr);
+
+extern PVRSRV_ERROR
+DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+                          IMG_HANDLE *phImport);
+
+extern PVRSRV_ERROR
+DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc,
+                                                  IMG_UINT64 *pui64UID);
+
+PVRSRV_ERROR
+DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc,
+                               IMG_HANDLE *hReservation);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc,
+               IMG_HANDLE *hPMR,
+               IMG_DEVMEM_OFFSET_T *puiPMROffset);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
+                               DEVMEM_FLAGS_T *puiFlags);
+
+PVRSRV_ERROR
+DevmemLocalImport(IMG_HANDLE hBridge,
+                                 IMG_HANDLE hExtHandle,
+                                 DEVMEM_FLAGS_T uiFlags,
+                                 DEVMEM_MEMDESC **ppsMemDescPtr,
+                                 IMG_DEVMEM_SIZE_T *puiSizePtr);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext,
+                         IMG_DEV_VIRTADDR sDevVAddr);
+
+/* DevmemGetHeapLog2ImportAlignment()
+ *
+ * Get the import alignment used for a certain heap.
+ */
+IMG_UINT32
+DevmemGetHeapLog2ImportAlignment(DEVMEM_HEAP *psHeap);
+
+#endif /* #ifndef SRVCLIENT_DEVICEMEM_CLIENT_H */
diff --git a/drivers/gpu/rogue_m/services/shared/include/devicemem_history_shared.h b/drivers/gpu/rogue_m/services/shared/include/devicemem_history_shared.h
new file mode 100644 (file)
index 0000000..789409c
--- /dev/null
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory History shared definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Shared (client/server) definitions related to the Devicemem History
+                functionality.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_HISTORY_SHARED_H
+#define DEVICEMEM_HISTORY_SHARED_H
+
+/* structure used inside MEMDESC to hold the allocation name until
+ * the allocation is unmapped
+ */
+typedef struct _DEVICEMEM_HISTORY_MEMDESC_DATA_
+{
+       IMG_CHAR szText[DEVICEMEM_HISTORY_TEXT_BUFSZ];
+       IMG_DEVMEM_SIZE_T uiSize;
+} DEVICEMEM_HISTORY_MEMDESC_DATA;
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/shared/include/devicemem_mmap.h b/drivers/gpu/rogue_m/services/shared/include/devicemem_mmap.h
new file mode 100644 (file)
index 0000000..2963336
--- /dev/null
@@ -0,0 +1,108 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS abstraction for the mmap2 interface for mapping PMRs into
+                User Mode memory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DEVICEMEM_MMAP_H_
+#define _DEVICEMEM_MMAP_H_
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/*
+ *
+ * OSMMapPMR
+ *
+ * Causes this PMR to be mapped into CPU memory that the user process
+ * may access.
+ *
+ * Whether the memory is mapped readonly, readwrite, or not at all, is
+ * dependent on the PMR itself.
+ *
+ * The PMR handle is opaque to the user, and lower levels of this
+ * stack ensure that the handle is private to this process, such that
+ * this API cannot be abused to gain access to other people's PMRs.
+ *
+ * The OS implementation of this function should return the virtual
+ * address and length for the User to use.  The "PrivData" is to be
+ * stored opaquely by the caller (N.B. he should make no assumptions,
+ * in particular, IMG_NULL is a valid handle) and given back to the
+ * call to OSMunmapPMR.
+ *
+ * The OS implementation is free to use the PrivData handle for any
+ * purpose it sees fit.
+ */
+
+extern PVRSRV_ERROR
+OSMMapPMR(IMG_HANDLE hBridge,
+          IMG_HANDLE hPMR,
+          IMG_DEVMEM_SIZE_T uiPMRLength,
+          IMG_UINT32 uiFlags,
+          IMG_HANDLE *phOSMMapPrivDataOut,
+          IMG_VOID **ppvMappingAddressOut,
+          IMG_SIZE_T *puiMappingLengthOut);
+
+/*
+ *
+ * OSMUnmapPMR
+ *
+ * The reverse of OSMMapPMR
+ *
+ * The caller is required to pass the PMR handle back in along with
+ * the same 3-tuple of information as was returned by the call to
+ * OSMMapPMR
+ *
+ */
+/* 
+   FIXME:
+   perhaps this function should take _only_ the hOSMMapPrivData arg,
+   and the implementation is required to store any of the other data
+   items that it requires to do the unmap?
+*/
+extern IMG_VOID
+OSMUnmapPMR(IMG_HANDLE hBridge,
+            IMG_HANDLE hPMR,
+            IMG_HANDLE hOSMMapPrivData,
+            IMG_VOID *pvMappingAddress,
+            IMG_SIZE_T uiMappingLength);
+
+#endif
diff --git a/drivers/gpu/rogue_m/services/shared/include/devicemem_pdump.h b/drivers/gpu/rogue_m/services/shared/include/devicemem_pdump.h
new file mode 100644 (file)
index 0000000..b86602a
--- /dev/null
@@ -0,0 +1,343 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management PDump internal
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Services internal interface to PDump device memory management
+                functions that are shared between client and server code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DEVICEMEM_PDUMP_H_
+#define _DEVICEMEM_PDUMP_H_
+
+#include "devicemem.h"
+#include "pdumpdefs.h"
+#include "pdump.h"
+
+#if defined(PDUMP)
+/*
+ * DevmemPDumpMem()
+ *
+ * takes a memory descriptor, offset, and size, and takes the current
+ * contents of the memory at that location and writes it to the prm
+ * pdump file, and emits a pdump LDB to load the data from that file.
+ * The intention here is that the contents of the simulated buffer
+ * upon pdump playback will be made to be the same as they are when
+ * this command is run, enabling pdump of cases where the memory has
+ * been modified externally, i.e. by the host cpu or by a third
+ * party.
+ */
+extern IMG_VOID
+DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
+                   IMG_DEVMEM_OFFSET_T uiOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpZeroMem()
+ *
+ * as DevmemPDumpMem() but the PDump allocation will be populated with zeros from
+ * the zero page in the parameter stream
+ */
+extern IMG_VOID
+DevmemPDumpLoadZeroMem(DEVMEM_MEMDESC *psMemDesc,
+                   IMG_DEVMEM_OFFSET_T uiOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpMemValue()
+ * 
+ * As above but dumps the value at a dword-aligned address in plain
+ * text to the pdump script2 file. Useful for patching a buffer at
+ * pdump playback by simply editing the script output file.
+ * 
+ * (The same functionality can be achieved by the above function but
+ *  the binary PARAM file must be patched in that case.)
+ */
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT32 ui32Value,
+                        PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpMemValue64()
+ *
+ * As above but dumps the 64bit-value at a dword-aligned address in plain
+ * text to the pdump script2 file. Useful for patching a buffer at
+ * pdump playback by simply editing the script output file.
+ *
+ * (The same functionality can be achieved by the above function but
+ *  the binary PARAM file must be patched in that case.)
+ */
+IMG_INTERNAL IMG_VOID
+DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT64 ui64Value,
+                        PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpPageCatBaseToSAddr()
+ *
+ * Returns the symbolic address of a piece of memory represented
+ * by an offset into the mem descriptor.
+ */
+extern PVRSRV_ERROR
+DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC           *psMemDesc,
+                                                         IMG_DEVMEM_OFFSET_T   *puiMemOffset,
+                                                         IMG_CHAR                              *pszName,
+                                                         IMG_UINT32                    ui32Size);
+
+/*
+ * DevmemPDumpSaveToFile()
+ *
+ * emits a pdump SAB to cause the current contents of the memory to be
+ * written to the given file during playback
+ */
+extern IMG_VOID
+DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc,
+                      IMG_DEVMEM_OFFSET_T uiOffset,
+                      IMG_DEVMEM_SIZE_T uiSize,
+                      const IMG_CHAR *pszFilename);
+
+/*
+ * DevmemPDumpSaveToFileVirtual()
+ *
+ * emits a pdump SAB, just like DevmemPDumpSaveToFile(), but uses the
+ * virtual address and device MMU context to cause the pdump player to
+ * traverse the MMU page tables itself.
+ */
+extern IMG_VOID
+DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
+                             IMG_DEVMEM_OFFSET_T uiOffset,
+                             IMG_DEVMEM_SIZE_T uiSize,
+                             const IMG_CHAR *pszFilename,
+                                                        IMG_UINT32 ui32FileOffset,
+                                                        IMG_UINT32 ui32PdumpFlags);
+
+
+/*
+ *
+ * Devmem_PDumpDevmemPol32()
+ *
+ * writes a PDump 'POL' command to wait for a masked 32-bit memory
+ * location to become the specified value
+ */
+extern PVRSRV_ERROR
+DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc,
+                           IMG_DEVMEM_OFFSET_T uiOffset,
+                           IMG_UINT32 ui32Value,
+                           IMG_UINT32 ui32Mask,
+                           PDUMP_POLL_OPERATOR eOperator,
+                           PDUMP_FLAGS_T ui32PDumpFlags);
+
+/*
+ * DevmemPDumpCBP()
+ *
+ * Polls for space in circular buffer. Reads the read offset
+ * from memory and waits until there is enough space to write
+ * the packet.
+ *
+ * hMemDesc      - MemDesc which contains the read offset
+ * uiReadOffset  - Offset into MemDesc to the read offset
+ * uiWriteOffset - Current write offset
+ * uiPacketSize  - Size of packet to write
+ * uiBufferSize  - Size of circular buffer
+ */
+extern PVRSRV_ERROR
+DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc,
+                               IMG_DEVMEM_OFFSET_T uiReadOffset,
+                               IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                               IMG_DEVMEM_SIZE_T uiPacketSize,
+                               IMG_DEVMEM_SIZE_T uiBufferSize);
+
+#else  /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMem)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
+                   IMG_DEVMEM_OFFSET_T uiOffset,
+                   IMG_DEVMEM_SIZE_T uiSize,
+                   PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMemValue32)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT32 ui32Value,
+                        PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMemValue64)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT64 ui64Value,
+                        PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(ui64Value);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMemValue)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpLoadMemValue(DEVMEM_MEMDESC *psMemDesc,
+                        IMG_DEVMEM_OFFSET_T uiOffset,
+                        IMG_UINT32 ui32Value,
+                        PDUMP_FLAGS_T uiPDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpPageCatBaseToSAddr)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC           *psMemDesc,
+                                                         IMG_DEVMEM_OFFSET_T   *puiMemOffset,
+                                                         IMG_CHAR                              *pszName,
+                                                         IMG_UINT32                    ui32Size)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(puiMemOffset);
+       PVR_UNREFERENCED_PARAMETER(pszName);
+       PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpSaveToFile)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc,
+                      IMG_DEVMEM_OFFSET_T uiOffset,
+                      IMG_DEVMEM_SIZE_T uiSize,
+                      const IMG_CHAR *pszFilename)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(pszFilename);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpSaveToFileVirtual)
+#endif
+static INLINE IMG_VOID
+DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
+                             IMG_DEVMEM_OFFSET_T uiOffset,
+                             IMG_DEVMEM_SIZE_T uiSize,
+                             const IMG_CHAR *pszFilename,
+                                                        IMG_UINT32 ui32FileOffset,
+                                                        IMG_UINT32 ui32PdumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(uiSize);
+       PVR_UNREFERENCED_PARAMETER(pszFilename);
+       PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32PdumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpDevmemPol32)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc,
+                           IMG_DEVMEM_OFFSET_T uiOffset,
+                           IMG_UINT32 ui32Value,
+                           IMG_UINT32 ui32Mask,
+                           PDUMP_POLL_OPERATOR eOperator,
+                           PDUMP_FLAGS_T ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiOffset);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+
+       return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpCBP)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc,
+                               IMG_DEVMEM_OFFSET_T uiReadOffset,
+                               IMG_DEVMEM_OFFSET_T uiWriteOffset,
+                               IMG_DEVMEM_SIZE_T uiPacketSize,
+                               IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psMemDesc);
+       PVR_UNREFERENCED_PARAMETER(uiReadOffset);
+       PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+       PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+       PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+
+       return PVRSRV_OK;
+}
+#endif /* PDUMP */
+#endif /* _DEVICEMEM_PDUMP_H_ */
diff --git a/drivers/gpu/rogue_m/services/shared/include/devicemem_utils.h b/drivers/gpu/rogue_m/services/shared/include/devicemem_utils.h
new file mode 100644 (file)
index 0000000..92a89b6
--- /dev/null
@@ -0,0 +1,388 @@
+/*************************************************************************/ /*!
+@File
+@Title          Device Memory Management internal utility functions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Utility functions used internally by device memory management
+                code.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DEVICEMEM_UTILS_H_
+#define _DEVICEMEM_UTILS_H_
+
+#include "devicemem.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvr_debug.h"
+#include "allocmem.h"
+#include "ra.h"
+#include "osfunc.h"
+#include "lock.h"
+#include "devicemem_mmap.h"
+#include "devicemem_utils.h"
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+#include "mm_common.h"
+#include "devicemem_history_shared.h"
+#endif
+
+#define DEVMEM_HEAPNAME_MAXLENGTH 160
+
+
+#if defined(DEVMEM_DEBUG) && defined(REFCOUNT_DEBUG)
+#define DEVMEM_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_ERROR, __FILE__, __LINE__, fmt, __VA_ARGS__)
+#else
+#define DEVMEM_REFCOUNT_PRINT(fmt, ...)
+#endif
+
+
+/* If we need a "hMapping" but we don't have a server-side mapping, we
+   poison the entry with this value so that it's easily recognised in
+   the debugger.  Note that this is potentially a valid handle, but
+   then so is IMG_NULL, which is no better, indeed worse, as it's not
+   obvious in the debugger.  The value doesn't matter.  We _never_ use
+   it (and because it's valid, we never assert it isn't this) but it's
+   nice to have a value in the source code that we can grep for when
+   things go wrong. */
+#define LACK_OF_MAPPING_POISON ((IMG_HANDLE)0x6116dead)
+#define LACK_OF_RESERVATION_POISON ((IMG_HANDLE)0x7117dead)
+
+struct _DEVMEM_CONTEXT_ {
+    /* Cookie of the device on which this memory context resides */
+    IMG_HANDLE hDeviceNode;
+
+    /* Number of heaps that have been created in this context
+       (regardless of whether they have allocations) */
+    IMG_UINT32 uiNumHeaps;
+
+    /* Sometimes we need to talk to Kernel Services.  In order to do
+       so, we need the connection handle */
+    DEVMEM_BRIDGE_HANDLE hBridge;
+
+    /*
+      Each "DEVMEM_CONTEXT" has a counterpart in the server,
+      which is responsible for handling the mapping into device MMU.
+      We have a handle to that here.
+    */
+    IMG_HANDLE hDevMemServerContext;
+
+    /* Number of automagically created heaps in this context,
+       i.e. those that are born at context creation time from the
+       chosen "heap config" or "blueprint" */
+    IMG_UINT32 uiAutoHeapCount;
+
+    /* pointer to array of such heaps */
+    struct _DEVMEM_HEAP_ **ppsAutoHeapArray;
+
+       /* Private data handle for device specific data */
+       IMG_HANDLE hPrivData;
+};
+
+struct _DEVMEM_HEAP_ {
+    /* Name of heap - for debug and lookup purposes. */
+    IMG_CHAR *pszName;
+
+    /* Number of live imports in the heap */
+    ATOMIC_T hImportCount;
+
+    /*
+     * Base address of heap, required by clients due to some requesters
+     * not being full range 
+     */
+    IMG_DEV_VIRTADDR sBaseAddress;
+
+    /* This RA is for managing sub-allocations in virtual space.  Two
+       more RA's will be used under the Hood for managing the coarser
+       allocation of virtual space from the heap, and also for
+       managing the physical backing storage. */
+    RA_ARENA *psSubAllocRA;
+    IMG_CHAR *pszSubAllocRAName;
+    /*
+      This RA is for the coarse allocation of virtual space from the heap
+    */
+    RA_ARENA *psQuantizedVMRA;
+    IMG_CHAR *pszQuantizedVMRAName;
+
+    /* We also need to store a copy of the quantum size in order to
+       feed this down to the server */
+    IMG_UINT32 uiLog2Quantum;
+
+    /* Store a copy of the minimum import alignment */
+    IMG_UINT32 uiLog2ImportAlignment;
+
+    /* The parent memory context for this heap */
+    struct _DEVMEM_CONTEXT_ *psCtx;
+
+       POS_LOCK hLock;                                                 /*!< Lock to protect this structure */
+
+    /*
+      Each "DEVMEM_HEAP" has a counterpart in the server,
+      which is responsible for handling the mapping into device MMU.
+      We have a handle to that here.
+    */
+    IMG_HANDLE hDevMemServerHeap;
+};
+
+
+typedef struct _DEVMEM_DEVICE_IMPORT_ {
+       DEVMEM_HEAP *psHeap;                    /*!< Heap this import is bound to */
+       IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the import */
+       IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
+       IMG_HANDLE hReservation;                /*!< Device memory reservation handle */
+       IMG_HANDLE hMapping;                    /*!< Device mapping handle */
+       IMG_BOOL bMapped;                               /*!< This is import mapped? */
+       POS_LOCK hLock;                                 /*!< Lock to protect the device import */
+} DEVMEM_DEVICE_IMPORT;
+
+typedef struct _DEVMEM_CPU_IMPORT_ {
+       IMG_PVOID pvCPUVAddr;                   /*!< CPU virtual address of the import */
+       IMG_UINT32 ui32RefCount;                /*!< Refcount of the CPU virtual address */
+       IMG_HANDLE hOSMMapData;                 /*!< CPU mapping handle */
+       POS_LOCK hLock;                                 /*!< Lock to protect the CPU import */
+#if !defined(__KERNEL__) && defined(SUPPORT_ION)
+       int iDmaBufFd;                                  /*!< >=0 if this was an imported ion allocation */
+#endif
+} DEVMEM_CPU_IMPORT;
+
+typedef struct _DEVMEM_IMPORT_ {
+    DEVMEM_BRIDGE_HANDLE hBridge;              /*!< Bridge connection for the server */
+       IMG_DEVMEM_ALIGN_T uiAlign;                     /*!< Alignment of the PMR */
+       DEVMEM_SIZE_T uiSize;                           /*!< Size of import */
+    ATOMIC_T hRefCount;                                        /*!< Refcount for this import */
+    IMG_BOOL bExportable;                              /*!< Is this import exportable? */
+    IMG_HANDLE hPMR;                                   /*!< Handle to the PMR */
+    DEVMEM_FLAGS_T uiFlags;                            /*!< Flags for this import */
+    POS_LOCK hLock;                                            /*!< Lock to protect the import */
+
+       DEVMEM_DEVICE_IMPORT sDeviceImport;     /*!< Device specifics of the import */
+       DEVMEM_CPU_IMPORT sCPUImport;           /*!< CPU specifics of the import */
+} DEVMEM_IMPORT;
+
+typedef struct _DEVMEM_DEVICE_MEMDESC_ {
+       IMG_DEV_VIRTADDR sDevVAddr;             /*!< Device virtual address of the allocation */
+       IMG_UINT32 ui32RefCount;                /*!< Refcount of the device virtual address */
+       POS_LOCK hLock;                                 /*!< Lock to protect device memdesc */
+} DEVMEM_DEVICE_MEMDESC;
+
+typedef struct _DEVMEM_CPU_MEMDESC_ {
+       IMG_PVOID pvCPUVAddr;                   /*!< CPU virtual address of the import */
+       IMG_UINT32 ui32RefCount;                /*!< Refcount of the device CPU address */
+       POS_LOCK hLock;                                 /*!< Lock to protect CPU memdesc */
+} DEVMEM_CPU_MEMDESC;
+
+struct _DEVMEM_MEMDESC_ {
+    DEVMEM_IMPORT *psImport;                           /*!< Import this memdesc is on */
+    IMG_DEVMEM_OFFSET_T uiOffset;                      /*!< Offset into import where our allocation starts */
+    ATOMIC_T hRefCount;                                                /*!< Refcount of the memdesc */
+    POS_LOCK hLock;                                                    /*!< Lock to protect memdesc */
+
+       DEVMEM_DEVICE_MEMDESC sDeviceMemDesc;   /*!< Device specifics of the memdesc */
+       DEVMEM_CPU_MEMDESC sCPUMemDesc;         /*!< CPU specifics of the memdesc */
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+       DEVICEMEM_HISTORY_MEMDESC_DATA sTraceData;
+#endif
+
+#if defined(PVR_RI_DEBUG)
+    IMG_HANDLE hRIHandle;                                      /*!< Handle to RI information */
+#endif
+};
+
+/******************************************************************************
+@Function       _DevmemValidateParams
+@Description    Check if flags are conflicting and if align is a size multiple.
+
+@Input          uiSize      Size of the import.
+@Input          uiAlign     Alignment of the import.
+@Input          uiFlags     Flags for the import.
+@return         PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
+                                                                  IMG_DEVMEM_ALIGN_T uiAlign,
+                                                                  DEVMEM_FLAGS_T uiFlags);
+
+/******************************************************************************
+@Function       _DevmemImportStructAlloc
+@Description    Allocates memory for an import struct. Does not allocate a PMR!
+                Create locks for CPU and Devmem mappings.
+
+@Input          hBridge       Bridge to use for calls from the import.
+@Input          bExportable   Is this import is exportable?
+@Input          ppsImport     The import to allocate.
+@return         PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR _DevmemImportStructAlloc(IMG_HANDLE hBridge,
+                                                                         IMG_BOOL bExportable,
+                                                                         DEVMEM_IMPORT **ppsImport);
+
+/******************************************************************************
+@Function       _DevmemImportStructInit
+@Description    Initialises the import struct with the given parameters.
+                Set it's refcount to 1!
+
+@Input          psImport    The import to initialise.
+@Input          uiSize      Size of the import.
+@Input          uiAlign     Alignment of allocations in the import.
+@Input          uiMapFlags
+@Input          hPMR        Reference to the PMR of this import struct.
+******************************************************************************/
+IMG_VOID _DevmemImportStructInit(DEVMEM_IMPORT *psImport,
+                                                                IMG_DEVMEM_SIZE_T uiSize,
+                                                                IMG_DEVMEM_ALIGN_T uiAlign,
+                                                                PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+                                                                IMG_HANDLE hPMR);
+
+/******************************************************************************
+@Function       _DevmemImportStructDevMap
+@Description    NEVER call after the last _DevmemMemDescRelease()
+                Maps the PMR referenced by the import struct to the device's
+                virtual address space.
+                Does nothing but increase the cpu mapping refcount if the
+                import struct was already mapped.
+
+@Input          psHeap    The heap to map to.
+@Input          bMap      Caller can choose if the import should be really
+                          mapped in the page tables or if just a virtual range
+                          should be reserved and the refcounts increased.
+@Input          psImport  The import we want to map.
+@return         PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR _DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
+                                                                          IMG_BOOL bMap,
+                                                                          DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemImportStructDevUnmap
+@Description    Unmaps the PMR referenced by the import struct from the
+                device's virtual address space.
+                If this was not the last remaining CPU mapping on the import
+                struct only the cpu mapping refcount is decreased.
+******************************************************************************/
+IMG_VOID _DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemImportStructCPUMap
+@Description    NEVER call after the last _DevmemMemDescRelease()
+                Maps the PMR referenced by the import struct to the CPU's
+                virtual address space.
+                Does nothing but increase the cpu mapping refcount if the
+                import struct was already mapped.
+@return         PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR _DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemImportStructCPUUnmap
+@Description    Unmaps the PMR referenced by the import struct from the CPU's
+                virtual address space.
+                If this was not the last remaining CPU mapping on the import
+                struct only the cpu mapping refcount is decreased.
+******************************************************************************/
+IMG_VOID _DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport);
+
+
+/******************************************************************************
+@Function       _DevmemImportStructAcquire
+@Description    Acquire an import struct by increasing it's refcount.
+******************************************************************************/
+IMG_VOID _DevmemImportStructAcquire(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemImportStructRelease
+@Description    Reduces the refcount of the import struct.
+                Destroys the import in the case it was the last reference.
+                Destroys underlying PMR if this import was the last reference
+                to it.
+@return         A boolean to signal if the import was destroyed. True = yes.
+******************************************************************************/
+IMG_VOID _DevmemImportStructRelease(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemImportDiscard
+@Description    Discard a created, but unitilised import structure.
+                This must only be called before _DevmemImportStructInit
+                after which _DevmemImportStructRelease must be used to
+                "free" the import structure.
+******************************************************************************/
+IMG_VOID _DevmemImportDiscard(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemMemDescAlloc
+@Description    Allocates a MemDesc and create it's various locks.
+                Zero the allocated memory.
+@return         PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc);
+
+/******************************************************************************
+@Function       _DevmemMemDescInit
+@Description    Sets the given offset and import struct fields in the MemDesc.
+                Initialises refcount to 1 and other values to 0.
+
+@Input          psMemDesc    MemDesc to initialise.
+@Input          uiOffset     Offset in the import structure.
+@Input          psImport     Import the MemDesc is on.
+******************************************************************************/
+IMG_VOID _DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
+                                                       IMG_DEVMEM_OFFSET_T uiOffset,
+                                                       DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function       _DevmemMemDescAcquire
+@Description    Acquires the MemDesc by increasing it's refcount.
+******************************************************************************/
+IMG_VOID _DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc);
+
+/******************************************************************************
+@Function       _DevmemMemDescRelease
+@Description    Releases the MemDesc by reducing it's refcount.
+                Destroy the MemDesc if it's recount is 0.
+                Destroy the import struct the MemDesc is on if that was the
+                last MemDesc on the import, probably following the destruction
+                of the underlying PMR.
+******************************************************************************/
+IMG_VOID _DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc);
+
+/******************************************************************************
+@Function       _DevmemMemDescDiscard
+@Description    Discard a created, but unitilised MemDesc structure.
+                This must only be called before _DevmemMemDescInit
+                after which _DevmemMemDescRelease must be used to
+                "free" the MemDesc structure.
+******************************************************************************/
+IMG_VOID _DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc);
+
+#endif /* _DEVICEMEM_UTILS_H_ */
diff --git a/drivers/gpu/rogue_m/services/shared/include/dllist.h b/drivers/gpu/rogue_m/services/shared/include/dllist.h
new file mode 100644 (file)
index 0000000..190f74d
--- /dev/null
@@ -0,0 +1,248 @@
+/*************************************************************************/ /*!
+@File
+@Title          Double linked list header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Double linked list interface
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DLLIST_
+#define _DLLIST_
+
+#include "img_types.h"
+
+/*!
+       Pointer to a linked list node
+*/
+typedef struct _DLLIST_NODE_   *PDLLIST_NODE;
+
+
+/*!
+       Node in a linked list
+*/
+/*
+ * Note: the following structure's size is architecture-dependent and
+ * clients may need to create a mirror the structure definition if it needs
+ * to be used in a structure shared between host and device. Consider such
+ * clients if any changes are made to this structure.
+ */ 
+typedef struct _DLLIST_NODE_
+{
+       struct _DLLIST_NODE_    *psPrevNode;
+       struct _DLLIST_NODE_    *psNextNode;
+} DLLIST_NODE;
+
+
+/*!
+       Static initialiser
+*/
+#define DECLARE_DLLIST(n) \
+DLLIST_NODE n = {&n, &n}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_init
+
+@Description    Initialize a new double linked list
+
+@Input          psListHead              List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_VOID dllist_init(PDLLIST_NODE psListHead)
+{
+       psListHead->psPrevNode = psListHead;
+       psListHead->psNextNode = psListHead;
+}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_is_empty
+
+@Description    Returns whether the list is empty
+
+@Input          psListHead              List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_BOOL dllist_is_empty(PDLLIST_NODE psListHead)
+{
+       return ((psListHead->psPrevNode == psListHead) 
+                               && (psListHead->psNextNode == psListHead));
+}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_add_to_head
+
+@Description    Add psNewNode to head of list psListHead
+
+@Input          psListHead             Head Node
+@Input          psNewNode              New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_VOID dllist_add_to_head(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+       PDLLIST_NODE psTmp;
+
+       psTmp = psListHead->psNextNode;
+
+       psListHead->psNextNode = psNewNode;
+       psNewNode->psNextNode = psTmp;
+
+       psTmp->psPrevNode = psNewNode;
+       psNewNode->psPrevNode = psListHead;
+}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_add_to_tail
+
+@Description    Add psNewNode to tail of list psListHead
+
+@Input          psListHead             Head Node
+@Input          psNewNode              New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_VOID dllist_add_to_tail(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+       PDLLIST_NODE psTmp;
+
+       psTmp = psListHead->psPrevNode;
+
+       psListHead->psPrevNode = psNewNode;
+       psNewNode->psPrevNode = psTmp;
+
+       psTmp->psNextNode = psNewNode;
+       psNewNode->psNextNode = psListHead;
+}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_node_is_in_list
+
+@Description    Returns IMG_TRUE if psNode is in a list 
+
+@Input          psNode             List node
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_BOOL dllist_node_is_in_list(PDLLIST_NODE psNode)
+{
+       return (psNode->psNextNode != 0);
+}
+
+
+/*************************************************************************/ /*!
+@Function       dllist_get_next_node
+
+@Description    Returns the list node after psListHead or IMG_NULL psListHead
+                               is the only element in the list.
+
+@Input          psListHead             List node to start the operation
+
+*/
+/*****************************************************************************/
+static INLINE
+PDLLIST_NODE dllist_get_next_node(PDLLIST_NODE psListHead)
+{
+       if (psListHead->psNextNode == psListHead)
+       {
+               return IMG_NULL;
+       }
+       else
+       {
+               return psListHead->psNextNode;
+       }
+} 
+
+
+/*************************************************************************/ /*!
+@Function       dllist_remove_node
+
+@Description    Removes psListNode from the list where it currently belongs
+
+@Input          psListNode             List node to be removed
+
+*/
+/*****************************************************************************/
+static INLINE
+IMG_VOID dllist_remove_node(PDLLIST_NODE psListNode)
+{
+       psListNode->psNextNode->psPrevNode = psListNode->psPrevNode;
+       psListNode->psPrevNode->psNextNode = psListNode->psNextNode;
+
+       /* Clear the node to show it's not on a list */
+       psListNode->psPrevNode = 0;
+       psListNode->psNextNode = 0;
+}
+
+
+/*!
+       Callback function called on each element of the list
+*/
+typedef IMG_BOOL (*PFN_NODE_CALLBACK)(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData);
+
+
+/*************************************************************************/ /*!
+@Function       dllist_foreach_node
+
+@Description    Walk through all the nodes on the list until the 
+                               end or a callback returns FALSE
+
+@Input          psListHead                     List node to start the operation
+@Input                 pfnCallBack                     PFN_NODE_CALLBACK function called on each element       
+@Input                 pvCallbackData          Data passed to pfnCallBack alongside the current Node
+
+*/
+/*****************************************************************************/
+IMG_INTERNAL
+IMG_VOID dllist_foreach_node(PDLLIST_NODE psListHead,
+                                                         PFN_NODE_CALLBACK pfnCallBack,
+                                                         IMG_PVOID pvCallbackData);
+
+
+#endif /* _DLLIST_ */
+
diff --git a/drivers/gpu/rogue_m/services/shared/include/sync.h b/drivers/gpu/rogue_m/services/shared/include/sync.h
new file mode 100644 (file)
index 0000000..290b8cd
--- /dev/null
@@ -0,0 +1,399 @@
+/*************************************************************************/ /*!
+@File
+@Title          Synchronisation interface header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines the client side interface for synchronisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "sync_external.h"
+#include "pdumpdefs.h"
+#include "dllist.h"
+#include "pvr_debug.h"
+
+#ifndef _SYNC_
+#define _SYNC_
+
+#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include <services_kernel_client.h>
+#endif
+
+/*************************************************************************/ /*!
+@Function       SyncPrimContextCreate
+
+@Description    Create a new synchronisation context
+
+@Input          hBridge                 Bridge handle
+
+@Input          hDeviceNode             Device node handle
+
+@Output         hSyncPrimContext        Handle to the created synchronisation
+                                        primitive context
+
+@Return         PVRSRV_OK if the synchronisation primitive context was
+                successfully created
+*/
+/*****************************************************************************/
+PVRSRV_ERROR
+SyncPrimContextCreate(SYNC_BRIDGE_HANDLE       hBridge,
+                                         IMG_HANDLE                    hDeviceNode,
+                                         PSYNC_PRIM_CONTEXT    *hSyncPrimContext);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimContextDestroy
+
+@Description    Destroy a synchronisation context
+
+@Input          hSyncPrimContext        Handle to the synchronisation
+                                        primitive context to destroy
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimAlloc
+
+@Description    Allocate a new synchronisation primitive on the specified
+                synchronisation context
+
+@Input          hSyncPrimContext        Handle to the synchronisation
+                                        primitive context
+
+@Output         ppsSync                 Created synchronisation primitive
+
+@Input          pszClassName            Sync source annotation
+
+@Return         PVRSRV_OK if the synchronisation primitive was
+                successfully created
+*/
+/*****************************************************************************/
+PVRSRV_ERROR
+SyncPrimAlloc(PSYNC_PRIM_CONTEXT               hSyncPrimContext,
+                         PVRSRV_CLIENT_SYNC_PRIM       **ppsSync,
+                         const IMG_CHAR                        *pszClassName);
+
+#if defined(__KERNEL__)
+/*************************************************************************/ /*!
+@Function       SyncPrimAllocForServerSync
+
+@Description    Allocate a new synchronisation primitive on the specified
+                synchronisation context for a server sync
+
+@Input          hSyncPrimContext        Handle to the synchronisation
+                                        primitive context
+
+@Output         ppsSync                 Created synchronisation primitive
+
+@Input          pszClassName            Sync source annotation
+
+@Return         PVRSRV_OK if the synchronisation primitive was
+                successfully created
+*/
+/*****************************************************************************/
+PVRSRV_ERROR
+SyncPrimAllocForServerSync(PSYNC_PRIM_CONTEXT   hSyncPrimContext,
+                                               PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                               const IMG_CHAR          *pszClassName);
+#endif
+
+/*************************************************************************/ /*!
+@Function       SyncPrimFree
+
+@Description    Free a synchronisation primitive
+
+@Input          psSync                  The synchronisation primitive to free
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimSet
+
+@Description    Set the synchronisation primitive to a value
+
+@Input          psSync                  The synchronisation primitive to set
+
+@Input          ui32Value               Value to set it to
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value);
+
+#if defined(NO_HARDWARE)
+
+/*************************************************************************/ /*!
+@Function       SyncPrimNoHwUpdate
+
+@Description    Updates the synchronisation primitive value (in NoHardware drivers)
+
+@Input          psSync                  The synchronisation primitive to update
+
+@Input          ui32Value               Value to update it to
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value);
+#endif
+
+PVRSRV_ERROR
+SyncPrimServerAlloc(SYNC_BRIDGE_HANDLE hBridge,
+                                       IMG_HANDLE                      hDeviceNode,
+                                       PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
+                                       const IMG_CHAR          *pszClassName
+                                       PVR_DBG_FILELINE_PARAM);
+
+PVRSRV_ERROR
+SyncPrimServerGetStatus(IMG_UINT32 ui32SyncCount,
+                                               PVRSRV_CLIENT_SYNC_PRIM **papsSync,
+                                               IMG_UINT32 *pui32UID,
+                                               IMG_UINT32 *pui32FWAddr,
+                                               IMG_UINT32 *pui32CurrentOp,
+                                               IMG_UINT32 *pui32NextOp);
+
+PVRSRV_ERROR
+SyncPrimServerQueueOp(PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOp);
+
+IMG_BOOL
+SyncPrimIsServerSync(PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+IMG_HANDLE
+SyncPrimGetServerHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+
+
+PVRSRV_ERROR
+SyncPrimOpCreate(IMG_UINT32 ui32SyncCount,
+                                PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim,
+                                PSYNC_OP_COOKIE *ppsCookie);
+
+PVRSRV_ERROR
+SyncPrimOpTake(PSYNC_OP_COOKIE psCookie,
+                          IMG_UINT32 ui32SyncCount,
+                          PVRSRV_CLIENT_SYNC_PRIM_OP *pasSyncOp);
+
+PVRSRV_ERROR
+SyncPrimOpReady(PSYNC_OP_COOKIE psCookie,
+                               IMG_BOOL *pbReady);
+
+PVRSRV_ERROR
+SyncPrimOpComplete(PSYNC_OP_COOKIE psCookie);
+
+IMG_VOID
+SyncPrimOpDestroy(PSYNC_OP_COOKIE psCookie);
+
+PVRSRV_ERROR
+SyncPrimOpResolve(PSYNC_OP_COOKIE psCookie,
+                                 IMG_UINT32 *pui32SyncCount,
+                                 PVRSRV_CLIENT_SYNC_PRIM_OP **ppsSyncOp);
+
+PVRSRV_ERROR
+SyncPrimDumpSyncs(IMG_UINT32 ui32SyncCount, PVRSRV_CLIENT_SYNC_PRIM **papsSync, const IMG_CHAR *pcszExtraInfo);
+
+#if defined(PDUMP)
+/*************************************************************************/ /*!
+@Function       SyncPrimPDump
+
+@Description    PDump the current value of the synchronisation primitive
+
+@Input          psSync                  The synchronisation primitive to PDump
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimPDumpValue
+
+@Description    PDump the ui32Value as the value of the synchronisation 
+                               primitive (regardless of the current value).
+
+@Input          psSync          The synchronisation primitive to PDump
+@Input                 ui32Value               Value to give to the sync prim on the pdump
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimPDumpPol
+
+@Description    Do a PDump poll of the synchronisation primitive
+
+@Input          psSync                  The synchronisation primitive to PDump
+
+@Input          ui32Value               Value to poll for 
+
+@Input          ui32Mask                PDump mask operator
+
+@Input          ui32PDumpFlags          PDump flags
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                IMG_UINT32 ui32Value,
+                                IMG_UINT32 ui32Mask,
+                                PDUMP_POLL_OPERATOR eOperator,
+                                IMG_UINT32 ui32PDumpFlags);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimOpPDumpPol
+
+@Description    Do a PDump poll all the synchronisation primitives on this
+                               Operation cookie.
+
+@Input          psCookie                Operation cookie
+
+@Input          ui32PDumpFlags          PDump flags
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID
+SyncPrimOpPDumpPol(PSYNC_OP_COOKIE psCookie,
+                                PDUMP_POLL_OPERATOR eOperator,
+                                IMG_UINT32 ui32PDumpFlags);
+
+/*************************************************************************/ /*!
+@Function       SyncPrimPDumpCBP
+
+@Description    Do a PDump CB poll using the synchronisation primitive
+
+@Input          psSync                  The synchronisation primitive to PDump
+
+@Input          uiWriteOffset           Current write offset of buffer
+
+@Input          uiPacketSize            Size of the packet to write into CB
+
+@Input          uiBufferSize            Size of the CB
+
+@Return         None
+*/
+/*****************************************************************************/
+IMG_VOID 
+SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                IMG_UINT64 uiWriteOffset,
+                                IMG_UINT64 uiPacketSize,
+                                IMG_UINT64 uiBufferSize);
+
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SyncPrimPDumpValue)
+#endif
+static INLINE IMG_VOID
+SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
+{
+       PVR_UNREFERENCED_PARAMETER(psSync);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SyncPrimPDump)
+#endif
+static INLINE IMG_VOID
+SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync)
+{
+       PVR_UNREFERENCED_PARAMETER(psSync);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SyncPrimPDumpPol)
+#endif
+static INLINE IMG_VOID
+SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                IMG_UINT32 ui32Value,
+                                IMG_UINT32 ui32Mask,
+                                PDUMP_POLL_OPERATOR eOperator,
+                                IMG_UINT32 ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psSync);
+       PVR_UNREFERENCED_PARAMETER(ui32Value);
+       PVR_UNREFERENCED_PARAMETER(ui32Mask);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SyncPrimServerPDumpPol)
+#endif
+static INLINE IMG_VOID
+SyncPrimServerPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                PDUMP_POLL_OPERATOR eOperator,
+                                IMG_UINT32 ui32PDumpFlags)
+{
+       PVR_UNREFERENCED_PARAMETER(psSync);
+       PVR_UNREFERENCED_PARAMETER(eOperator);
+       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SyncPrimPDumpCBP)
+#endif
+static INLINE IMG_VOID 
+SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                IMG_UINT64 uiWriteOffset,
+                                IMG_UINT64 uiPacketSize,
+                                IMG_UINT64 uiBufferSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psSync);
+       PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+       PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+       PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+}
+#endif /* PDUMP */
+#endif /* _PVRSRV_SYNC_ */
+
diff --git a/drivers/gpu/rogue_m/services/shared/include/sync_internal.h b/drivers/gpu/rogue_m/services/shared/include/sync_internal.h
new file mode 100644 (file)
index 0000000..3821699
--- /dev/null
@@ -0,0 +1,125 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services internal synchronisation interface header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Defines the internal client side interface for services
+                synchronisation
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SYNC_INTERNAL_
+#define _SYNC_INTERNAL_
+
+#include "img_types.h"
+#include "sync_external.h"
+#include "ra.h"
+#include "dllist.h"
+#include "lock.h"
+#include "devicemem.h"
+
+/*
+       Private structure's
+*/
+#define SYNC_PRIM_NAME_SIZE            50
+typedef struct SYNC_PRIM_CONTEXT
+{
+       SYNC_BRIDGE_HANDLE                      hBridge;                                                /*!< Bridge handle */
+       IMG_HANDLE                                      hDeviceNode;                                    /*!< The device we're operating on */
+       IMG_CHAR                                        azName[SYNC_PRIM_NAME_SIZE];    /*!< Name of the RA */
+       RA_ARENA                                        *psSubAllocRA;                                  /*!< RA context */
+       IMG_CHAR                                        azSpanName[SYNC_PRIM_NAME_SIZE];/*!< Name of the span RA */
+       RA_ARENA                                        *psSpanRA;                                              /*!< RA used for span management of SubAllocRA */
+       ATOMIC_T                                hRefCount;      /*!< Ref count for this context */
+} SYNC_PRIM_CONTEXT;
+
+typedef struct _SYNC_PRIM_BLOCK_
+{
+       SYNC_PRIM_CONTEXT       *psContext;                             /*!< Our copy of the services connection */
+       IMG_HANDLE                      hServerSyncPrimBlock;   /*!< Server handle for this block */
+       IMG_UINT32                      ui32SyncBlockSize;              /*!< Size of the sync prim block */
+       IMG_UINT32                      ui32FirmwareAddr;               /*!< Firmware address */
+       DEVMEM_MEMDESC          *hMemDesc;                              /*!< Host mapping handle */
+       IMG_UINT32                      *pui32LinAddr;                  /*!< User CPU mapping */
+       IMG_UINT64                      uiSpanBase;                             /*!< Base of this import in the span RA */
+       DLLIST_NODE                     sListNode;                              /*!< List node for the sync block list */
+} SYNC_PRIM_BLOCK;
+
+typedef enum _SYNC_PRIM_TYPE_
+{
+       SYNC_PRIM_TYPE_UNKNOWN = 0,
+       SYNC_PRIM_TYPE_LOCAL,
+       SYNC_PRIM_TYPE_SERVER,
+} SYNC_PRIM_TYPE;
+
+typedef struct _SYNC_PRIM_LOCAL_
+{
+       ATOMIC_T                                hRefCount;      /*!< Ref count for this sync */
+       SYNC_PRIM_BLOCK                 *psSyncBlock;   /*!< Synchronisation block this primitive is allocated on */
+       IMG_UINT64                              uiSpanAddr;             /*!< Span address of the sync */
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+       IMG_HANDLE                              hRecord;                /*!< Sync record handle */
+#endif
+} SYNC_PRIM_LOCAL;
+
+typedef struct _SYNC_PRIM_SERVER_
+{
+       SYNC_BRIDGE_HANDLE              hBridge;                        /*!< Bridge handle */
+       IMG_HANDLE                              hServerSync;            /*!< Handle to the server sync */
+       IMG_UINT32                              ui32FirmwareAddr;       /*!< Firmware address of the sync */
+} SYNC_PRIM_SERVER;
+
+typedef struct _SYNC_PRIM_
+{
+       PVRSRV_CLIENT_SYNC_PRIM sCommon;                /*!< Client visible part of the sync prim */
+       SYNC_PRIM_TYPE                  eType;                  /*!< Sync primative type */
+       union {
+               SYNC_PRIM_LOCAL         sLocal;                 /*!< Local sync primative data */
+               SYNC_PRIM_SERVER        sServer;                /*!< Server sync primative data */
+       } u;
+} SYNC_PRIM;
+
+
+/* FIXME this must return a correctly typed pointer */
+IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync);
+
+IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync,
+                                                       IMG_HANDLE *phBlock,
+                                                       IMG_UINT32 *pui32Offset);
+
+
+#endif /* _SYNC_INTERNAL_ */
diff --git a/drivers/gpu/rogue_m/services/shared/include/tlclient.h b/drivers/gpu/rogue_m/services/shared/include/tlclient.h
new file mode 100644 (file)
index 0000000..3a81ef6
--- /dev/null
@@ -0,0 +1,169 @@
+/*************************************************************************/ /*!
+@File           tlclient.h
+@Title          Services Transport Layer shared API
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Transport layer common API used in both clients and server
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef TLCLIENT_H_
+#define TLCLIENT_H_
+
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "services.h"
+
+#include "pvr_tlcommon.h"
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientConnect
+ @Description  Initialise direct connection to Services kernel server
+                transport layer
+ @Output               phSrvHandle     Address of a pointer to a connection object
+ @Return        PVRSRV_ERROR:  for system error codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientConnect(IMG_HANDLE* phSrvHandle);
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientDisconnect
+ @Description  Disconnect from the direct connected Services kernel server
+                transport layer
+ @Input                        hSrvHandle      Handle to connection object as returned from
+                                                       TLClientConnect()
+ @Return        PVRSRV_ERROR:  for system error codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientDisconnect(IMG_HANDLE hSrvHandle);
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientOpenStream
+ @Description  Open a descriptor onto an existing kernel transport stream.
+ @Input                        hSrvHandle      Address of a pointer to a connection object
+ @Input                        pszName                 Address of the stream name string, no longer
+                                                               than PRVSRVTL_MAX_STREAM_NAME_SIZE.
+ @Input                        ui32Mode                Unused
+ @Output               phSD                    Address of a pointer to an stream object
+ @Return               PVRSRV_ERROR_NOT_FOUND:        when named stream not found
+ @Return               PVRSRV_ERROR_ALREADY_OPEN:     stream already open by another
+ @Return               PVRSRV_ERROR_STREAM_ERROR:     internal driver state error
+ @Return        PVRSRV_ERROR_TIMEOUT:          block timed out, stream not found
+ @Return               PVRSRV_ERROR:                          for other system codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientOpenStream(IMG_HANDLE hSrvHandle,
+               IMG_PCHAR    pszName,
+               IMG_UINT32   ui32Mode,
+               IMG_HANDLE*  phSD);
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientCloseStream
+ @Description  Close and release the stream connection to Services kernel
+                               server transport layer. Any outstanding Acquire will be
+                               released.
+ @Input                        hSrvHandle      Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to close
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND: when SD handle is not known
+ @Return               PVRSRV_ERROR_STREAM_ERROR:        internal driver state error
+ @Return               PVRSRV_ERROR:                             for system codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientCloseStream(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE hSD);
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientAcquireData
+ @Description  When there is data available in the stream buffer this call
+                               returns with the address and length of the data buffer the
+                               client can safely read. This buffer may contain one or more
+                               packets of data.
+                               If no data is available then this call blocks until it becomes
+                               available. However if the stream has been destroyed while
+                               waiting then a resource unavailable error will be returned
+                               to the caller. Clients must pair this call with a
+                               ReleaseData call.
+ @Input                        hSrvHandle      Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to read
+ @Output               ppPacketBuf             Address of a pointer to an byte buffer. On exit
+                                                               pointer contains address of buffer to read from
+ @Output               puiBufLen               Pointer to an integer. On exit it is the size
+                                                               of the data to read from the packet buffer
+ @Return               PVRSRV_ERROR_RESOURCE_UNAVAILABLE: when stream no longer exists
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND:     when SD handle not known
+ @Return               PVRSRV_ERROR_STREAM_ERROR:             internal driver state error
+ @Return               PVRSRV_ERROR_RETRY:                                release not called beforehand
+ @Return        PVRSRV_ERROR_TIMEOUT:              block timed out, no data
+ @Return               PVRSRV_ERROR:                                      for other system codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientAcquireData(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE  hSD,
+               IMG_PBYTE*  ppPacketBuf,
+               IMG_UINT32* puiBufLen);
+
+
+/**************************************************************************/ /*!
+ @Function             TLClientReleaseData
+ @Description  Called after client has read the stream data out of the buffer
+                               The data is subsequently flushed from the stream buffer to make
+                               room for more data packets from the stream source.
+ @Input                        hSrvHandle      Address of a pointer to a connection object
+ @Input                        hSD                             Handle of the stream object to read
+ @Return               PVRSRV_ERROR_RESOURCE_UNAVAILABLE: when stream no longer exists
+ @Return               PVRSRV_ERROR_HANDLE_NOT_FOUND:   when SD handle not known to TL
+ @Return               PVRSRV_ERROR_STREAM_ERROR:           internal driver state error
+ @Return               PVRSRV_ERROR_RETRY:                              acquire not called beforehand
+ @Return               PVRSRV_ERROR:                    for system codes
+*/ /***************************************************************************/
+IMG_INTERNAL
+PVRSRV_ERROR TLClientReleaseData(IMG_HANDLE hSrvHandle,
+               IMG_HANDLE hSD);
+
+
+
+#endif /* TLCLIENT_H_ */
+
+/******************************************************************************
+ End of file (tlclient.h)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/Kbuild.mk b/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/Kbuild.mk
new file mode 100644 (file)
index 0000000..bc4bb63
--- /dev/null
@@ -0,0 +1,50 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm-y += \
+       services/system/$(PVR_SYSTEM)/sysconfig.o \
+       services/system/common/env/linux/pci_support.o
+
+ccflags-y += \
+       -I$(TOP)/services/system/common/env/linux \
+       -I$(TOP)/services/linux/include \
+       -I$(TOP)/kernel/drivers/staging/imgtec \
+       -I$(TOP)/include/system/rgx_tc
diff --git a/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysconfig.c b/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysconfig.c
new file mode 100644 (file)
index 0000000..94a522a
--- /dev/null
@@ -0,0 +1,733 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    System Configuration functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "sysinfo.h"
+#include "apollo_regs.h"
+
+#include "pvrsrv_device.h"
+#include "rgxdevice.h"
+#include "syscommon.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+
+#if defined(SUPPORT_ION)
+#include PVR_ANDROID_ION_HEADER
+#include "ion_support.h"
+#include "ion_sys.h"
+#endif
+
+#include "apollo_drv.h"
+
+#include <linux/platform_device.h>
+
+#if !defined(LMA)
+#error Apollo only supports LMA at the minute
+#endif
+
+#define TC_SYSTEM_NAME         "Rogue Test Chip"
+
+/* Valid values for the TC_MEMORY_CONFIG configuration option */
+#define TC_MEMORY_LOCAL                (1)
+#define TC_MEMORY_HOST         (2)
+#define TC_MEMORY_HYBRID       (3)
+#define TC_MEMORY_DIRECT_MAPPED        (4)
+
+#if TC_MEMORY_CONFIG != TC_MEMORY_LOCAL
+#error Apollo only supports TC_MEMORY_LOCAL at the minute
+#endif
+
+#define SYS_RGX_ACTIVE_POWER_LATENCY_MS (10)
+
+static PVRSRV_SYSTEM_CONFIG gsSysConfig;
+
+static RGX_TIMING_INFORMATION gsRGXTimingInfo =
+{
+       /* Initialise to 0, real value will be set in PCIInitDev() */
+       .ui32CoreClockSpeed = 0,
+       .bEnableActivePM = IMG_FALSE,
+       .bEnableRDPowIsland = IMG_FALSE,
+       .ui32ActivePMLatencyms = SYS_RGX_ACTIVE_POWER_LATENCY_MS,
+};
+
+static RGX_DATA gsRGXData =
+{
+       .psRGXTimingInfo = &gsRGXTimingInfo
+};
+static PVRSRV_DEVICE_CONFIG gsDevices[] =
+{
+       {
+               .uiFlags = 0,
+               .pszName = "RGX",
+               .eDeviceType = PVRSRV_DEVICE_TYPE_RGX,
+
+               /* Device setup information */
+               .sRegsCpuPBase = { 0 },
+               .ui32RegsSize = 0,
+
+               .ui32IRQ = APOLLO_INTERRUPT_ROGUE,
+               .bIRQIsShared = IMG_TRUE,
+               .eIRQActiveLevel = PVRSRV_DEVICE_IRQ_ACTIVE_SYSDEFAULT,
+
+               .hDevData = &gsRGXData,
+               .hSysData = IMG_NULL,
+
+               .aui32PhysHeapID = { 0, 0 },
+
+               .pfnPrePowerState = IMG_NULL,
+               .pfnPostPowerState = IMG_NULL,
+               .pfnClockFreqGet = IMG_NULL,
+               .pfnInterruptHandled = IMG_NULL,
+               .pfnCheckMemAllocSize = SysCheckMemAllocSize,
+
+               .eBPDM = RGXFWIF_DM_TA,
+               .bBPSet = IMG_FALSE
+       }
+};
+
+static void TCLocalCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                     IMG_UINT32 ui32NumOfAddr,
+                                     IMG_DEV_PHYADDR *psDevPAddr,
+                                     IMG_CPU_PHYADDR *psCpuPAddr);
+
+static void TCLocalDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                     IMG_UINT32 ui32NumOfAddr,
+                                     IMG_CPU_PHYADDR *psCpuPAddr,
+                                     IMG_DEV_PHYADDR *psDevPAddr);
+static PHYS_HEAP_FUNCTIONS gsLocalPhysHeapFuncs =
+{
+       .pfnCpuPAddrToDevPAddr = TCLocalCpuPAddrToDevPAddr,
+       .pfnDevPAddrToCpuPAddr = TCLocalDevPAddrToCpuPAddr,
+};
+
+static void TCIonCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                   IMG_UINT32 ui32NumOfAddr,
+                                   IMG_DEV_PHYADDR *psDevPAddr,
+                                   IMG_CPU_PHYADDR *psCpuPAddr);
+
+static void TCIonDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                   IMG_UINT32 ui32NumOfAddr,
+                                   IMG_CPU_PHYADDR *psCpuPAddr,
+                                   IMG_DEV_PHYADDR *psDevPAddr);
+
+static PHYS_HEAP_FUNCTIONS gsIonPhysHeapFuncs =
+{
+       .pfnCpuPAddrToDevPAddr = TCIonCpuPAddrToDevPAddr,
+       .pfnDevPAddrToCpuPAddr = TCIonDevPAddrToCpuPAddr,
+};
+
+static PHYS_HEAP_CONFIG        gsPhysHeapConfig[] =
+{
+       {
+               .ui32PhysHeapID = 0,
+               .eType = PHYS_HEAP_TYPE_LMA,
+               .sStartAddr = { 0 },
+               .uiSize = 0,
+               .pszPDumpMemspaceName = "LMA",
+               .psMemFuncs = &gsLocalPhysHeapFuncs,
+               .hPrivData = (IMG_HANDLE)&gsSysConfig,
+       },
+       {
+               .ui32PhysHeapID = 1,
+               .eType = PHYS_HEAP_TYPE_LMA,
+               .sStartAddr = { 0 },
+               .uiSize = 0,
+               .pszPDumpMemspaceName = "LMA",
+               .psMemFuncs = &gsIonPhysHeapFuncs,
+               .hPrivData = (IMG_HANDLE)&gsSysConfig,
+       }
+};
+
+/* default BIF tiling heap x-stride configurations. */
+static IMG_UINT32 gauiBIFTilingHeapXStrides[RGXFWIF_NUM_BIF_TILING_CONFIGS] =
+{
+       0, /* BIF tiling heap 1 x-stride */
+       1, /* BIF tiling heap 2 x-stride */
+       2, /* BIF tiling heap 3 x-stride */
+       3  /* BIF tiling heap 4 x-stride */
+};
+
+static PVRSRV_SYSTEM_CONFIG gsSysConfig =
+{
+       .uiSysFlags = 0,
+       .pszSystemName = TC_SYSTEM_NAME,
+       .uiDeviceCount = ARRAY_SIZE(gsDevices),
+       .pasDevices = &gsDevices[0],
+
+       .pfnSysPrePowerState = IMG_NULL,
+       .pfnSysPostPowerState = IMG_NULL,
+
+       .eCacheSnoopingMode = PVRSRV_SYSTEM_SNOOP_NONE,
+
+       .pasPhysHeaps = &gsPhysHeapConfig[0],
+       .ui32PhysHeapCount = ARRAY_SIZE(gsPhysHeapConfig),
+
+       .pui32BIFTilingHeapConfigs = &gauiBIFTilingHeapXStrides[0],
+       .ui32BIFTilingHeapCount = ARRAY_SIZE(gauiBIFTilingHeapXStrides),
+};
+
+
+typedef struct _SYS_DATA_ SYS_DATA;
+
+extern struct platform_device *gpsPVRLDMDev;
+
+struct _SYS_DATA_
+{
+       IMG_UINT32              uiRefCount;
+
+       struct pci_dev *pcidev;
+
+       struct platform_device *pdev;
+
+       struct apollo_rogue_platform_data *pdata;
+
+       IMG_CHAR                *pszSystemInfoString;
+
+       PVRSRV_SYS_POWER_STATE  ePowerState;
+
+#if defined(SUPPORT_ION)
+       struct ion_client *ion_client;
+       struct ion_handle *ion_rogue_allocation;
+#endif
+
+       IMG_HANDLE              hFlashData;
+
+};
+
+#define SYSTEM_INFO_FORMAT_STRING      "%s\tFPGA Revision: %s\tTCF Core Revision: %s\tTCF Core Target Build ID: %s\tPCI Version: %s\tMacro Version: %s"
+static IMG_CHAR *GetSystemInfoString(SYS_DATA *psSysData)
+{
+       int err;
+       char str_fpga_rev[12];
+       char str_tcf_core_rev[12];
+       char str_tcf_core_target_build_id[4];
+       char str_pci_ver[4];
+       char str_macro_ver[8];
+
+       IMG_CHAR *pszSystemInfoString;
+       IMG_UINT32 ui32StringLength;
+
+       struct apollo_rogue_platform_data *pdata = ((struct platform_device*)gpsPVRLDMDev)->dev.platform_data;
+
+       err = apollo_sys_strings(&pdata->pdev->dev, //&psSysData->pdev->dev,
+                                                        str_fpga_rev, sizeof(str_fpga_rev),
+                                                        str_tcf_core_rev, sizeof(str_tcf_core_rev),
+                                                        str_tcf_core_target_build_id, sizeof(str_tcf_core_target_build_id),
+                                                        str_pci_ver, sizeof(str_pci_ver),
+                                                        str_macro_ver, sizeof(str_macro_ver));
+       if (err)
+       {
+               return NULL;
+       }
+
+       ui32StringLength = OSStringLength(SYSTEM_INFO_FORMAT_STRING);
+       ui32StringLength += OSStringLength(TC_SYSTEM_NAME);
+       ui32StringLength += OSStringLength(str_fpga_rev);
+       ui32StringLength += OSStringLength(str_tcf_core_rev);
+       ui32StringLength += OSStringLength(str_tcf_core_target_build_id);
+       ui32StringLength += OSStringLength(str_pci_ver);
+       ui32StringLength += OSStringLength(str_macro_ver);
+
+       /* Create the system info string */
+       pszSystemInfoString = OSAllocZMem(ui32StringLength * sizeof(IMG_CHAR));
+       if (pszSystemInfoString)
+       {
+               OSSNPrintf(&pszSystemInfoString[0], ui32StringLength, SYSTEM_INFO_FORMAT_STRING, TC_SYSTEM_NAME,
+                                  str_fpga_rev,
+                                  str_tcf_core_rev,
+                                  str_tcf_core_target_build_id,
+                                  str_pci_ver,
+                                  str_macro_ver);
+       }
+
+       return pszSystemInfoString;
+}
+
+#if defined(SUPPORT_ION)
+static SYS_DATA *gpsIonPrivateData;
+
+PVRSRV_ERROR IonInit(void *pvPrivateData)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       SYS_DATA *psSysData = pvPrivateData;
+       gpsIonPrivateData = psSysData;
+
+       psSysData->ion_client = ion_client_create(psSysData->pdata->ion_device, SYS_RGX_DEV_NAME);
+       if (IS_ERR(psSysData->ion_client))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create ION client (%ld)", __func__, PTR_ERR(psSysData->ion_client)));
+               /* FIXME: Find a better matching error code */
+               eError = PVRSRV_ERROR_PCI_CALL_FAILED;
+               goto err_out;
+       }
+       /* Allocate the whole rogue ion heap and pass that to services to manage */
+       psSysData->ion_rogue_allocation = ion_alloc(psSysData->ion_client, psSysData->pdata->rogue_heap_memory_size, 4096, (1 << psSysData->pdata->ion_heap_id), 0);
+       if (IS_ERR(psSysData->ion_rogue_allocation))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate ION rogue buffer (%ld)", __func__, PTR_ERR(psSysData->ion_rogue_allocation)));
+               /* FIXME: Find a better matching error code */
+               eError = PVRSRV_ERROR_PCI_CALL_FAILED;
+               goto err_destroy_client;
+
+       }
+
+       return PVRSRV_OK;
+err_destroy_client:
+       ion_client_destroy(psSysData->ion_client);
+       psSysData->ion_client = NULL;
+err_out:
+       return eError;
+}
+
+void IonDeinit(void)
+{
+       SYS_DATA *psSysData = gpsIonPrivateData;
+       ion_free(psSysData->ion_client, psSysData->ion_rogue_allocation);
+       psSysData->ion_rogue_allocation = NULL;
+       ion_client_destroy(psSysData->ion_client);
+       psSysData->ion_client = NULL;
+}
+
+IMG_DEV_PHYADDR IonCPUPhysToDevPhys(IMG_CPU_PHYADDR sCPUPhysAddr,
+                                    IMG_UINT32 ui32Offset)
+{
+       IMG_DEV_PHYADDR sDevPAddr =
+       {
+                       .uiAddr = sCPUPhysAddr.uiAddr + ui32Offset -
+                                         gpsIonPrivateData->pdata->apollo_memory_base,
+       };
+
+       PVR_ASSERT(sCPUPhysAddr.uiAddr + ui32Offset
+               >= gpsIonPrivateData->pdata->pdp_heap_memory_base);
+       PVR_ASSERT(sCPUPhysAddr.uiAddr + ui32Offset
+               < gpsIonPrivateData->pdata->pdp_heap_memory_base
+                       + gpsIonPrivateData->pdata->pdp_heap_memory_size);
+
+       return sDevPAddr;
+}
+
+struct ion_device *IonDevAcquire(void)
+{
+       return gpsIonPrivateData->pdata->ion_device;
+}
+
+void IonDevRelease(struct ion_device *ion_device)
+{
+       PVR_ASSERT(ion_device == gpsIonPrivateData->pdata->ion_device);
+}
+
+IMG_UINT32 IonPhysHeapID(void)
+{
+       /* This seems to be the services heap that ION allocations should be mapped into
+        * FIXME: This may depend on the allocation? Eg. if allocations can come
+        * from more than one heap?*/
+       return 1;
+}
+#endif /* defined(SUPPORT_ION) */
+
+static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData)
+{
+       PVRSRV_DEVICE_CONFIG *psDevice = &gsSysConfig.pasDevices[0];
+       PVRSRV_ERROR eError;
+       int err = 0;
+
+       err = pci_enable_device(psSysData->pcidev);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to enable PCI device (%d)", __func__, err));
+               eError = PVRSRV_ERROR_PCI_CALL_FAILED;
+               goto err_out;
+       }
+
+#if defined(SUPPORT_ION)
+       eError = IonInit(psSysData);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Failed to initialise ION", __func__));
+               goto ErrorPCIReleaseDevice;
+       }
+#endif
+
+       /* FIXME: Use ion_phys on the allocation? */
+       gsPhysHeapConfig[0].uiSize =
+               psSysData->pdata->rogue_heap_memory_size;
+
+       gsPhysHeapConfig[0].sStartAddr.uiAddr =
+               psSysData->pdata->rogue_heap_memory_base;
+
+
+
+       gsPhysHeapConfig[1].uiSize = psSysData->pdata->pdp_heap_memory_size;
+       gsPhysHeapConfig[1].sStartAddr.uiAddr = psSysData->pdata->pdp_heap_memory_base;
+
+       /* Setup Rogue register information */
+       psDevice->sRegsCpuPBase.uiAddr  = pci_resource_start(psSysData->pcidev, SYS_RGX_REG_PCI_BASENUM);
+       psDevice->ui32RegsSize          = pci_resource_len(psSysData->pcidev, SYS_RGX_REG_PCI_BASENUM);
+
+       /* Save data for this device */
+       psDevice->hSysData = (IMG_HANDLE)psSysData;
+
+       /* Check the address range is large enough. */
+       if (psDevice->ui32RegsSize < SYS_RGX_REG_REGION_SIZE)
+       {
+               PVR_DPF((PVR_DBG_ERROR,
+                        "%s: Rogue register region isn't big enough (was 0x%08x, required 0x%08x)",
+                        __FUNCTION__, psDevice->ui32RegsSize, SYS_RGX_REG_REGION_SIZE));
+
+               eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL;
+               goto ErrorDeInitION;
+       }
+
+       /* Reserve the address range */
+       err = pci_request_region(psSysData->pcidev, SYS_RGX_REG_PCI_BASENUM, SYS_RGX_DEV_NAME);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: Rogue register memory region not available", __FUNCTION__));
+               eError = PVRSRV_ERROR_PCI_CALL_FAILED;
+
+               goto ErrorDeInitION;
+       }
+
+       /* Override the system name if we can get the system info string */
+       psSysData->pszSystemInfoString = GetSystemInfoString(psSysData);
+       if (psSysData->pszSystemInfoString)
+       {
+               gsSysConfig.pszSystemName = psSysData->pszSystemInfoString;
+       }
+
+       /* Make the core clock speed value available to the driver */
+       ((RGX_DATA *)psDevice->hDevData)->psRGXTimingInfo->ui32CoreClockSpeed = apollo_core_clock_speed(&psSysData->pdev->dev) * 6;
+
+       return PVRSRV_OK;
+
+ErrorDeInitION:
+#if defined(SUPPORT_ION)
+       IonDeinit();
+ErrorPCIReleaseDevice:
+#endif
+       pci_disable_device(psSysData->pcidev);
+err_out:
+       return eError;
+}
+
+static void PCIDeInitDev(SYS_DATA *psSysData)
+{
+       PVRSRV_DEVICE_CONFIG *psDevice = &gsSysConfig.pasDevices[0];
+
+       if (psSysData->pszSystemInfoString)
+       {
+               OSFreeMem(psSysData->pszSystemInfoString);
+               psSysData->pszSystemInfoString = NULL;
+       }
+
+#if defined(SUPPORT_ION)
+       IonDeinit();
+#endif
+
+       pci_release_region(psSysData->pcidev, SYS_RGX_REG_PCI_BASENUM);
+       psDevice->sRegsCpuPBase.uiAddr  = 0;
+       psDevice->ui32RegsSize          = 0;
+
+       pci_disable_device(psSysData->pcidev);
+       psSysData->pcidev = NULL;
+}
+
+static void TCLocalCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                     IMG_UINT32 ui32NumOfAddr,
+                                     IMG_DEV_PHYADDR *psDevPAddr,
+                                     IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       PVRSRV_SYSTEM_CONFIG *psSysConfig = (PVRSRV_SYSTEM_CONFIG *)hPrivData;
+
+       /* Optimise common case */
+       psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr - psSysConfig->pasPhysHeaps[0].sStartAddr.uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr - psSysConfig->pasPhysHeaps[0].sStartAddr.uiAddr;
+               }
+       }
+}
+
+static void TCLocalDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                     IMG_UINT32 ui32NumOfAddr,
+                                     IMG_CPU_PHYADDR *psCpuPAddr,
+                                     IMG_DEV_PHYADDR *psDevPAddr)
+{
+       PVRSRV_SYSTEM_CONFIG *psSysConfig = (PVRSRV_SYSTEM_CONFIG *)hPrivData;
+       
+       /* Optimise common case */
+       psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr + psSysConfig->pasPhysHeaps[0].sStartAddr.uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr + psSysConfig->pasPhysHeaps[0].sStartAddr.uiAddr;
+               }
+       }
+}
+
+
+static void TCIonCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                   IMG_UINT32 ui32NumOfAddr,
+                                   IMG_DEV_PHYADDR *psDevPAddr,
+                                   IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       PVRSRV_SYSTEM_CONFIG *psSysConfig = (PVRSRV_SYSTEM_CONFIG *)hPrivData;
+       SYS_DATA *psSysData = psSysConfig->pasDevices[0].hSysData;
+       
+       /* Optimise common case */
+       psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr - psSysData->pdata->apollo_memory_base;     
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr - psSysData->pdata->apollo_memory_base;
+               }
+       }
+}
+
+static void TCIonDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                   IMG_UINT32 ui32NumOfAddr,
+                                   IMG_CPU_PHYADDR *psCpuPAddr,
+                                   IMG_DEV_PHYADDR *psDevPAddr)
+{
+       PVRSRV_SYSTEM_CONFIG *psSysConfig = (PVRSRV_SYSTEM_CONFIG *)hPrivData;
+       SYS_DATA *psSysData = psSysConfig->pasDevices[0].hSysData;
+
+       /* Optimise common case */
+       psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr + psSysData->pdata->apollo_memory_base;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr + psSysData->pdata->apollo_memory_base;
+               }
+       }
+}
+
+PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *hDevice)
+{
+       SYS_DATA *psSysData;
+       PVRSRV_ERROR eError;
+
+       PVR_UNREFERENCED_PARAMETER(hDevice);
+
+       psSysData = OSAllocZMem(sizeof(*psSysData));
+       if (psSysData == IMG_NULL)
+       {
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       PVR_ASSERT(gpsPVRLDMDev != NULL);
+
+       psSysData->pdev = gpsPVRLDMDev;
+       psSysData->pdata = ((struct platform_device*)gpsPVRLDMDev)->dev.platform_data;
+       psSysData->pcidev = psSysData->pdata->pdev;
+
+       eError = PCIInitDev(psSysData);
+       if (eError != PVRSRV_OK)
+       {
+               goto ErrorFreeSysData;
+       }
+
+       (void)SysAcquireSystemData((IMG_HANDLE)psSysData);
+
+       *ppsSysConfig = &gsSysConfig;
+
+       return PVRSRV_OK;
+
+ErrorFreeSysData:
+       OSFreeMem(psSysData);
+
+       return eError;
+}
+
+void SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig)
+{
+       SYS_DATA *psSysData = (SYS_DATA *)psSysConfig->pasDevices[0].hSysData;
+
+       PCIDeInitDev(psSysData);
+
+       (void)SysReleaseSystemData((IMG_HANDLE)psSysData);
+}
+
+PVRSRV_ERROR SysAcquireSystemData(IMG_HANDLE hSysData)
+{
+       SYS_DATA *psSysData = (SYS_DATA *)hSysData;
+
+       if (psSysData == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       psSysData->uiRefCount++;
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysReleaseSystemData(IMG_HANDLE hSysData)
+{
+       SYS_DATA *psSysData = (SYS_DATA *)hSysData;
+
+       if (psSysData == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       PVR_ASSERT(psSysData->uiRefCount != 0);
+       psSysData->uiRefCount--;
+
+       if (psSysData->uiRefCount == 0)
+       {
+               OSFreeMem(psSysData);
+       }
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       PVRSRV_ERROR eError = PVRSRV_OK;
+       u32 tmp = 0;
+       u32 pll;
+
+       struct apollo_rogue_platform_data *pdata = ((struct platform_device*)gpsPVRLDMDev)->dev.platform_data;
+
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+
+       PVR_DUMPDEBUG_LOG(("------[ rgx_tc system debug ]------"));
+
+       if (apollo_sys_info(&pdata->pdev->dev, &tmp, &pll))
+               goto err_out;
+
+       if (tmp > 0)
+               PVR_DUMPDEBUG_LOG(("Chip temperature: %d degrees C", tmp));
+       PVR_DUMPDEBUG_LOG(("PLL status: %x", pll));
+
+err_out:
+       return eError;
+}
+
+typedef struct
+{
+       struct device *psDev;
+       int iInterruptID;
+       void *pvData;
+       PFN_LISR pfnLISR;
+} LISR_DATA;
+
+static void ApolloInterruptHandler(void* pvData)
+{
+       LISR_DATA *psLISRData = pvData;
+       psLISRData->pfnLISR(psLISRData->pvData);
+}
+
+PVRSRV_ERROR SysInstallDeviceLISR(IMG_UINT32 ui32IRQ,
+                                 IMG_CHAR *pszName,
+                                 PFN_LISR pfnLISR,
+                                 void *pvData,
+                                 IMG_HANDLE *phLISRData)
+{
+       LISR_DATA *psLISRData;
+       PVRSRV_ERROR eError;
+       int err;
+       struct apollo_rogue_platform_data *pdata = ((struct platform_device*)gpsPVRLDMDev)->dev.platform_data;
+
+       PVR_DPF((PVR_DBG_ERROR, "%s: Trying to install LISR %p to irq %u", __func__, pfnLISR, ui32IRQ));
+       psLISRData = OSAllocZMem(sizeof(*psLISRData));
+       if (!psLISRData)
+       {
+               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+               goto err_out;
+       }
+       psLISRData->pfnLISR = pfnLISR;
+       psLISRData->pvData = pvData;
+       psLISRData->iInterruptID = APOLLO_INTERRUPT_ROGUE;
+       psLISRData->psDev = &pdata->pdev->dev;
+       err = apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, ApolloInterruptHandler, psLISRData);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: apollo_set_interrupt_handler() failed (%d)", __func__, err));
+               eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+               goto err_free_data;
+       }
+       err = apollo_enable_interrupt(psLISRData->psDev, psLISRData->iInterruptID);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: apollo_enable_interrupt() failed (%d)", __func__, err));
+               eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+               goto err_unset_interrupt_handler;
+       }
+
+       *phLISRData = psLISRData;
+       eError = PVRSRV_OK;
+err_out:
+       return eError;
+err_unset_interrupt_handler:
+       apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, NULL, NULL);
+err_free_data:
+       OSFreeMem(psLISRData);
+       goto err_out;
+}
+
+PVRSRV_ERROR SysUninstallDeviceLISR(IMG_HANDLE hLISRData)
+{
+       LISR_DATA *psLISRData = (LISR_DATA *) hLISRData;
+       int err = apollo_disable_interrupt(psLISRData->psDev, psLISRData->iInterruptID);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: apollo_enable_interrupt() failed (%d)", __func__, err));
+       }
+       err = apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, NULL, NULL);
+       if (err)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: apollo_set_interrupt_handler() failed (%d)", __func__, err));
+       }
+       OSFreeMem(psLISRData);
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysinfo.h b/drivers/gpu/rogue_m/services/system/rgx_linux_apollo/sysinfo.h
new file mode 100644 (file)
index 0000000..8803ac5
--- /dev/null
@@ -0,0 +1,66 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#if defined (VIRTUAL_PLATFORM)
+#define MAX_HW_TIME_US                           (240000000)
+#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT  (120000)
+#else
+#define MAX_HW_TIME_US                           (500000)
+#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT  (10000)
+#endif
+#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT (3600000)
+#define WAIT_TRY_COUNT                           (10000)
+
+/* RGX, DISPLAY (external), BUFFER (external) */
+#define SYS_DEVICE_COUNT       (3)
+
+/* This should be one higher than the highest possible physical heap ID */
+#define SYS_PHYS_HEAP_COUNT 2
+
+#define SYS_RGX_DEV_NAME "apollo_rogue"
+
+#endif /* !defined(__SYSINFO_H__) */
diff --git a/drivers/gpu/rogue_m/services/system/rgx_nohw/Kbuild.mk b/drivers/gpu/rogue_m/services/system/rgx_nohw/Kbuild.mk
new file mode 100644 (file)
index 0000000..54bebc4
--- /dev/null
@@ -0,0 +1,46 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm-y += services/system/$(PVR_SYSTEM)/sysconfig.o
+
+ifeq ($(SUPPORT_ION),1)
+pvrsrvkm-y += services/system/common/env/linux/ion_support_generic.o
+endif
diff --git a/drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.c b/drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.c
new file mode 100644 (file)
index 0000000..082deec
--- /dev/null
@@ -0,0 +1,258 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    System Configuration functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "syscommon.h"
+#include "sysconfig.h"
+#include "physheap.h"
+#if defined(SUPPORT_ION)
+#include "ion_support.h"
+#endif
+
+static RGX_TIMING_INFORMATION  gsRGXTimingInfo;
+static RGX_DATA                        gsRGXData;
+static PVRSRV_DEVICE_CONFIG    gsDevices[1];
+static PVRSRV_SYSTEM_CONFIG    gsSysConfig;
+
+static PHYS_HEAP_FUNCTIONS     gsPhysHeapFuncs;
+#if defined(TDMETACODE)
+static PHYS_HEAP_CONFIG                gsPhysHeapConfig[3];
+#else
+static PHYS_HEAP_CONFIG                gsPhysHeapConfig[1];
+#endif
+
+/*
+       CPU to Device physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+       
+       /* Optimise common case */
+       psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       Device to CPU physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr)                           
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+       
+       /* Optimise common case */
+       psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       SysCreateConfigData
+*/
+PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *device)
+{
+       PVR_UNREFERENCED_PARAMETER(device);
+
+       /*
+        * Setup information about physical memory heap(s) we have
+        */
+       gsPhysHeapFuncs.pfnCpuPAddrToDevPAddr = UMAPhysHeapCpuPAddrToDevPAddr;
+       gsPhysHeapFuncs.pfnDevPAddrToCpuPAddr = UMAPhysHeapDevPAddrToCpuPAddr;
+
+       gsPhysHeapConfig[0].ui32PhysHeapID = 0;
+       gsPhysHeapConfig[0].pszPDumpMemspaceName = "SYSMEM";
+       gsPhysHeapConfig[0].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[0].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[0].hPrivData = IMG_NULL;
+
+#if defined(TDMETACODE)
+       gsPhysHeapConfig[1].ui32PhysHeapID = 1;
+       gsPhysHeapConfig[1].pszPDumpMemspaceName = "TDMETACODEMEM";
+       gsPhysHeapConfig[1].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[1].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[1].hPrivData = IMG_NULL;
+
+       gsPhysHeapConfig[2].ui32PhysHeapID = 2;
+       gsPhysHeapConfig[2].pszPDumpMemspaceName = "TDSECUREBUFMEM";
+       gsPhysHeapConfig[2].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[2].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[2].hPrivData = IMG_NULL;
+#endif
+
+       gsSysConfig.pasPhysHeaps = &(gsPhysHeapConfig[0]);
+       gsSysConfig.ui32PhysHeapCount = IMG_ARR_NUM_ELEMS(gsPhysHeapConfig);
+
+       gsSysConfig.pui32BIFTilingHeapConfigs = gauiBIFTilingHeapXStrides;
+       gsSysConfig.ui32BIFTilingHeapCount = IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides);
+
+       /*
+        * Setup RGX specific timing data
+        */
+       gsRGXTimingInfo.ui32CoreClockSpeed        = RGX_NOHW_CORE_CLOCK_SPEED;
+       gsRGXTimingInfo.bEnableActivePM           = IMG_FALSE;
+       gsRGXTimingInfo.bEnableRDPowIsland        = IMG_FALSE;
+       gsRGXTimingInfo.ui32ActivePMLatencyms     = SYS_RGX_ACTIVE_POWER_LATENCY_MS;
+
+       /*
+        *Setup RGX specific data
+        */
+       gsRGXData.psRGXTimingInfo = &gsRGXTimingInfo;
+#if defined(TDMETACODE)
+       gsRGXData.bHasTDMetaCodePhysHeap = IMG_TRUE;
+       gsRGXData.uiTDMetaCodePhysHeapID = 1;
+
+       gsRGXData.bHasTDSecureBufPhysHeap = IMG_TRUE;
+       gsRGXData.uiTDSecureBufPhysHeapID = 2;
+#endif
+
+       /*
+        * Setup RGX device
+        */
+       gsDevices[0].eDeviceType            = PVRSRV_DEVICE_TYPE_RGX;
+       gsDevices[0].pszName                = "RGX";
+
+       /* Device setup information */
+       gsDevices[0].sRegsCpuPBase.uiAddr   = 0x00f00baa;
+       gsDevices[0].ui32RegsSize           = 0x4000;
+       gsDevices[0].ui32IRQ                = 0x00000bad;
+       gsDevices[0].bIRQIsShared           = IMG_FALSE;
+
+       /* Device's physical heap IDs */
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = 0;
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = 0;
+
+       /* No power management on no HW system */
+       gsDevices[0].pfnPrePowerState       = IMG_NULL;
+       gsDevices[0].pfnPostPowerState      = IMG_NULL;
+
+       /* No clock frequency either */
+       gsDevices[0].pfnClockFreqGet        = IMG_NULL;
+
+       /* No interrupt handled either */
+       gsDevices[0].pfnInterruptHandled    = IMG_NULL;
+
+       gsDevices[0].pfnCheckMemAllocSize   = SysCheckMemAllocSize;
+
+       gsDevices[0].hDevData               = &gsRGXData;
+
+       /*
+        * Setup system config
+        */
+       gsSysConfig.pszSystemName = RGX_NOHW_SYSTEM_NAME;
+       gsSysConfig.uiDeviceCount = sizeof(gsDevices)/sizeof(gsDevices[0]);
+       gsSysConfig.pasDevices = &gsDevices[0];
+
+       /* No power management on no HW system */
+       gsSysConfig.pfnSysPrePowerState = IMG_NULL;
+       gsSysConfig.pfnSysPostPowerState = IMG_NULL;
+
+       /* no cache snooping */
+       gsSysConfig.eCacheSnoopingMode = PVRSRV_SYSTEM_SNOOP_NONE;
+
+       /* Setup other system specific stuff */
+#if defined(SUPPORT_ION)
+       IonInit(NULL);
+#endif
+
+       *ppsSysConfig = &gsSysConfig;
+
+       return PVRSRV_OK;
+}
+
+/*
+       SysDestroyConfigData
+*/
+IMG_VOID SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+
+#if defined(SUPPORT_ION)
+       IonDeinit();
+#endif
+}
+
+PVRSRV_ERROR SysAcquireSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysReleaseSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+       PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf);
+       return PVRSRV_OK;
+}
+
+/******************************************************************************
+ End of file (sysconfig.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.h b/drivers/gpu/rogue_m/services/system/rgx_nohw/sysconfig.h
new file mode 100644 (file)
index 0000000..38a9f9f
--- /dev/null
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "rgxdevice.h"
+
+#if !defined(__SYSCCONFIG_H__)
+#define __SYSCCONFIG_H__
+
+
+#define RGX_NOHW_CORE_CLOCK_SPEED 100000000
+#define RGX_NOHW_SYSTEM_NAME "RGX No HW"
+#define SYS_RGX_ACTIVE_POWER_LATENCY_MS (100)
+
+/* default BIF tiling heap x-stride configurations. */
+static IMG_UINT32 gauiBIFTilingHeapXStrides[RGXFWIF_NUM_BIF_TILING_CONFIGS] =
+{
+       0, /* BIF tiling heap 1 x-stride */
+       1, /* BIF tiling heap 2 x-stride */
+       2, /* BIF tiling heap 3 x-stride */
+       3  /* BIF tiling heap 4 x-stride */
+};
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+#endif /* __SYSCCONFIG_H__ */
diff --git a/drivers/gpu/rogue_m/services/system/rgx_nohw/sysinfo.h b/drivers/gpu/rogue_m/services/system/rgx_nohw/sysinfo.h
new file mode 100644 (file)
index 0000000..b7efa09
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#define MAX_HW_TIME_US                           (500000)
+#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT  (10000)
+#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT (3600000)
+#define WAIT_TRY_COUNT                           (10000)
+
+#define SYS_DEVICE_COUNT 3 /* RGX, DISPLAY (external), BUFFER (external) */
+
+#if defined(TDMETACODE)
+/* in systems that support trusted device address protection, there are three
+   physical heaps from which pages should be allocated:
+   - one heap for normal allocations
+   - one heap for allocations holding META code memory
+   - one heap for allocations holding secured DRM data
+*/
+#define SYS_PHYS_HEAP_COUNT            3
+#else
+#define SYS_PHYS_HEAP_COUNT            1
+#endif
+
+#if defined(__linux__)
+#define SYS_RGX_DEV_NAME    "rgxnohw"
+#endif
+
+#endif /* !defined(__SYSINFO_H__) */
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/Kbuild.mk b/drivers/gpu/rogue_m/services/system/rgx_sunxi/Kbuild.mk
new file mode 100644 (file)
index 0000000..402e2b9
--- /dev/null
@@ -0,0 +1,49 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm-y += \
+ services/system/$(PVR_SYSTEM)/sunxi_init.o \
+ services/system/$(PVR_SYSTEM)/sysconfig.o 
+
+ifeq ($(SUPPORT_ION),1)
+pvrsrvkm-y += \
+ services/system/$(PVR_SYSTEM)/ion_support_sunxi.o
+endif
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/ion_support_sunxi.c b/drivers/gpu/rogue_m/services/system/rgx_sunxi/ion_support_sunxi.c
new file mode 100644 (file)
index 0000000..6c867ad
--- /dev/null
@@ -0,0 +1,75 @@
+/*************************************************************************/ /*!
+@File           ion_support_sunxi.c
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "ion_support.h"
+#include "ion_sys.h"
+
+extern struct ion_device *idev;
+
+PVRSRV_ERROR IonInit(void *phPrivateData)
+{
+       /* Nothing to do */
+       return PVRSRV_OK;
+}
+
+struct ion_device *IonDevAcquire(IMG_VOID)
+{
+       return idev;
+}
+
+IMG_VOID IonDevRelease(struct ion_device *psIonDev)
+{
+       /* Nothing to do, sanity check the pointer we're passed back */
+       PVR_ASSERT(psIonDev == idev);
+}
+
+IMG_UINT32 IonPhysHeapID(IMG_VOID)
+{
+       return 0;
+}
+
+IMG_VOID IonDeinit(IMG_VOID)
+{
+       /* Nothing to do */
+}
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.c b/drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.c
new file mode 100644 (file)
index 0000000..0ab0ba7
--- /dev/null
@@ -0,0 +1,462 @@
+/*************************************************************************/ /*!
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@Description    System Configuration functions
+*/ /**************************************************************************/
+
+#if defined(SUPPORT_ION)
+#include "ion_sys.h"
+#endif /* defined(SUPPORT_ION) */
+
+#include <linux/hardirq.h>
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include <linux/io.h>
+#include <linux/clk/sunxi_name.h>
+#include <linux/clk/sunxi.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <mach/sys_config.h>
+#include "power.h"
+#include "sunxi_init.h"
+#include "pvrsrv_device.h"
+#include "syscommon.h"
+
+#ifdef CONFIG_CPU_BUDGET_THERMAL
+#include <linux/cpu_budget_cooling.h>
+static int Is_powernow = 0;
+#endif /* CONFIG_CPU_BUDGET_THERMAL */
+
+static const IMG_OPP asOPPTable[] =
+{
+#if defined(PVR_DVFS)
+       { 824,  240},
+       { 840,  260},
+       { 856,  280},
+       { 872,  300},
+       { 887,  320},
+       { 903,  340},
+       { 919,  360},
+       { 935,  380},
+       { 951,  400},
+       { 996,  420},
+       { 982,  440},
+       { 998,  460},
+       { 1014, 480},
+       { 1029, 500},
+       { 1045, 520},
+       { 1061, 540},
+#else
+       { 700,  48},
+       { 800, 120},
+       { 800, 240},
+       { 900, 320},
+       { 900, 384},
+       {1000, 480},
+       {1100, 528},
+#endif
+};
+
+#define LEVEL_COUNT (sizeof(asOPPTable) / sizeof(asOPPTable[0]))
+
+#define AXI_CLK_FREQ 320
+#define GPU_CTRL "gpuctrl"
+
+static struct clk *gpu_core_clk        = NULL;
+static struct clk *gpu_mem_clk         = NULL;
+static struct clk *gpu_axi_clk         = NULL;
+static struct clk *gpu_pll_clk         = NULL;
+static struct clk *gpu_ctrl_clk        = NULL;
+static struct regulator *rgx_regulator = NULL;
+static char *regulator_id              = "axp22_dcdc2";
+
+#if defined(PVR_DVFS)
+       #define DEFAULT_MIN_VL_LEVEL 0
+#else
+       #define DEFAULT_MIN_VL_LEVEL 4
+#endif
+
+static IMG_UINT32 min_vf_level_val     = DEFAULT_MIN_VL_LEVEL;
+static IMG_UINT32 max_vf_level_val     = LEVEL_COUNT - 1;
+
+static PVRSRV_DEVICE_CONFIG* gpsDevConfig = NULL;
+
+long int GetConfigFreq(IMG_VOID)
+{
+    return asOPPTable[min_vf_level_val].ui32Freq*1000*1000;
+}
+
+IMG_UINT32 AwClockFreqGet(IMG_HANDLE hSysData)
+{
+       return (IMG_UINT32)clk_get_rate(gpu_core_clk);
+}
+
+static IMG_VOID AssertGpuResetSignal(IMG_VOID)
+{
+       if(sunxi_periph_reset_assert(gpu_core_clk))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to pull down gpu reset!"));
+       }
+       if(sunxi_periph_reset_assert(gpu_ctrl_clk))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to pull down gpu control reset!"));
+       }
+}
+
+static IMG_VOID DeAssertGpuResetSignal(IMG_VOID)
+{
+       if(sunxi_periph_reset_deassert(gpu_ctrl_clk))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to release gpu control reset!"));
+       }
+       if(sunxi_periph_reset_deassert(gpu_core_clk))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to release gpu reset!"));
+       }
+}
+
+static IMG_VOID RgxEnableClock(IMG_VOID)
+{
+       if(gpu_core_clk->enable_count == 0)
+       {       
+               if(clk_prepare_enable(gpu_pll_clk))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to enable pll9 clock!"));
+               }
+               if(clk_prepare_enable(gpu_core_clk))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to enable core clock!"));
+               }
+               if(clk_prepare_enable(gpu_mem_clk))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to enable mem clock!"));
+               }
+               if(clk_prepare_enable(gpu_axi_clk))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to enable axi clock!"));
+               }
+               if(clk_prepare_enable(gpu_ctrl_clk))
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "Failed to enable ctrl clock!"));
+               }
+       }
+}
+
+static IMG_VOID RgxDisableClock(IMG_VOID)
+{                              
+       if(gpu_core_clk->enable_count == 1)
+       {
+               clk_disable_unprepare(gpu_ctrl_clk);            
+               clk_disable_unprepare(gpu_axi_clk);
+               clk_disable_unprepare(gpu_mem_clk);     
+               clk_disable_unprepare(gpu_core_clk);
+               clk_disable_unprepare(gpu_pll_clk);
+       }
+}
+
+static IMG_VOID RgxEnablePower(IMG_VOID)
+{
+       if(!regulator_is_enabled(rgx_regulator))
+       {
+               regulator_enable(rgx_regulator);                
+       }
+}
+
+static IMG_VOID RgxDisablePower(IMG_VOID)
+{
+       if(regulator_is_enabled(rgx_regulator))
+       {
+               regulator_disable(rgx_regulator);               
+       }
+}
+
+void SetVoltage(IMG_UINT32 ui32Volt)
+{
+       if(regulator_set_voltage(rgx_regulator, ui32Volt*1000, ui32Volt*1000) != 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to set gpu power voltage!"));
+       }
+}
+
+static void SetClkVal(const char clk_name[], int freq)
+{
+       struct clk *clk = NULL;
+       
+       if(!strcmp(clk_name, "pll"))
+       {
+               clk = gpu_pll_clk;
+       }
+       else if(!strcmp(clk_name, "core"))
+       {
+               clk = gpu_core_clk;
+       }
+       else if(!strcmp(clk_name, "mem"))
+       {
+               clk = gpu_mem_clk;
+       }
+       else
+       {
+               clk = gpu_axi_clk;
+       }
+       
+       if(clk_set_rate(clk, freq*1000*1000))
+    {
+               clk = NULL;
+               return;
+    }
+
+       if(clk == gpu_pll_clk)
+       {
+               /* delay for gpu pll stability */
+               udelay(100);
+       }
+       
+       clk = NULL;
+}
+
+void SetFrequency(IMG_UINT32 ui32Frequency)
+{
+       SetClkVal("pll", (int) ui32Frequency);
+}
+
+static void ParseFexPara(void)
+{
+    script_item_u regulator_id_fex, min_vf_level, max_vf_level;
+       if(SCIRPT_ITEM_VALUE_TYPE_STR == script_get_item("rgx_para", "regulator_id", &regulator_id_fex))
+    {              
+        regulator_id = regulator_id_fex.str;
+    }
+       
+    if(SCIRPT_ITEM_VALUE_TYPE_INT == script_get_item("rgx_para", "min_vf_level", &min_vf_level))
+    {              
+        if((min_vf_level.val >= 0 && min_vf_level.val < LEVEL_COUNT))
+               {
+                       min_vf_level_val = min_vf_level.val;
+               }
+    }
+       else
+       {
+               goto err_out2;
+       }
+       
+    if(SCIRPT_ITEM_VALUE_TYPE_INT == script_get_item("rgx_para", "max_vf_level", &max_vf_level))
+    {              
+               if(max_vf_level.val >= min_vf_level_val && max_vf_level.val < LEVEL_COUNT)
+               {
+                       max_vf_level_val = max_vf_level.val;
+               }
+    }
+       else
+       {       
+               goto err_out1;
+       }
+       
+       return;
+
+err_out1:
+       min_vf_level_val = DEFAULT_MIN_VL_LEVEL;
+err_out2:
+       regulator_id = "axp22_dcdc2";
+       return;
+}
+
+PVRSRV_ERROR AwPrePowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced)
+{
+       return AwSysPrePowerState(eNewPowerState);
+}
+
+PVRSRV_ERROR AwPostPowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced)
+{
+       return AwSysPostPowerState(eNewPowerState);
+}
+
+PVRSRV_ERROR AwSysPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+       if(eNewPowerState == PVRSRV_SYS_POWER_STATE_ON)
+       {
+               RgxEnablePower();
+       
+               mdelay(2);
+       
+               /* set external isolation invalid */
+               writel(0, SUNXI_R_PRCM_VBASE + GPU_PWROFF_GATING);
+       
+               DeAssertGpuResetSignal();
+               
+               RgxEnableClock();
+               
+               /* set delay for internal power stability */
+               writel(0x100, SUNXI_GPU_CTRL_VBASE + 0x18);
+       }
+       
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR AwSysPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+       if(eNewPowerState == PVRSRV_SYS_POWER_STATE_OFF)
+       {
+               RgxDisableClock();
+               
+               AssertGpuResetSignal();
+       
+               /* set external isolation valid */
+               writel(1, SUNXI_R_PRCM_VBASE + GPU_PWROFF_GATING);
+       
+               RgxDisablePower();
+       }
+       
+       return PVRSRV_OK;
+}
+
+#ifdef CONFIG_CPU_BUDGET_THERMAL
+static void RgxDvfsChange(int vf_level, int up_flag)
+{
+#if defined (PVR_DVFS)
+       IMG_DVFS_DEVICE_CFG     *psDVFSDeviceCfg = &gpsDevConfig->sDVFS.sDVFSDeviceCfg;
+       psDVFSDeviceCfg->ui32FreqMax = asOPPTable[vf_level].ui32Freq;
+#else
+       PVRSRV_ERROR err;
+       err = PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL);
+       if(err == PVRSRV_OK)
+       {
+               if(up_flag == 1)
+               {
+                       SetVoltage(asOPPTable[vf_level].ui32Volt);
+                       SetClkVal("pll", asOPPTable[vf_level].ui32Freq);
+               }
+               else
+               {
+                       SetClkVal("pll", asOPPTable[vf_level].ui32Freq);
+                       SetVoltage(asOPPTable[vf_level].ui32Volt);
+               }
+               PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL);
+       }
+#endif
+}
+
+static int rgx_throttle_notifier_call(struct notifier_block *nfb, unsigned long mode, void *cmd)
+{
+    int retval = NOTIFY_DONE;
+       if(mode == BUDGET_GPU_THROTTLE && Is_powernow)
+    {
+                       RgxDvfsChange(min_vf_level_val, 0);
+        Is_powernow = 0;
+    }
+    else
+       {
+        if(cmd && (*(int *)cmd) == 1 && !Is_powernow)
+               {
+                       RgxDvfsChange(max_vf_level_val, 0);
+            Is_powernow = 1;
+        }
+               else if(cmd && (*(int *)cmd) == 0 && Is_powernow)
+               {
+                       RgxDvfsChange(min_vf_level_val, 0);
+            Is_powernow = 0;
+        }
+    }
+       
+       return retval;
+}
+
+static struct notifier_block rgx_throttle_notifier = {
+.notifier_call = rgx_throttle_notifier_call,
+};
+#endif /* CONFIG_CPU_BUDGET_THERMAL */
+
+IMG_VOID RgxSunxiDeInit(IMG_VOID)
+{
+#ifdef CONFIG_CPU_BUDGET_THERMAL
+       unregister_budget_cooling_notifier(&rgx_throttle_notifier);
+#endif /* CONFIG_CPU_BUDGET_THERMAL */
+       regulator_put(rgx_regulator);
+       rgx_regulator = NULL;
+}
+
+void RgxSunxiInit(PVRSRV_DEVICE_CONFIG* psDevConfig)
+{      
+       IMG_UINT32 vf_level_val;
+
+       ParseFexPara();
+
+       rgx_regulator = regulator_get(NULL, regulator_id);
+       if (IS_ERR(rgx_regulator)) 
+       {
+               PVR_DPF((PVR_DBG_ERROR, "Failed to get rgx regulator!"));
+        rgx_regulator = NULL;
+               return;
+       }
+       
+       gpu_core_clk = clk_get(NULL, GPUCORE_CLK);
+       gpu_mem_clk  = clk_get(NULL, GPUMEM_CLK);
+       gpu_axi_clk  = clk_get(NULL, GPUAXI_CLK);
+       gpu_pll_clk  = clk_get(NULL, PLL9_CLK);
+       gpu_ctrl_clk = clk_get(NULL, GPU_CTRL);
+
+       gpsDevConfig = psDevConfig;
+
+#if defined(PVR_DVFS)
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.pasOPPTable = asOPPTable;
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.ui32OPPTableSize = LEVEL_COUNT;
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.ui32FreqMin = asOPPTable[min_vf_level_val].ui32Freq;
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.ui32FreqMax = asOPPTable[max_vf_level_val].ui32Freq;
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.pfnSetFrequency = SetFrequency;
+       gpsDevConfig->sDVFS.sDVFSDeviceCfg.pfnSetVoltage = SetVoltage;
+#endif
+
+       vf_level_val = min_vf_level_val;
+
+       SetVoltage(asOPPTable[vf_level_val].ui32Volt);
+               
+       SetClkVal("pll", asOPPTable[vf_level_val].ui32Freq);
+       SetClkVal("core", asOPPTable[vf_level_val].ui32Freq);
+       SetClkVal("mem", asOPPTable[vf_level_val].ui32Freq);
+       SetClkVal("axi", AXI_CLK_FREQ);
+
+       (void) AwSysPrePowerState(PVRSRV_SYS_POWER_STATE_ON);
+
+#ifdef CONFIG_CPU_BUDGET_THERMAL
+       register_budget_cooling_notifier(&rgx_throttle_notifier);
+#endif /* CONFIG_CPU_BUDGET_THERMAL */
+}
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.h b/drivers/gpu/rogue_m/services/system/rgx_sunxi/sunxi_init.h
new file mode 100644 (file)
index 0000000..4b05ae9
--- /dev/null
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@Description    System Configuration functions
+*/ /**************************************************************************/
+
+#if !defined(__SUNXI_INIT__)
+#define __SUNXI_INIT__
+long int GetConfigFreq(IMG_VOID);
+IMG_UINT32 AwClockFreqGet(IMG_HANDLE hSysData);
+IMG_VOID RgxSunxiDeInit(IMG_VOID);
+IMG_VOID RgxResume(IMG_VOID);
+IMG_VOID RgxSuspend(IMG_VOID);
+void RgxSunxiInit(PVRSRV_DEVICE_CONFIG* psDevConfig);
+PVRSRV_ERROR AwPrePowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced);
+PVRSRV_ERROR AwPostPowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced);
+PVRSRV_ERROR AwSysPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR AwSysPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+void SetFrequency(IMG_UINT32 ui32Frequency);
+void SetVoltage(IMG_UINT32 ui32Voltage);
+#endif /* __SUNXI_INIT__ */
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.c b/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.c
new file mode 100644 (file)
index 0000000..f854682
--- /dev/null
@@ -0,0 +1,260 @@
+/*************************************************************************/ /*!
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@Description    System Configuration functions
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "syscommon.h"
+#include "sysconfig.h"
+#include "physheap.h"
+#if defined(SUPPORT_ION)
+#include "ion_support.h"
+#endif
+
+#include <mach/platform.h>
+#include <mach/irqs.h>
+#include "sunxi_init.h"
+
+static RGX_TIMING_INFORMATION  gsRGXTimingInfo;
+static RGX_DATA                 gsRGXData;
+static PVRSRV_DEVICE_CONFIG    gsDevices[1];
+static PVRSRV_SYSTEM_CONFIG    gsSysConfig;
+
+static PHYS_HEAP_FUNCTIONS      gsPhysHeapFuncs;
+static PHYS_HEAP_CONFIG         gsPhysHeapConfig[1];
+
+
+/*
+       CPU to Device physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+
+       /* Optimise common case */
+       psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       Device to CPU physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr)                           
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+
+       /* Optimise common case */
+       psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       SysCreateConfigData
+*/
+PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *hDevice)
+{
+       PVR_UNREFERENCED_PARAMETER(hDevice);
+
+       /* Sunxi Init */
+       RgxSunxiInit(&gsDevices[0]);
+       
+       /*
+        * Setup information about physical memory heap(s) we have
+        */
+       gsPhysHeapFuncs.pfnCpuPAddrToDevPAddr = UMAPhysHeapCpuPAddrToDevPAddr;
+       gsPhysHeapFuncs.pfnDevPAddrToCpuPAddr = UMAPhysHeapDevPAddrToCpuPAddr;
+
+       gsPhysHeapConfig[0].ui32PhysHeapID = 0;
+       gsPhysHeapConfig[0].pszPDumpMemspaceName = "SYSMEM";
+       gsPhysHeapConfig[0].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[0].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[0].hPrivData = IMG_NULL;
+
+       gsSysConfig.pasPhysHeaps = &(gsPhysHeapConfig[0]);
+       gsSysConfig.ui32PhysHeapCount = IMG_ARR_NUM_ELEMS(gsPhysHeapConfig);
+
+       gsSysConfig.pui32BIFTilingHeapConfigs = gauiBIFTilingHeapXStrides;
+       gsSysConfig.ui32BIFTilingHeapCount = IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides);
+
+       /*
+        * Setup RGX specific timing data
+        */
+       gsRGXTimingInfo.ui32CoreClockSpeed        = GetConfigFreq();
+       gsRGXTimingInfo.bEnableActivePM           = IMG_TRUE;
+       gsRGXTimingInfo.bEnableRDPowIsland        = IMG_TRUE;
+       gsRGXTimingInfo.ui32ActivePMLatencyms     = SYS_RGX_ACTIVE_POWER_LATENCY_MS;
+
+       /*
+        *Setup RGX specific data
+        */
+       gsRGXData.psRGXTimingInfo = &gsRGXTimingInfo;
+
+       /*
+        * Setup RGX device
+        */
+       gsDevices[0].eDeviceType            = PVRSRV_DEVICE_TYPE_RGX;
+       gsDevices[0].pszName                = "RGX";
+
+       /* Device setup information */
+       gsDevices[0].sRegsCpuPBase.uiAddr   = SUNXI_GPU_PBASE;
+       gsDevices[0].ui32RegsSize           = SUNXI_GPU_SIZE;
+       gsDevices[0].ui32IRQ                = SUNXI_IRQ_GPU;
+       gsDevices[0].bIRQIsShared           = IMG_FALSE;
+
+       /* Device's physical heap IDs */
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = 0;
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = 0;
+
+       /* Power management on SUNXI system */
+       gsDevices[0].pfnPrePowerState       = AwPrePowerState;
+       gsDevices[0].pfnPostPowerState      = AwPostPowerState;
+
+       /* No clock frequency either */
+       gsDevices[0].pfnClockFreqGet        = IMG_NULL;
+
+       /* No interrupt handled either */
+       gsDevices[0].pfnInterruptHandled    = IMG_NULL;
+
+       gsDevices[0].pfnCheckMemAllocSize   = SysCheckMemAllocSize;
+
+       gsDevices[0].hDevData               = &gsRGXData;
+
+#if defined(PVR_DVFS)
+       gsDevices[0].sDVFS.sDVFSDeviceCfg.ui32PollMs = 100;
+       gsDevices[0].sDVFS.sDVFSDeviceCfg.bIdleReq = IMG_FALSE;
+
+       gsDevices[0].sDVFS.sDVFSGovernorCfg.ui32UpThreshold = 90;
+       gsDevices[0].sDVFS.sDVFSGovernorCfg.ui32DownDifferential = 10;
+
+#if defined(PVR_POWER_ACTOR)
+       gsDevices[0].sDVFS.sDVFSPACfg.i32Ta = 113;
+       gsDevices[0].sDVFS.sDVFSPACfg.i32Tb = -11375;
+       gsDevices[0].sDVFS.sDVFSPACfg.i32Tc = 800472;
+       gsDevices[0].sDVFS.sDVFSPACfg.i32Td = -7651043;
+       gsDevices[0].sDVFS.sDVFSPACfg.ui32Other = 0;
+       gsDevices[0].sDVFS.sDVFSPACfg.ui32Weight = 0;
+#endif
+#endif
+
+       /*
+        * Setup system config
+        */
+       gsSysConfig.pszSystemName = RGX_SUNXI_SYSTEM_NAME;
+       gsSysConfig.uiDeviceCount = sizeof(gsDevices)/sizeof(gsDevices[0]);
+       gsSysConfig.pasDevices = &gsDevices[0];
+
+       /* No power management on no HW system */
+       gsSysConfig.pfnSysPrePowerState = IMG_NULL;
+       gsSysConfig.pfnSysPostPowerState = IMG_NULL;
+
+       /* no cache snooping */
+       gsSysConfig.eCacheSnoopingMode = PVRSRV_SYSTEM_SNOOP_NONE;
+
+       /* Setup other system specific stuff */
+#if defined(SUPPORT_ION)
+       IonInit(NULL);
+#endif
+
+       *ppsSysConfig = &gsSysConfig;
+
+       return PVRSRV_OK;
+}
+
+/*
+       SysDestroyConfigData
+*/
+void SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+
+       /* Sunxi DeInit */
+       RgxSunxiDeInit();
+
+#if defined(SUPPORT_ION)
+       IonDeinit();
+#endif
+}
+
+PVRSRV_ERROR SysAcquireSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysReleaseSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+       PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf);
+       return PVRSRV_OK;
+}
+
+/******************************************************************************
+ End of file (sysconfig.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.h b/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysconfig.h
new file mode 100644 (file)
index 0000000..76211d2
--- /dev/null
@@ -0,0 +1,66 @@
+/*************************************************************************/ /*!
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@Description    This header provides system-specific declarations and macros
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "rgxdevice.h"
+
+#if !defined(__SYSCCONFIG_H__)
+#define __SYSCCONFIG_H__
+
+
+#define RGX_SUNXI_SYSTEM_NAME "RGX SUNXI"
+#define SYS_RGX_ACTIVE_POWER_LATENCY_MS (100)
+
+/* default BIF tiling heap x-stride configurations. */
+static IMG_UINT32 gauiBIFTilingHeapXStrides[RGXFWIF_NUM_BIF_TILING_CONFIGS] =
+{
+       0, /* BIF tiling heap 1 x-stride */
+       1, /* BIF tiling heap 2 x-stride */
+       2, /* BIF tiling heap 3 x-stride */
+       3  /* BIF tiling heap 4 x-stride */
+};
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+#endif /* __SYSCCONFIG_H__ */
diff --git a/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysinfo.h b/drivers/gpu/rogue_m/services/system/rgx_sunxi/sysinfo.h
new file mode 100644 (file)
index 0000000..3654bb5
--- /dev/null
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@Description    This header provides system-specific declarations and macros
+*/ /**************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#define MAX_HW_TIME_US                                                         (500000)
+#define FATAL_ERROR_DETECTION_POLL_MS                          (10000)
+#define WAIT_TRY_COUNT                                                         (10000)
+#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT                (10000)
+#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT       (3600000)
+
+#define SYS_DEVICE_COUNT 3 /* RGX, DISPLAY (external), BUFFER (external) */
+
+#define SYS_PHYS_HEAP_COUNT 1
+
+#if defined(__linux__)
+#define SYS_RGX_DEV_NAME "rgxsunxi"
+#endif
+
+#endif /* !defined(__SYSINFO_H__) */
diff --git a/drivers/gpu/rogue_m/system/common/ion_support_generic.c b/drivers/gpu/rogue_m/system/common/ion_support_generic.c
new file mode 100644 (file)
index 0000000..277c3b5
--- /dev/null
@@ -0,0 +1,161 @@
+/*************************************************************************/ /*!
+@File           ion_support.c
+@Title          Generic Ion support
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This file does the Ion initialisation and De-initialistion for
+                systems that don't already have Ion.
+                For systems that do have Ion it's expected they they init Ion
+                as per their requirements and then implement IonDevAcquire and
+                IonDevRelease which provides access to the ion device.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "ion_support.h"
+#include "ion_sys.h"
+
+#include <linux/version.h>
+#include PVR_ANDROID_ION_HEADER
+#include PVR_ANDROID_ION_PRIV_HEADER
+#include <linux/err.h>
+#include <linux/slab.h>
+
+/* Just the system heaps are used by the generic implementation */
+static struct ion_platform_data generic_config = {
+       .nr = 2,
+       .heaps =
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,39))
+#else
+               (struct ion_platform_heap [])
+#endif
+               {
+                       {
+                               .type = ION_HEAP_TYPE_SYSTEM_CONTIG,
+                               .name = "system_contig",
+                               .id = ION_HEAP_TYPE_SYSTEM_CONTIG,
+                       },
+                       {
+                               .type = ION_HEAP_TYPE_SYSTEM,
+                               .name = "system",
+                               .id = ION_HEAP_TYPE_SYSTEM,
+                       }
+               }
+};
+
+struct ion_heap **g_apsIonHeaps;
+struct ion_device *g_psIonDev;
+
+PVRSRV_ERROR IonInit(void *phPrivateData)
+{
+       int uiHeapCount = generic_config.nr;
+       int uiError;
+       int i;
+
+       PVR_UNREFERENCED_PARAMETER(phPrivateData);
+
+       g_apsIonHeaps = kzalloc(sizeof(struct ion_heap *) * uiHeapCount, GFP_KERNEL);
+
+       /* Create the ion devicenode */
+       g_psIonDev = ion_device_create(NULL);
+       if (IS_ERR_OR_NULL(g_psIonDev)) {
+               kfree(g_apsIonHeaps);
+               return PVRSRV_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* Register all the heaps */
+       for (i = 0; i < generic_config.nr; i++)
+       {
+               struct ion_platform_heap *psPlatHeapData = &generic_config.heaps[i];
+
+               g_apsIonHeaps[i] = ion_heap_create(psPlatHeapData);
+               if (IS_ERR_OR_NULL(g_apsIonHeaps[i]))
+               {
+                       uiError = PTR_ERR(g_apsIonHeaps[i]);
+                       goto failHeapCreate;
+               }
+               ion_device_add_heap(g_psIonDev, g_apsIonHeaps[i]);
+       }
+
+       return PVRSRV_OK;
+
+failHeapCreate:
+       for (i = 0; i < uiHeapCount; i++) {
+               if (g_apsIonHeaps[i])
+               {
+                               ion_heap_destroy(g_apsIonHeaps[i]);
+               }
+       }
+       kfree(g_apsIonHeaps);
+       ion_device_destroy(g_psIonDev);
+
+       return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+struct ion_device *IonDevAcquire(IMG_VOID)
+{
+       return g_psIonDev;
+}
+
+IMG_VOID IonDevRelease(struct ion_device *psIonDev)
+{
+       /* Nothing to do, sanity check the pointer we're passed back */
+       PVR_ASSERT(psIonDev == g_psIonDev);
+}
+
+IMG_UINT32 IonPhysHeapID(IMG_VOID)
+{
+       return 0;
+}
+
+IMG_VOID IonDeinit(IMG_VOID)
+{
+       int uiHeapCount = generic_config.nr;
+       int i;
+
+       for (i = 0; i < uiHeapCount; i++) {
+               if (g_apsIonHeaps[i])
+               {
+                               ion_heap_destroy(g_apsIonHeaps[i]);
+               }
+       }
+       kfree(g_apsIonHeaps);
+       ion_device_destroy(g_psIonDev);
+}
+
diff --git a/drivers/gpu/rogue_m/system/common/pci_support.c b/drivers/gpu/rogue_m/system/common/pci_support.c
new file mode 100644 (file)
index 0000000..5c03669
--- /dev/null
@@ -0,0 +1,658 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/pci.h>
+#include <linux/version.h>
+#include <asm/mtrr.h>
+
+#include "pci_support.h"
+#include "allocmem.h"
+
+typedef        struct _PVR_PCI_DEV_TAG
+{
+       struct pci_dev          *psPCIDev;
+       HOST_PCI_INIT_FLAGS     ePCIFlags;
+       IMG_BOOL                abPCIResourceInUse[DEVICE_COUNT_RESOURCE];
+} PVR_PCI_DEV;
+
+/*************************************************************************/ /*!
+@Function       OSPCISetDev
+@Description    Set a PCI device for subsequent use.
+@Input          pvPCICookie             Pointer to OS specific PCI structure
+@Input          eFlags                  Flags
+@Return                PVRSRV_PCI_DEV_HANDLE   Pointer to PCI device handle
+*/ /**************************************************************************/
+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
+{
+       int err;
+       IMG_UINT32 i;
+       PVR_PCI_DEV *psPVRPCI;
+
+       psPVRPCI = OSAllocMem(sizeof(*psPVRPCI));
+       if (psPVRPCI == IMG_NULL)
+       {
+               printk(KERN_ERR "OSPCISetDev: Couldn't allocate PVR PCI structure\n");
+               return IMG_NULL;
+       }
+
+       psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
+       psPVRPCI->ePCIFlags = eFlags;
+
+       err = pci_enable_device(psPVRPCI->psPCIDev);
+       if (err != 0)
+       {
+               printk(KERN_ERR "OSPCISetDev: Couldn't enable device (%d)\n", err);
+               OSFreeMem(psPVRPCI);
+               return IMG_NULL;
+       }
+
+       if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)        /* PRQA S 3358 */ /* misuse of enums */
+       {
+               pci_set_master(psPVRPCI->psPCIDev);
+       }
+
+       if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)               /* PRQA S 3358 */ /* misuse of enums */
+       {
+#if defined(CONFIG_PCI_MSI)
+               err = pci_enable_msi(psPVRPCI->psPCIDev);
+               if (err != 0)
+               {
+                       printk(KERN_ERR "OSPCISetDev: Couldn't enable MSI (%d)", err);
+                       psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI; /* PRQA S 1474,3358,4130 */ /* misuse of enums */
+               }
+#else
+               printk(KERN_ERR "OSPCISetDev: MSI support not enabled in the kernel");
+#endif
+}
+
+       /* Initialise the PCI resource tracking array */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+       {
+               psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+       }
+
+       return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIAcquireDev
+@Description    Acquire a PCI device for subsequent use.
+@Input          ui16VendorID            Vendor PCI ID
+@Input          ui16DeviceID            Device PCI ID
+@Input          eFlags                  Flags
+@Return                PVRSRV_PCI_DEV_HANDLE   Pointer to PCI device handle
+*/ /**************************************************************************/
+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)
+       {
+               return IMG_NULL;
+       }
+
+       return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIDevID
+@Description    Get the PCI device ID.
+@Input          hPVRPCI                 PCI device handle
+@Output         pui16DeviceID           Pointer to where the device ID should 
+                                        be returned
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIDevID(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT16 *pui16DeviceID)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+       if (pui16DeviceID == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *pui16DeviceID = psPVRPCI->psPCIDev->device;
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIIRQ
+@Description    Get the interrupt number for the device.
+@Input          hPVRPCI                 PCI device handle
+@Output         pui16DeviceID           Pointer to where the interrupt number 
+                                        should be returned
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+
+       if (pui32IRQ == IMG_NULL)
+       {
+               return PVRSRV_ERROR_INVALID_PARAMS;
+       }
+
+       *pui32IRQ = psPVRPCI->psPCIDev->irq;
+
+       return PVRSRV_OK;
+}
+
+/* Functions supported by OSPCIAddrRangeFunc */
+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
+};
+
+/*************************************************************************/ /*!
+@Function       OSPCIAddrRangeFunc
+@Description    Internal support function for various address range related 
+                functions
+@Input          eFunc                   Function to perform
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                IMG_UINT32              Function dependent value
+*/ /**************************************************************************/
+static IMG_UINT64 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)
+       {
+               printk(KERN_ERR "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 = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, PVRSRV_MODNAME);
+                       if (err != 0)
+                       {
+                               printk(KERN_ERR "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:
+               {
+                       printk(KERN_ERR "OSPCIAddrRangeFunc: Unknown function");
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIAddrRangeLen
+@Description    Returns length of a given address range
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                IMG_UINT32              Length of address range or 0 if no 
+                                        such range
+*/ /**************************************************************************/
+IMG_UINT64 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+       return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index);
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIAddrRangeStart
+@Description    Returns the start of a given address range
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                IMG_UINT32              Start of address range or 0 if no 
+                                        such range
+*/ /**************************************************************************/
+IMG_UINT64 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+       return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); 
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIAddrRangeEnd
+@Description    Returns the end of a given address range
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                IMG_UINT32              End of address range or 0 if no such
+                                        range
+*/ /**************************************************************************/
+IMG_UINT64 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+       return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); 
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIRequestAddrRange
+@Description    Request a given address range index for subsequent use
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+                                                                  IMG_UINT32 ui32Index)
+{
+       if (OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0)
+       {
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+       else
+       {
+               return PVRSRV_OK;
+       }
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIReleaseAddrRange
+@Description    Release a given address range that is no longer being used
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+       if (OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0)
+       {
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+       else
+       {
+               return PVRSRV_OK;
+       }
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIRequestAddrRegion
+@Description    Request a given region from an address range for subsequent use
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Input          uiOffset              Offset into the address range that forms 
+                                        the start of the region
+@Input          uiLength              Length of the region
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIRequestAddrRegion(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+                                                                       IMG_UINT32 ui32Index,
+                                                                       IMG_UINT64 uiOffset,
+                                                                       IMG_UINT64 uiLength)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       resource_size_t start;
+       resource_size_t end;
+
+       start = pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
+       end = pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
+
+       /* Check that the requested region is valid */
+       if ((start + uiOffset + uiLength - 1) > end)
+       {
+               return PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH;
+       }
+
+       if (pci_resource_flags(psPVRPCI->psPCIDev, ui32Index) & IORESOURCE_IO)
+       {
+               if (request_region(start + uiOffset, uiLength, PVRSRV_MODNAME) == NULL)
+               {
+                       return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+               }
+       }
+       else
+       {
+               if (request_mem_region(start + uiOffset, uiLength, PVRSRV_MODNAME) == NULL)
+               {
+                       return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIReleaseAddrRegion
+@Description    Release a given region, from an address range, that is no 
+                longer in use
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Input          ui32Offset              Offset into the address range that forms 
+                                        the start of the region
+@Input          ui32Length              Length of the region
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIReleaseAddrRegion(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+                                                                       IMG_UINT32 ui32Index,
+                                                                       IMG_UINT64 uiOffset,
+                                                                       IMG_UINT64 uiLength)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       resource_size_t start;
+       resource_size_t end;
+
+       start = pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
+       end = pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
+
+       /* Check that the region is valid */
+       if ((start + uiOffset + uiLength - 1) > end)
+       {
+               return PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH;
+       }
+
+       if (pci_resource_flags(psPVRPCI->psPCIDev, ui32Index) & IORESOURCE_IO)
+       {
+               release_region(start + uiOffset, uiLength);
+       }
+       else
+       {
+               release_mem_region(start + uiOffset, uiLength);
+       }
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIReleaseDev
+@Description    Release a PCI device that is no longer being used
+@Input          hPVRPCI                 PCI device handle
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       int i;
+
+       /* Release all PCI regions that are currently in use */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+       {
+               if (psPVRPCI->abPCIResourceInUse[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)               /* PRQA S 3358 */ /* misuse of enums */
+       {
+               pci_disable_msi(psPVRPCI->psPCIDev);
+       }
+#endif
+
+       if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)        /* PRQA S 3358 */ /* misuse of enums */
+       {
+               pci_clear_master(psPVRPCI->psPCIDev);
+       }
+
+       pci_disable_device(psPVRPCI->psPCIDev);
+
+       OSFreeMem((IMG_VOID *)psPVRPCI);
+       /*not nulling pointer, copy on stack*/
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCISuspendDev
+@Description    Prepare PCI device to be turned off by power management
+@Input          hPVRPCI                 PCI device handle
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       int i;
+       int err;
+
+       /* Release all PCI regions that are currently in use */
+       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)
+       {
+               printk(KERN_ERR "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:
+                       printk(KERN_ERR "OSPCISuspendDev: device doesn't support PCI PM");
+                       break;
+               case -EINVAL:
+                       printk(KERN_ERR "OSPCISuspendDev: can't enter requested power state");
+                       break;
+               default:
+                       printk(KERN_ERR "OSPCISuspendDev: pci_set_power_state failed (%d)", err);
+                       break;
+       }
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIResumeDev
+@Description    Prepare a PCI device to be resumed by power management
+@Input          hPVRPCI                 PCI device handle
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       int err;
+       int i;
+
+       err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
+       switch(err)
+       {
+               case 0:
+                       break;
+               case -EIO:
+                       printk(KERN_ERR "OSPCIResumeDev: device doesn't support PCI PM");
+                       break;
+               case -EINVAL:
+                       printk(KERN_ERR "OSPCIResumeDev: can't enter requested power state");
+                       return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+               default:
+                       printk(KERN_ERR "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)
+       {
+               printk(KERN_ERR "OSPCIResumeDev: pci_restore_state failed (%d)", err);
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+#endif
+       err = pci_enable_device(psPVRPCI->psPCIDev);
+       if (err != 0)
+       {
+               printk(KERN_ERR "OSPCIResumeDev: Couldn't enable device (%d)", err);
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+
+       if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)        /* PRQA S 3358 */ /* misuse of enums */
+               pci_set_master(psPVRPCI->psPCIDev);
+
+       /* Restore the PCI resource tracking array */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+       {
+               if (psPVRPCI->abPCIResourceInUse[i])
+               {
+                       err = pci_request_region(psPVRPCI->psPCIDev, i, PVRSRV_MODNAME);
+                       if (err != 0)
+                       {
+                               printk(KERN_ERR "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err);
+                       }
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       OSPCIClearResourceMTRRs
+@Description    Clear any BIOS-configured MTRRs for a PCI memory region
+@Input          hPVRPCI                 PCI device handle
+@Input          ui32Index               Address range index
+@Return                PVRSRV_ERROR            Services error code
+*/ /**************************************************************************/
+PVRSRV_ERROR OSPCIClearResourceMTRRs(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+       resource_size_t start, end;
+       int err;
+
+       start = pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
+       end = pci_resource_end(psPVRPCI->psPCIDev, ui32Index) + 1;
+
+       err = mtrr_add(start, end - start, MTRR_TYPE_UNCACHABLE, 0);
+       if (err < 0)
+       {
+               printk(KERN_ERR "OSPCIClearResourceMTRRs: mtrr_add failed (%d)", err);
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+
+       err = mtrr_del(err, start, end - start);
+       if (err < 0)
+       {
+               printk(KERN_ERR "OSPCIClearResourceMTRRs: mtrr_del failed (%d)", err);
+               return PVRSRV_ERROR_PCI_CALL_FAILED;
+       }
+
+       /* Workaround for overlapping MTRRs. */
+       {
+               IMG_BOOL bGotMTRR0 = IMG_FALSE;
+
+               /* Current mobo BIOSes will normally set up a WRBACK MTRR spanning
+                * 0->4GB, and then another 4GB->6GB. If the PCI card's automatic &
+                * overlapping UNCACHABLE MTRR is deleted, we see WRBACK behaviour.
+                *
+                * WRBACK is incompatible with some PCI devices, so try to split
+                * the UNCACHABLE regions up and insert a WRCOMB region instead.
+                */
+               err = mtrr_add(start, end - start, MTRR_TYPE_WRBACK, 0);
+               if (err < 0)
+               {
+                       /* If this fails, services has probably run before and created
+                        * a write-combined MTRR for the test chip. Assume it has, and
+                        * don't return an error here.
+                        */
+                       return PVRSRV_OK;
+               }
+
+               if(err == 0)
+                       bGotMTRR0 = IMG_TRUE;
+
+               err = mtrr_del(err, start, end - start);
+               if(err < 0)
+               {
+                       printk(KERN_ERR "OSPCIClearResourceMTRRs: mtrr_del failed (%d)", err);
+                       return PVRSRV_ERROR_PCI_CALL_FAILED;
+               }
+
+               if(bGotMTRR0)
+               {
+                       /* Replace 0 with a non-overlapping WRBACK MTRR */
+                       err = mtrr_add(0, start, MTRR_TYPE_WRBACK, 0);
+                       if(err < 0)
+                       {
+                               printk(KERN_ERR "OSPCIClearResourceMTRRs: mtrr_add failed (%d)", err);
+                               return PVRSRV_ERROR_PCI_CALL_FAILED;
+                       }
+
+                       /* Add a WRCOMB MTRR for the PCI device memory bar */
+                       err = mtrr_add(start, end - start, MTRR_TYPE_WRCOMB, 0);
+                       if(err < 0)
+                       {
+                               printk(KERN_ERR "OSPCIClearResourceMTRRs: mtrr_add failed (%d)", err);
+                               return PVRSRV_ERROR_PCI_CALL_FAILED;
+                       }
+               }
+       }
+
+       return PVRSRV_OK;
+}
diff --git a/drivers/gpu/rogue_m/system/include/ion_support.h b/drivers/gpu/rogue_m/system/include/ion_support.h
new file mode 100644 (file)
index 0000000..341038d
--- /dev/null
@@ -0,0 +1,46 @@
+/*************************************************************************/ /*!
+@File           ion_support.h
+@Title          Generic Ion support header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This file defines the API for generic Ion support.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+PVRSRV_ERROR IonInit(void *pvPrivateData);
+
+IMG_VOID IonDeinit(IMG_VOID);
diff --git a/drivers/gpu/rogue_m/system/include/pci_support.h b/drivers/gpu/rogue_m/system/include/pci_support.h
new file mode 100644 (file)
index 0000000..57da29b
--- /dev/null
@@ -0,0 +1,74 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PCI_SUPPORT_H__
+#define __PCI_SUPPORT_H__
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+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 OSPCIDevID(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT16 *pui16DeviceID);
+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ);
+IMG_UINT64 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT64 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+IMG_UINT64 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 OSPCIRequestAddrRegion(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index, IMG_UINT64 uiOffset, IMG_UINT64 uiLength);
+PVRSRV_ERROR OSPCIReleaseAddrRegion(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index, IMG_UINT64 uiOffset, IMG_UINT64 uiLength);
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
+PVRSRV_ERROR OSPCIClearResourceMTRRs(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
+
+#endif /* __PCI_SUPPORT_H__ */
diff --git a/drivers/gpu/rogue_m/system/include/syscommon.h b/drivers/gpu/rogue_m/system/include/syscommon.h
new file mode 100644 (file)
index 0000000..cfc4b82
--- /dev/null
@@ -0,0 +1,173 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common System APIs and structures
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides common system-specific declarations and macros
+                that are supported by all systems
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SYSCOMMON_H
+#define _SYSCOMMON_H
+
+#include "osfunc.h"
+
+#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
+#include <asm/io.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+#include "pvrsrv.h"
+
+PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *hDevice);
+IMG_VOID SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig);
+PVRSRV_ERROR SysAcquireSystemData(IMG_HANDLE hSysData);
+PVRSRV_ERROR SysReleaseSystemData(IMG_HANDLE hSysData);
+PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf);
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "services.h"
+IMG_VOID SysSetOSidRegisters(IMG_UINT32 aui32OSidMin[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS], IMG_UINT32 aui32OSidMax[GPUVIRT_VALIDATION_NUM_OS][GPUVIRT_VALIDATION_NUM_REGIONS]);
+IMG_VOID SysPrintAndResetFaultStatusRegister(void);
+#endif
+
+#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
+PVRSRV_ERROR SysInstallDeviceLISR(IMG_UINT32 ui32IRQ,
+                                 IMG_CHAR *pszName,
+                                 PFN_LISR pfnLISR,
+                                 IMG_PVOID pvData,
+                                 IMG_HANDLE *phLISRData);
+
+PVRSRV_ERROR SysUninstallDeviceLISR(IMG_HANDLE hLISRData);
+
+#if defined(SUPPORT_DRM)
+IMG_BOOL SystemISRHandler(IMG_VOID *pvData);
+#endif
+#endif /* defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING) */
+
+
+/*
+ * SysReadHWReg and SysWriteHWReg differ from OSReadHWReg and OSWriteHWReg
+ * in that they are always intended for use with real hardware, even on
+ * NO_HARDWARE systems.
+ */
+#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  /* !(defined(NO_HARDWARE) && defined(__linux__)) */
+/*!
+******************************************************************************
+
+ @Function     SysReadHWReg
+
+ @Description
+
+ register read function
+
+ @input pvLinRegBaseAddr :     lin addr of register block base
+
+ @input ui32Offset :
+
+ @Return   register value
+
+******************************************************************************/
+static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+       return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
+}
+
+/*!
+******************************************************************************
+
+ @Function     SysWriteHWReg
+
+ @Description
+
+ register write function
+
+ @input pvLinRegBaseAddr :     lin addr of register block base
+
+ @input ui32Offset :
+
+ @input ui32Value :
+
+ @Return   none
+
+******************************************************************************/
+static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+       writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
+}
+#endif /* !(defined(NO_HARDWARE) && defined(__linux__)) */
+
+/*!
+******************************************************************************
+
+ @Function             SysCheckMemAllocSize
+
+ @Description  Function to apply memory budgeting policies
+
+ @input                        psDevNode
+
+ @input                        uiChunkSize
+
+ @input                        ui32NumPhysChunks
+
+ @Return               PVRSRV_ERROR
+
+******************************************************************************/
+FORCE_INLINE PVRSRV_ERROR SysCheckMemAllocSize(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+                                                                                               IMG_UINT64 ui64MemSize)
+{
+       PVR_UNREFERENCED_PARAMETER(psDevNode);
+       PVR_UNREFERENCED_PARAMETER(ui64MemSize);
+
+       return PVRSRV_OK;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
+/*****************************************************************************
+ End of file (syscommon.h)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/system/rk3368/Kbuild.mk b/drivers/gpu/rogue_m/system/rk3368/Kbuild.mk
new file mode 100644 (file)
index 0000000..df218fc
--- /dev/null
@@ -0,0 +1,49 @@
+########################################################################### ###
+#@File
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm-y += \
+       services/system/$(PVR_SYSTEM)/rk_init.o \
+       services/system/$(PVR_SYSTEM)/sysconfig.o
+
+#zxl:to support rockchip ion
+ifeq ($(SUPPORT_ION),1)
+#pvrsrvkm-y += services/system/common/env/linux/ion_support_generic.o
+endif
diff --git a/drivers/gpu/rogue_m/system/rk3368/rk_init.c b/drivers/gpu/rogue_m/system/rk3368/rk_init.c
new file mode 100644 (file)
index 0000000..be01f79
--- /dev/null
@@ -0,0 +1,2150 @@
+#if defined(SUPPORT_ION)
+#include "ion_sys.h"
+#endif /* defined(SUPPORT_ION) */
+
+#include <linux/hardirq.h>
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+#include <linux/rk_fb.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/rockchip/dvfs.h>
+#include <linux/rockchip/common.h>
+#include <linux/workqueue.h>
+#include <linux/clkdev.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/freezer.h>
+#include <linux/sched/rt.h>
+#include "power.h"
+#include "rk_init.h"
+
+#include <asm/compiler.h>
+static IMG_HANDLE ghGpuUtilDvfs = NULL;
+
+#if RK_TF_VERSION
+#define PSCI_RKSIP_TF_VERSION (0x82000001)
+
+
+static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
+      u64 arg2)
+{
+ asm volatile(
+   __asmeq("%0", "x0")
+   __asmeq("%1", "x1")
+   __asmeq("%2", "x2")
+   __asmeq("%3", "x3")
+   "smc #0\n"
+  : "+r" (function_id)
+  : "r" (arg0), "r" (arg1), "r" (arg2));
+
+
+ return function_id;
+}
+
+static int (*invoke_psci_fn)(u64, u64 , u64, u64) = __invoke_psci_fn_smc;
+
+
+static int rk_tf_get_version(void)
+{
+    int ver_num;
+    ver_num = invoke_psci_fn(PSCI_RKSIP_TF_VERSION, 0, 0, 0);
+
+    return ver_num;
+}
+
+static int rk_tf_check_version(void)
+{
+    int version=0;
+    int high_16=0;
+    int low_16=0;
+    IMG_PINT pNULL=NULL;
+
+    version = rk_tf_get_version();
+    high_16 = (version >> 16) & ~(0xFFFF << 16);
+    low_16 = (version & ~(0xFFFF << 16));
+
+    printk("raw version=0x%x,rk_tf_version=%x.%x\n",version,high_16,low_16);
+
+    if((version != 0xFFFFFFFF) && (high_16 >= 1) && (low_16 >= 3))
+    {
+        return 0;
+    }
+    else
+    {
+        printk("Error:%s-line:%d This version cann't support rk3328\n",__func__,__LINE__);
+        *pNULL=0; //crash system
+        return -1;
+    }
+}
+
+#endif
+
+extern struct platform_device *gpsPVRLDMDev;
+
+#if RK33_DVFS_SUPPORT
+#define gpu_temp_limit                  110
+#define gpu_temp_statis_time            1
+#define level0_threshold_min            0
+#define level0_threshold_max            40
+#define levelf_threshold_max            100
+#define level0_coef_max                 95
+
+static IMG_UINT32 div_dvfs = 0 ;
+
+/*dvfs status*/
+static struct workqueue_struct *rgx_dvfs_wq = IMG_NULL;
+spinlock_t rgx_dvfs_spinlock;
+//struct mutex rgx_set_clock_lock;
+struct mutex rgx_enable_clock_lock;
+static struct cpufreq_frequency_table *rgx_freq_table = NULL;
+#endif
+
+/* voltage     clock   min_threshold   max_threshold   time  */
+static rgx_dvfs_info rgx_dvfs_infotbl[] =
+{
+    {925, 100, 0, 70, 0, 100},
+    {925, 160, 50, 65, 0, 95},
+    {1025, 266, 60, 78, 0, 90},
+    {1075, 350, 65, 75, 0, 85},
+    {1125, 400, 70, 75, 0, 80},
+    {1200, 500, 90, 100, 0, 75},
+};
+rgx_dvfs_info *p_rgx_dvfs_infotbl = rgx_dvfs_infotbl;
+
+unsigned int RGX_DVFS_STEP = ARRAY_SIZE(rgx_dvfs_infotbl);
+
+static int rk33_clk_set_normal_node(struct clk* node, unsigned long rate)
+{
+    int ret = 0;
+
+    if (!node)
+    {
+        printk("rk33_clk_set_normal_node error \r\n");
+        ret = -1;
+    }
+    ret = clk_set_rate(node, rate * ONE_MHZ);
+    if (ret)
+    {
+        printk("clk_set_rate error \r\n");
+    }
+    return ret;
+}
+
+
+static int rk33_clk_set_dvfs_node(struct dvfs_node *node, unsigned long rate)
+{
+    int ret = 0;
+    if (!node)
+    {
+        printk("rk33_clk_set_dvfs_node error \r\n");
+        ret = -1;
+    }
+    ret = dvfs_clk_set_rate(node, rate * ONE_MHZ);
+    if (ret)
+    {
+        printk("dvfs_clk_set_rate error \r\n");
+    }
+    return ret;
+}
+#if RK33_DVFS_SUPPORT
+#define dividend 7
+#define fix_float(a) ((((a)*dividend)%10)?((((a)*dividend)/10)+1):(((a)*dividend)/10))
+static IMG_BOOL calculate_dvfs_max_min_threshold(IMG_UINT32 level)
+{
+    IMG_UINT32 pre_level;
+    IMG_UINT32 tmp ;
+
+    if (0 == level)
+    {
+        if ((RGX_DVFS_STEP - 1) == level)
+        {
+            rgx_dvfs_infotbl[level].min_threshold = level0_threshold_min;
+            rgx_dvfs_infotbl[level].max_threshold = levelf_threshold_max;
+        }
+        else
+        {
+            rgx_dvfs_infotbl[level].min_threshold = level0_threshold_min;
+            rgx_dvfs_infotbl[level].max_threshold = level0_threshold_max;
+        }
+#if RK33_USE_CL_COUNT_UTILS
+        rgx_dvfs_infotbl[level].coef = level0_coef_max;
+#endif
+    }
+    else
+    {
+        pre_level = level - 1;
+        if ((RGX_DVFS_STEP - 1) == level)
+        {
+            rgx_dvfs_infotbl[level].max_threshold = levelf_threshold_max;
+        }
+        else
+        {
+            rgx_dvfs_infotbl[level].max_threshold = rgx_dvfs_infotbl[pre_level].max_threshold + div_dvfs;
+        }
+        rgx_dvfs_infotbl[level].min_threshold = (rgx_dvfs_infotbl[pre_level].max_threshold * (rgx_dvfs_infotbl[pre_level].clock))
+                                                / (rgx_dvfs_infotbl[level].clock);
+
+        tmp = rgx_dvfs_infotbl[level].max_threshold - rgx_dvfs_infotbl[level].min_threshold;
+
+        rgx_dvfs_infotbl[level].min_threshold += fix_float(tmp);
+#if RK33_USE_CL_COUNT_UTILS
+        rgx_dvfs_infotbl[level].coef = (rgx_dvfs_infotbl[pre_level].clock * rgx_dvfs_infotbl[pre_level].coef + 2000)
+                                       / (rgx_dvfs_infotbl[level].clock);
+#endif
+    }
+
+#if 1
+    printk("rgx_dvfs_infotbl[%d].clock=%d,min_threshold=%d,max_threshold=%d,coef=%d\n", level,
+           rgx_dvfs_infotbl[level].clock,
+           rgx_dvfs_infotbl[level].min_threshold,
+           rgx_dvfs_infotbl[level].max_threshold,
+           rgx_dvfs_infotbl[level].coef
+          );
+#endif
+    return IMG_TRUE;
+}
+
+static void rk33_dvfs_set_clock(int freq)
+{
+    struct rk_context       *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (NULL == platform)
+        panic("oops");
+
+    if ( !platform->aclk_gpu_mem || !platform->aclk_gpu_cfg || !platform->dvfs_enabled)
+    {
+        printk("aclk_gpu_mem or aclk_gpu_cfg not init\n");
+        return;
+    }
+    //mutex_lock(&rgx_set_clock_lock);
+    rk33_clk_set_normal_node(platform->aclk_gpu_mem, freq);
+    rk33_clk_set_normal_node(platform->aclk_gpu_cfg, freq);
+
+    if(platform->gpu_clk_node)
+        rk33_clk_set_dvfs_node(platform->gpu_clk_node, freq);
+    else if(platform->clk_gpu)
+        rk33_clk_set_normal_node(platform->clk_gpu, freq);
+
+    //mutex_unlock(&rgx_set_clock_lock);
+    return;
+}
+
+#if RK33_DVFS_FREQ_LIMIT
+static int rk33_dvfs_get_freq(int level)
+{
+    if (WARN_ON((level >= RGX_DVFS_STEP) || (level < 0)))
+    {
+        printk("unkown rgx dvfs level:level = %d,set clock not done \n", level);
+        return  -1;
+    }
+    return (rgx_dvfs_infotbl[level].clock);
+}
+#endif
+
+static int rk33_dvfs_get_level(int freq)
+{
+    int i;
+    for (i = 0; i < RGX_DVFS_STEP; i++)
+    {
+        if (rgx_dvfs_infotbl[i].clock == freq)
+            return i;
+    }
+    return -1;
+}
+
+static void rk33_dvfs_set_level(int level)
+{
+    static int prev_level = -1;
+
+    if (level == prev_level)
+        return;
+
+    if (WARN_ON((level >= RGX_DVFS_STEP) || (level < 0)))
+    {
+        printk("unkown rgx dvfs level:level = %d,set clock not done \n", level);
+        return  ;
+    }
+    /*panic("invalid level");*/
+#if 0
+    if (mali_dvfs_status_current.upper_lock >= 0 && level > mali_dvfs_status_current.upper_lock)
+        level = mali_dvfs_status_current.upper_lock;
+    if (mali_dvfs_status_current.under_lock >= 0 && level < mali_dvfs_status_current.under_lock)
+        level = mali_dvfs_status_current.under_lock;
+#endif
+    rk33_dvfs_set_clock(rgx_dvfs_infotbl[level].clock);
+#if 0
+    update_time_in_state(prev_level);
+#endif
+    prev_level = level;
+}
+
+static int rk33_dvfs_get_enable_status(void)
+{
+    struct rk_context       *platform;
+    unsigned long           flags;
+    int                     enable;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    spin_lock_irqsave(&platform->timer_lock, flags);
+    enable = platform->timer_active;
+    spin_unlock_irqrestore(&platform->timer_lock, flags);
+
+    return enable;
+}
+
+#if 0
+static int rk33_dvfs_enable(bool enable, int freq)
+{
+    struct rk_context       *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    BUG_ON(platform == NULL);
+
+    mutex_lock(&rgx_enable_clock_lock);
+
+    if (enable != platform->timer_active)
+    {
+        if (enable)
+        {
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_TRUE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+            hrtimer_start(&platform->timer,
+                          HR_TIMER_DELAY_MSEC(RK33_DEFAULT_CLOCK),
+                          HRTIMER_MODE_REL);
+        }
+        else
+        {
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_FALSE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+            hrtimer_cancel(&platform->timer);
+        }
+    }
+
+    if (freq != RGX_DVFS_CURRENT_FREQ)
+    {
+        spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+        platform->time_tick = 0;
+        platform->time_busy = 0;
+        platform->time_idle = 0;
+        platform->utilisation = 0;
+        platform->freq_level = rk33_dvfs_get_level(freq);
+        spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+        rk33_dvfs_set_level(platform->freq_level);
+    }
+
+    mutex_unlock(&rgx_enable_clock_lock);
+
+    return IMG_TRUE;
+}
+#endif
+
+
+#if RK33_USE_CL_COUNT_UTILS
+static void rk33_dvfs_event_proc(struct work_struct *w)
+{
+    unsigned long flags;
+    static IMG_UINT32 temp_tmp;
+    IMG_UINT32 fps = 0;
+    IMG_UINT32 fps_limit;
+    IMG_UINT32 policy;
+    IMG_INT32 absload;
+    IMG_INT32 new_index;
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    mutex_lock(&rgx_enable_clock_lock);
+
+    if (!rk33_dvfs_get_enable_status())
+    {
+        mutex_unlock(&rgx_enable_clock_lock);
+        return;
+    }
+
+    fps = rk_get_real_fps(0);
+
+    platform->temperature_time++;
+    /*
+    temp_tmp += rockchip_tsadc_get_temp(2);
+    */
+    if (platform->temperature_time >= gpu_temp_statis_time)
+    {
+        platform->temperature_time = 0;
+        platform->temperature = temp_tmp / gpu_temp_statis_time;
+        temp_tmp = 0;
+        /*pr_info("platform->temperature = %d\n",platform->temperature);*/
+    }
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+
+    platform->abs_load[0] = platform->abs_load[1];
+    platform->abs_load[1] = platform->abs_load[2];
+    platform->abs_load[2] = platform->abs_load[3];
+    platform->abs_load[3] = (platform->utilisation * rgx_dvfs_infotbl[platform->freq_level].clock * rgx_dvfs_infotbl[platform->freq_level].coef) / 100;
+    absload = (platform->abs_load[3] * 4 + platform->abs_load[2] * 3 + platform->abs_load[1] * 2 + platform->abs_load[0]);
+
+    /*
+    policy = rockchip_pm_get_policy();
+    */
+    policy = ROCKCHIP_PM_POLICY_NORMAL;
+
+    if (ROCKCHIP_PM_POLICY_PERFORMANCE == policy)
+    {
+        platform->freq_level = RGX_DVFS_STEP - 1; /*Highest level when performance mode*/
+    }
+    else if (platform->fix_freq > 0)
+    {
+        platform->freq_level = rk33_dvfs_get_level(platform->fix_freq);
+
+        if (platform->debug_level == DBG_HIGH)
+            printk("fix clock=%d\n", platform->fix_freq);
+    }
+    else
+    {
+        fps_limit = (ROCKCHIP_PM_POLICY_NORMAL == policy) ? LIMIT_FPS : LIMIT_FPS_POWER_SAVE;
+        /*
+        printk("policy : %d , fps_limit = %d\n",policy,fps_limit);
+        */
+
+
+        /*give priority to temperature unless in performance mode */
+        if (platform->temperature > gpu_temp_limit)
+        {
+            if (platform->freq_level > 0)
+                platform->freq_level--;
+
+            if (gpu_temp_statis_time > 1)
+                platform->temperature = 0;
+        }
+        else if (absload == 0 || platform->gpu_active == IMG_FALSE)
+        {
+            platform->freq_level = 0;
+        }
+        else if ((platform->freq_level < RGX_DVFS_STEP - 1) && fps < fps_limit)
+        {
+            //freq_hint=0 or freq_hint>sRK30_DVFS.u8FreqNums,  select freq automatically, find the right index
+            for (new_index = 0; new_index < RGX_DVFS_STEP; new_index++)
+            {
+                if (absload <= (rgx_dvfs_infotbl[new_index].clock*rgx_dvfs_infotbl[new_index].coef*9))
+                {
+                    if (platform->debug_level == DBG_HIGH)
+                        printk("absload=%d,cur_coef[%d]=%d\n", absload, new_index, rgx_dvfs_infotbl[new_index].clock*rgx_dvfs_infotbl[new_index].coef*9);
+                    break;
+                }
+            }
+
+            //ensure the new_index in the reasonable range
+            if (new_index >= RGX_DVFS_STEP)
+            {
+                new_index = RGX_DVFS_STEP - 1;
+            }
+
+            //if fps>=50, should not run at the higher frequency
+            if (new_index > platform->freq_level && fps >= fps_limit)
+            {
+                new_index = platform->freq_level;
+            }
+            //if running at highest frequency & fps>53 & absload<90%, try to run at a lower frequency
+            else if (platform->freq_level == RGX_DVFS_STEP - 1 && fps > 53 && absload <= (rgx_dvfs_infotbl[new_index].clock*rgx_dvfs_infotbl[new_index].coef*9))
+            {
+                new_index = platform->freq_level - 1;
+            }
+            if (platform->debug_level == DBG_HIGH)
+                printk("absload=%d,freq_level=%d,freq=%dM\n", absload, new_index, rgx_dvfs_infotbl[new_index].clock);
+
+            platform->freq_level = new_index;
+        }
+    }
+#if RK33_SYSFS_FILE_SUPPORT && RK33_DVFS_FREQ_LIMIT
+    if ((platform->up_level >= 0) && (platform->freq_level > platform->up_level))
+    {
+        platform->freq_level = platform->up_level;
+    }
+
+    if ((platform->down_level >= 0) && (platform->freq_level < platform->down_level))
+    {
+        platform->freq_level = platform->down_level;
+    }
+#endif
+
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    rk33_dvfs_set_level(platform->freq_level);
+
+    platform->time_busy = 0;
+    platform->time_idle = 0;
+    platform->utilisation = 0;
+
+    mutex_unlock(&rgx_enable_clock_lock);
+}
+#else
+static void rk33_dvfs_event_proc(struct work_struct *w)
+{
+    unsigned long flags;
+    static int level_down_time = 0;
+    static int level_up_time = 0;
+    static IMG_UINT32 temp_tmp;
+    IMG_UINT32 fps = 0;
+    IMG_UINT32 fps_limit;
+    IMG_UINT32 policy;
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    mutex_lock(&rgx_enable_clock_lock);
+
+    if (!rk33_dvfs_get_enable_status())
+    {
+        mutex_unlock(&rgx_enable_clock_lock);
+        return;
+    }
+
+    fps = rk_get_real_fps(0);
+
+    platform->temperature_time++;
+    /*
+    temp_tmp += rockchip_tsadc_get_temp(2);
+    */
+    if (platform->temperature_time >= gpu_temp_statis_time)
+    {
+        platform->temperature_time = 0;
+        platform->temperature = temp_tmp / gpu_temp_statis_time;
+        temp_tmp = 0;
+        /*pr_info("platform->temperature = %d\n",platform->temperature);*/
+    }
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    /*
+    policy = rockchip_pm_get_policy();
+    */
+    policy = ROCKCHIP_PM_POLICY_NORMAL;
+
+    if (ROCKCHIP_PM_POLICY_PERFORMANCE == policy)
+    {
+        platform->freq_level = RGX_DVFS_STEP - 1; /*Highest level when performance mode*/
+    }
+    else if (platform->fix_freq > 0)
+    {
+        platform->freq_level = rk33_dvfs_get_level(platform->fix_freq);
+
+        if (platform->debug_level == DBG_HIGH)
+            printk("fix clock=%d\n", platform->fix_freq);
+    }
+    else
+    {
+        fps_limit = (ROCKCHIP_PM_POLICY_NORMAL == policy) ? LIMIT_FPS : LIMIT_FPS_POWER_SAVE;
+#if 0
+        printk("policy : %d , fps_limit = %d\n", policy, fps_limit);
+#endif
+
+        /*give priority to temperature unless in performance mode */
+        if (platform->temperature > gpu_temp_limit)
+        {
+            if (platform->freq_level > 0)
+                platform->freq_level--;
+
+            if (gpu_temp_statis_time > 1)
+                platform->temperature = 0;
+        }
+        else if ((platform->utilisation > rgx_dvfs_infotbl[platform->freq_level].max_threshold) && (platform->freq_level < RGX_DVFS_STEP - 1) && fps < fps_limit)
+        {
+            level_up_time++;
+            if (level_up_time == RGX_DVFS_LEVEL_INTERVAL)
+            {
+                if (platform->debug_level == DBG_HIGH)
+                    printk("up,utilisation=%d,current clock=%d,fps = %d\n", platform->utilisation, rgx_dvfs_infotbl[platform->freq_level].clock, fps);
+
+                platform->freq_level++;
+                level_up_time = 0;
+
+                if (platform->debug_level == DBG_HIGH)
+                    printk(" next clock=%d\n", rgx_dvfs_infotbl[platform->freq_level].clock);
+
+                BUG_ON(platform->freq_level >= RGX_DVFS_STEP);
+            }
+            level_down_time = 0;
+        }
+        else if ((platform->freq_level > 0) && (platform->utilisation < rgx_dvfs_infotbl[platform->freq_level].min_threshold))
+            /*else if((dvfs_status->step > 0) && (platform->time_tick == RGX_DVFS_LEVEL_INTERVAL) && (platform->utilisation < mali_dvfs_infotbl[dvfs_status->step].min_threshold)) */
+        {
+            level_down_time++;
+            if (level_down_time == RGX_DVFS_LEVEL_INTERVAL)
+            {
+                if (platform->debug_level == DBG_HIGH)
+                    printk("down,utilisation=%d,current clock=%d,fps = %d\n", platform->utilisation, rgx_dvfs_infotbl[platform->freq_level].clock, fps);
+
+                BUG_ON(platform->freq_level <= 0);
+                platform->freq_level--;
+                level_down_time = 0;
+
+                if (platform->debug_level == DBG_HIGH)
+                    printk(" next clock=%d\n", rgx_dvfs_infotbl[platform->freq_level].clock);
+            }
+            level_up_time = 0;
+        }
+        else
+        {
+            level_down_time = 0;
+            level_up_time = 0;
+
+            if (platform->debug_level == DBG_HIGH)
+                printk("keep,utilisation=%d,current clock=%d,fps = %d\n", platform->utilisation, rgx_dvfs_infotbl[platform->freq_level].clock, fps);
+        }
+    }
+#if RK33_SYSFS_FILE_SUPPORT && RK33_DVFS_FREQ_LIMIT
+    if ((platform->up_level >= 0) && (platform->freq_level > platform->up_level))
+    {
+        platform->freq_level = platform->up_level;
+    }
+
+    if ((platform->down_level >= 0) && (platform->freq_level < platform->down_level))
+    {
+        platform->freq_level = platform->down_level;
+    }
+#endif
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    rk33_dvfs_set_level(platform->freq_level);
+
+    platform->time_busy = 0;
+    platform->time_idle = 0;
+    platform->utilisation = 0;
+
+    mutex_unlock(&rgx_enable_clock_lock);
+}
+#endif
+static DECLARE_WORK(rgx_dvfs_work, rk33_dvfs_event_proc);
+
+static IMG_BOOL rk33_dvfs_event(RGXFWIF_GPU_UTIL_STATS* psUtilStats)
+{
+    struct rk_context       *platform;
+#if !RK33_USE_CUSTOMER_GET_GPU_UTIL
+    IMG_UINT32              time_busy = 0;
+    IMG_UINT32              time_idle = 0;
+#endif
+    unsigned long           flags;
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    ktime_t now = ktime_get();
+    ktime_t diff;
+    IMG_INT i;
+#endif
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+#if RK33_USE_RGX_GET_GPU_UTIL
+    PVR_ASSERT(psUtilStats != NULL);
+
+    if (platform->debug_level == DBG_HIGH)
+        printk("GPU util info:valid[%d],ActiveHigh[%llu],ActiveLow[%llu],Blocked[%llu],Idle[%llu],Sum[%llu]\n",
+               psUtilStats->bValid,
+               psUtilStats->ui64GpuStatActiveHigh, psUtilStats->ui64GpuStatActiveLow,
+               psUtilStats->ui64GpuStatBlocked, psUtilStats->ui64GpuStatIdle,psUtilStats->ui64GpuStatCumulative);
+
+    if (psUtilStats->bValid /*&& psUtilStats->bIncompleteData*/)
+    {
+        time_busy = psUtilStats->ui64GpuStatActiveHigh + psUtilStats->ui64GpuStatActiveLow ;
+        time_idle = psUtilStats->ui64GpuStatIdle + psUtilStats->ui64GpuStatBlocked;
+
+        //check valid
+        if (time_busy + time_idle == 0)
+        {
+            goto err;
+        }
+
+        spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+        platform->time_busy += time_busy;
+        platform->time_idle += time_idle;
+        platform->utilisation = (time_busy * 100) / (time_busy + time_idle);
+        spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+        queue_work_on(0, rgx_dvfs_wq, &rgx_dvfs_work);
+    }
+#elif RK33_USE_CUSTOMER_GET_GPU_UTIL
+
+    diff = ktime_sub(now, platform->time_period_start);
+
+    if (platform->gpu_active)
+    {
+        platform->time_busy += (IMG_UINT32)(ktime_to_ns(diff) >> RK_PM_TIME_SHIFT);
+        platform->time_period_start = now;
+    }
+    else
+    {
+        platform->time_idle += (IMG_UINT32)(ktime_to_ns(diff) >> RK_PM_TIME_SHIFT);
+        platform->time_period_start = now;
+    }
+
+
+    //check valid
+    if (platform->time_busy + platform->time_idle == 0)
+    {
+        goto err;
+    }
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    for(i=0;i<RK33_MAX_UTILIS-1;i++)
+    {
+        platform->stUtilis.time_busys[i]=platform->stUtilis.time_busys[i+1];
+        platform->stUtilis.time_idles[i]=platform->stUtilis.time_idles[i+1];
+        platform->stUtilis.utilis[i]=platform->stUtilis.utilis[i+1];
+    }
+    platform->stUtilis.time_busys[RK33_MAX_UTILIS-1] = platform->time_busy;
+    platform->stUtilis.time_idles[RK33_MAX_UTILIS-1] = platform->time_idle;
+    platform->stUtilis.utilis[RK33_MAX_UTILIS-1] = (platform->time_busy * 10) / (platform->time_busy + platform->time_idle);
+    platform->utilisation = platform->stUtilis.utilis[3] * 4 + platform->stUtilis.utilis[2] * 3 +\
+                            platform->stUtilis.utilis[1] * 2 + platform->stUtilis.utilis[0] * 1;
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    if (platform->debug_level == DBG_HIGH)
+        printk("GPU util info:time_busy=%d,time_idle=%d,utilisation=%d\n",platform->time_busy,platform->time_idle,platform->utilisation);
+
+    queue_work_on(0, rgx_dvfs_wq, &rgx_dvfs_work);
+#endif
+
+    return IMG_TRUE;
+
+err:
+
+    platform->time_busy = 0;
+    platform->time_idle = 0;
+    platform->utilisation = 0;
+
+    return IMG_FALSE;
+}
+
+#if USE_HRTIMER
+static enum hrtimer_restart dvfs_callback(struct hrtimer *timer)
+{
+    unsigned long           flags;
+    struct rk_context       *platform;
+    PVRSRV_RGXDEV_INFO  *psDevInfo;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    PVR_ASSERT(timer != NULL);
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+#if 0
+    if (platform->psDeviceNode == NULL)
+    {
+        //Fix dvfs_callback crash problem when psDeviceNode hasn't been set.
+        PVR_DPF((PVR_DBG_WARNING, "%s:line=%d, DeviceNode is null", __func__, __LINE__));
+        spin_lock_irqsave(&platform->timer_lock, flags);
+        if (platform->timer_active)
+            hrtimer_start(timer,
+                          HR_TIMER_DELAY_MSEC(10*RK33_DVFS_FREQ),  //delay 500ms
+                          HRTIMER_MODE_REL);
+        spin_unlock_irqrestore(&platform->timer_lock, flags);
+    }
+    else
+#endif
+    spin_lock_irqsave(&platform->timer_lock, flags);
+
+    if(platform->psDeviceNode)
+    {
+        psDevInfo = platform->psDeviceNode->pvDevice;
+
+        if(psDevInfo && psDevInfo->pfnGetGpuUtilStats && platform->gpu_active)
+        {
+            //Measuring GPU Utilisation
+            eError = ((psDevInfo->pfnGetGpuUtilStats)(platform->psDeviceNode,ghGpuUtilDvfs,&platform->sUtilStats));
+            rk33_dvfs_event(&platform->sUtilStats);
+        }
+        else
+        {
+            if(!psDevInfo || !psDevInfo->pfnGetGpuUtilStats)
+                PVR_DPF((PVR_DBG_ERROR,"%s:line=%d,devinfo is null\n",__func__,__LINE__));
+        }
+    }
+
+    if (platform->timer_active)
+        hrtimer_start(timer,
+                      HR_TIMER_DELAY_MSEC(RK33_DVFS_FREQ),
+                      HRTIMER_MODE_REL);
+    spin_unlock_irqrestore(&platform->timer_lock, flags);
+
+    return HRTIMER_NORESTART;
+}
+#elif USE_KTHREAD
+static int gpu_dvfs_task(void *data)
+{
+       static long sTimeout=msecs_to_jiffies(RK33_DVFS_FREQ);
+       long timeout = sTimeout;
+       unsigned long           flags;
+    struct rk_context *platform=data;
+    PVRSRV_RGXDEV_INFO  *psDevInfo;
+
+    PVR_ASSERT(platform != NULL);
+
+       set_freezable();
+
+       do {
+               if(platform->psDeviceNode)
+               {
+                psDevInfo = platform->psDeviceNode->pvDevice;
+                spin_lock_irqsave(&platform->timer_lock, flags);
+                if(psDevInfo && psDevInfo->pfnGetGpuUtilStats && platform->gpu_active)
+                {
+                    //Measuring GPU Utilisation
+                    platform->sUtilStats = ((psDevInfo->pfnGetGpuUtilStats)(platform->psDeviceNode));
+                    rk33_dvfs_event(&platform->sUtilStats);
+                }
+                else
+                {
+                    if(!psDevInfo || !psDevInfo->pfnGetGpuUtilStats)
+                        PVR_DPF((PVR_DBG_ERROR,"%s:line=%d,devinfo is null\n",__func__,__LINE__));
+                }
+                spin_unlock_irqrestore(&platform->timer_lock, flags);
+            }
+               wait_event_freezable_timeout(platform->dvfs_wait, kthread_should_stop(), timeout);
+       } while (!kthread_should_stop());
+
+       return 0;
+}
+#endif
+
+static IMG_VOID rk33_dvfs_utils_init(struct rk_context *platform)
+{
+#if USE_KTHREAD
+    int iRet=-1;
+    struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+#endif
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    IMG_INT i;
+#endif
+    PVR_ASSERT(platform != NULL);
+
+// spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+
+    platform->utilisation = 0;
+    platform->freq_level = 0;
+    platform->freq = 0;
+    platform->time_tick = 0;
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    platform->time_period_start = ktime_get();
+    for(i=0;i<RK33_MAX_UTILIS;i++)
+    {
+        platform->stUtilis.time_busys[i]=0;
+        platform->stUtilis.time_idles[i]=0;
+        platform->stUtilis.utilis[i]=0;
+    }
+#endif
+    platform->gpu_active = IMG_FALSE;
+    platform->time_busy = 0;
+    platform->time_idle = 0;
+    platform->temperature = 0;
+    platform->temperature_time = 0;
+    platform->timer_active = IMG_FALSE;
+
+#if RK33_USE_CL_COUNT_UTILS
+    platform->abs_load[0] = platform->abs_load[1] = platform->abs_load[2] = platform->abs_load[3] = 0;
+#endif
+#if RK33_SYSFS_FILE_SUPPORT
+    platform->debug_level = DBG_OFF;
+    platform->fix_freq = 0;
+    platform->fps_gap = FPS_DEFAULT_GAP;
+#if RK33_DVFS_FREQ_LIMIT
+    platform->up_level = -1;
+    platform->down_level = -1;
+#endif //RK33_DVFS_FREQ_LIMIT
+#endif //RK33_SYSFS_FILE_SUPPORT
+
+
+#if USE_HRTIMER
+    {
+        hrtimer_init(&platform->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+    }
+    platform->timer.function = dvfs_callback;
+#endif
+
+#if USE_KTHREAD
+    platform->dvfs_task = kthread_create(gpu_dvfs_task, platform, "GpuDvfsD");
+       if (IS_ERR(platform->dvfs_task)) {
+               iRet = PTR_ERR(platform->dvfs_task);
+               PVR_DPF((PVR_DBG_ERROR, "failed to create kthread! error %d\n", iRet));
+        return;
+       }
+
+       sched_setscheduler_nocheck(platform->dvfs_task, SCHED_FIFO, &param);
+       get_task_struct(platform->dvfs_task);
+       kthread_bind(platform->dvfs_task, 0);
+
+    init_waitqueue_head(&platform->dvfs_wait);
+
+#endif
+    //spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+}
+
+static void rk33_dvfs_utils_term(struct rk_context *platform)
+{
+    unsigned long flags;
+
+    PVR_ASSERT(platform != NULL);
+
+
+    if(platform->timer_active)
+    {
+        spin_lock_irqsave(&platform->timer_lock, flags);
+        platform->timer_active = IMG_FALSE;
+        spin_unlock_irqrestore(&platform->timer_lock, flags);
+#if USE_HRTIMER
+        hrtimer_cancel(&platform->timer);
+#elif USE_KTHREAD
+        kthread_stop(platform->dvfs_task);
+#endif
+    }
+}
+
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+/*caller needs to hold kbdev->pm.metrics.lock before calling this function*/
+static void rk33_dvfs_record_busy_utils(struct rk_context *platform)
+{
+    ktime_t now;
+    ktime_t diff;
+    IMG_UINT32 ns_time;
+
+    PVR_ASSERT(platform != NULL);
+
+    now = ktime_get();
+    diff = ktime_sub(now, platform->time_period_start);
+
+    ns_time = (IMG_UINT32)(ktime_to_ns(diff) >> RK_PM_TIME_SHIFT);
+    platform->time_busy += ns_time;
+    platform->time_period_start = now;
+}
+
+static void rk33_dvfs_record_idle_utils(struct rk_context *platform)
+{
+    ktime_t now;
+    ktime_t diff;
+    IMG_UINT32 ns_time;
+
+    PVR_ASSERT(platform != NULL);
+
+    now = ktime_get();
+    diff = ktime_sub(now, platform->time_period_start);
+
+    ns_time = (IMG_UINT32)(ktime_to_ns(diff) >> RK_PM_TIME_SHIFT);
+    platform->time_idle += ns_time;
+    platform->time_period_start = now;
+}
+#endif
+
+static void rk33_dvfs_record_gpu_idle(struct rk_context *platform)
+{
+    unsigned long flags;
+    PVR_ASSERT(platform != NULL);
+
+    if(!platform->gpu_active)
+        return;
+
+    spin_lock_irqsave(&platform->timer_lock, flags);
+
+    //PVR_ASSERT(platform->gpu_active == IMG_TRUE);
+
+    platform->gpu_active = IMG_FALSE;
+
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    rk33_dvfs_record_busy_utils(platform);
+#endif
+
+    spin_unlock_irqrestore(&platform->timer_lock, flags);
+}
+
+
+static void rk33_dvfs_record_gpu_active(struct rk_context *platform)
+{
+    unsigned long flags;
+
+    PVR_ASSERT(platform != NULL);
+
+    if(platform->gpu_active)
+        return;
+
+    spin_lock_irqsave(&platform->timer_lock, flags);
+
+    //PVR_ASSERT(platform->gpu_active == IMG_FALSE);
+
+    platform->gpu_active = IMG_TRUE;
+
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    rk33_dvfs_record_idle_utils(platform);
+#endif
+
+    spin_unlock_irqrestore(&platform->timer_lock, flags);
+}
+
+static IMG_BOOL rk33_dvfs_get_freq_table(struct rk_context *platform)
+{
+    IMG_INT i;
+
+    PVR_ASSERT(platform != NULL);
+
+    //get freq table
+    rgx_freq_table = dvfs_get_freq_volt_table(platform->gpu_clk_node);
+
+    if (rgx_freq_table == NULL)
+    {
+        printk("rgx freq table not assigned yet,use default\n");
+        return IMG_FALSE ;
+    }
+    else
+    {
+        /*recalculte step*/
+        RGX_DVFS_STEP = 0;
+
+        PVR_DPF((PVR_DBG_WARNING, "The raw GPU freq_table:"));
+        for (i = 0; rgx_freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+        {
+            rgx_dvfs_infotbl[i].clock = rgx_freq_table[i].frequency / ONE_KHZ;
+            PVR_DPF((PVR_DBG_WARNING, "%dM,", rgx_dvfs_infotbl[i].clock));
+            RGX_DVFS_STEP++;
+        }
+
+        if (RGX_DVFS_STEP > 1)
+            div_dvfs = round_up(((levelf_threshold_max - level0_threshold_max) / (RGX_DVFS_STEP - 1)), 1);
+
+        PVR_DPF((PVR_DBG_WARNING, "RGX_DVFS_STEP=%d,div_dvfs=%d\n", RGX_DVFS_STEP, div_dvfs));
+
+        for (i = 0;i < RGX_DVFS_STEP;i++)
+        {
+            calculate_dvfs_max_min_threshold(i);
+        }
+        p_rgx_dvfs_infotbl = rgx_dvfs_infotbl;
+    }
+
+    return IMG_TRUE;
+}
+
+IMG_BOOL rk33_dvfs_init(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (IMG_FALSE == rk33_dvfs_get_freq_table(platform))
+        return IMG_FALSE;
+
+    if (!rgx_dvfs_wq)
+        rgx_dvfs_wq = create_singlethread_workqueue("rgx_dvfs");
+
+    spin_lock_init(&rgx_dvfs_spinlock);
+   // mutex_init(&rgx_set_clock_lock);
+    mutex_init(&rgx_enable_clock_lock);
+
+    rk33_dvfs_utils_init(platform);
+
+    return IMG_TRUE;
+}
+
+
+IMG_VOID rk33_dvfs_term(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+    rk33_dvfs_utils_term(platform);
+
+    if (rgx_dvfs_wq)
+        destroy_workqueue(rgx_dvfs_wq);
+
+    rgx_dvfs_wq = NULL;
+}
+
+#if RK33_SYSFS_FILE_SUPPORT
+#if RK33_DVFS_FREQ_LIMIT
+static int rk33_dvfs_up_limit_on(int level)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform || level < 0)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    if (platform->down_level >= 0 &&
+            platform->down_level > level)
+    {
+        PVR_DPF((PVR_DBG_ERROR, " rk33_dvfs_up_limit_on : Attempting to set upper lock (%d) to below under lock(%d)\n", level, platform->down_level));
+        spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+        return -1;
+    }
+    platform->up_level = level;
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    PVR_DPF((PVR_DBG_WARNING, " Up Level Set : %d\n", level));
+
+    return 0;
+}
+
+static int rk33_dvfs_up_limit_off(void)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    platform->up_level = -1;
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    PVR_DPF((PVR_DBG_WARNING, "Up Level Unset\n"));
+
+    return 0;
+}
+
+static int rk33_dvfs_down_limit_on(int level)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform || level < 0)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    if (platform->up_level >= 0 &&
+            platform->up_level < level)
+    {
+        PVR_DPF((PVR_DBG_ERROR, " rk33_dvfs_down_limit_on : Attempting to set under lock (%d) to above upper lock(%d)\n", level, platform->up_level));
+        spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+        return -1;
+    }
+    platform->down_level = level;
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    PVR_DPF((PVR_DBG_WARNING, " Down Level Set : %d\n", level));
+
+    return 0;
+}
+
+static int rk33_dvfs_down_limit_off(void)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    platform->down_level = -1;
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    PVR_DPF((PVR_DBG_WARNING, "Up Level Unset\n"));
+
+    return 0;
+}
+
+static int rk33_dvfs_get_dvfs_up_limit_freq(void)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+    int up_level = -1;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    up_level = rk33_dvfs_get_freq(platform->up_level);
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    return up_level;
+}
+
+static int rk33_dvfs_get_dvfs_down_limit_freq(void)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+    int down_level = -1;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    spin_lock_irqsave(&rgx_dvfs_spinlock, flags);
+    down_level = rk33_dvfs_get_freq(platform->down_level);
+    spin_unlock_irqrestore(&rgx_dvfs_spinlock, flags);
+
+    return down_level;
+}
+#endif //end of RK33_DVFS_FREQ_LIMIT
+
+static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct rk_context *platform;
+    ssize_t ret = 0;
+    unsigned int clkrate;
+    int i ;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    if (platform->debug_level > DBG_OFF)
+    {
+#if RK33_DVFS_SUPPORT
+        if (!platform->gpu_clk_node)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "gpu_clk_node not init!"));
+            return -ENODEV;
+        }
+        clkrate = dvfs_clk_get_rate(platform->gpu_clk_node);
+#else
+        if (!platform->aclk_gpu_mem)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "aclk_gpu_mem not init!"));
+            return -ENODEV;
+        }
+        clkrate = clk_get_rate(platform->aclk_gpu_mem);
+#endif
+        if (platform->dvfs_enabled)
+        {
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "DVFS is on");
+
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nCurrent clk rgx = %dMhz", clkrate / ONE_MHZ);
+            /* To be revised  */
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings:");
+            for (i = 0;i < RGX_DVFS_STEP;i++)
+                ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_rgx_dvfs_infotbl[i].clock);
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
+        }
+        else
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "DVFS is off");
+
+        if (ret < PAGE_SIZE - 1)
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+        else
+        {
+            buf[PAGE_SIZE - 2] = '\n';
+            buf[PAGE_SIZE - 1] = '\0';
+            ret = PAGE_SIZE - 1;
+        }
+    }
+    return ret;
+}
+
+static ssize_t set_freq(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct rk_context *platform;
+    unsigned int tmp = 0, freq = 0;
+    tmp = 0;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform)
+        return -ENODEV;
+
+    if (!platform->gpu_clk_node)
+        return -ENODEV;
+#if 0
+    if (sysfs_streq("500", buf))
+    {
+        freq = 500;
+    }
+    else if (sysfs_streq("400", buf))
+    {
+        freq = 400;
+    }
+    else if (sysfs_streq("350", buf))
+    {
+        freq = 350;
+    }
+    else if (sysfs_streq("266", buf))
+    {
+        freq = 266;
+    }
+    else if (sysfs_streq("160", buf))
+    {
+        freq = 160;
+    }
+    else if (sysfs_streq("100", buf))
+    {
+        freq = 100;
+    }
+    else
+    {
+        dev_err(dev, "set_clock: invalid value\n");
+        return -ENOENT;
+    }
+#endif
+
+    if (memcmp(buf, "debug_hi", 8) == 0)
+    {
+        platform->debug_level = DBG_HIGH;
+        return (count);
+    }
+    if (memcmp(buf, "debug_lo", 8) == 0)
+    {
+        platform->debug_level = DBG_LOW;
+        return (count);
+    }
+    else if (memcmp(buf, "debug_off", 9) == 0)
+    {
+        platform->debug_level = DBG_OFF;
+        return (count);
+    }
+
+// freq = simple_strtoul(buf, NULL, 10);
+    if (sscanf(buf, "%i", &freq) == 0)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "invalid value"));
+        return -EINVAL;
+    }
+    else
+    {
+        if (rk33_dvfs_get_level(freq) >= RGX_DVFS_STEP || rk33_dvfs_get_level(freq) < 0)
+        {
+            PVR_DPF((PVR_DBG_ERROR, "invalid freq(%d)", freq));
+            platform->fix_freq = 0; //open dvfs
+            return count;
+        }
+    }
+
+    rk33_dvfs_set_level(rk33_dvfs_get_level(freq));
+
+    platform->fix_freq = freq;  //close dvfs
+
+    return count;
+}
+
+static ssize_t show_utilisation(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct rk_context *platform;
+    PVRSRV_RGXDEV_INFO  *psDevInfo;
+    IMG_INT         utilisation;
+    IMG_UINT32      time_busy;
+    IMG_UINT32      time_idle;
+    ssize_t ret = 0;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform || !platform->psDeviceNode)
+        return -ENODEV;
+
+    if (platform->debug_level > DBG_OFF)
+    {
+        psDevInfo = platform->psDeviceNode->pvDevice;
+
+        //Measuring GPU Utilisation
+        eError = ((psDevInfo->pfnGetGpuUtilStats)(platform->psDeviceNode,ghGpuUtilDvfs,&platform->sUtilStats));
+        time_busy = platform->sUtilStats.ui64GpuStatActiveHigh + platform->sUtilStats.ui64GpuStatActiveLow;
+        time_idle = platform->sUtilStats.ui64GpuStatIdle + platform->sUtilStats.ui64GpuStatBlocked;
+        utilisation = (time_busy * 100) / (time_busy + time_idle);
+
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "Utilisation=%d", utilisation);
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nDetail: ActiveHigh=%llu,ActiveLow=%llu,Blocked=%llu,Idle=%llu", \
+                        platform->sUtilStats.ui64GpuStatActiveHigh, platform->sUtilStats.ui64GpuStatActiveLow, platform->sUtilStats.ui64GpuStatBlocked, platform->sUtilStats.ui64GpuStatIdle);
+
+        if (ret < PAGE_SIZE - 1)
+            ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+        else
+        {
+            buf[PAGE_SIZE - 2] = '\n';
+            buf[PAGE_SIZE - 1] = '\0';
+            ret = PAGE_SIZE - 1;
+        }
+    }
+    return ret;
+}
+
+static ssize_t set_utilisation(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    unsigned int utilisation = 0;
+    utilisation = simple_strtoul(buf, NULL, 10);
+
+    return count;
+}
+
+static ssize_t show_fbdev(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    int i, ret = 0;
+
+    for (i = 0; i < num_registered_fb; i++)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "fb[%d] xres=%d, yres=%d, addr=0x%lx\n", i, registered_fb[i]->var.xres, registered_fb[i]->var.yres, registered_fb[i]->fix.smem_start);
+
+    if (ret < PAGE_SIZE - 1)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+    else
+    {
+        buf[PAGE_SIZE - 2] = '\n';
+        buf[PAGE_SIZE - 1] = '\0';
+        ret = PAGE_SIZE - 1;
+    }
+
+    return ret;
+}
+
+static ssize_t show_fps(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    int ret = 0;
+    IMG_UINT32 fps = 0;
+
+    fps = rk_get_real_fps(0);
+
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, "fbs=%d", fps);
+
+    if (ret < PAGE_SIZE - 1)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+    else
+    {
+        buf[PAGE_SIZE - 2] = '\n';
+        buf[PAGE_SIZE - 1] = '\0';
+        ret = PAGE_SIZE - 1;
+    }
+
+    return ret;
+}
+static enum hrtimer_restart fps_callback(struct hrtimer *timer)
+{
+    struct rk_context *platform;
+    IMG_UINT32 fps = 0;
+
+    PVR_ASSERT(timer != NULL);
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    PVR_ASSERT(platform != NULL);
+
+    fps = rk_get_real_fps(0);
+    printk("Current fps=%d\n", fps);
+
+    hrtimer_start(timer,
+                  HR_TIMER_DELAY_MSEC(platform->fps_gap),
+                  HRTIMER_MODE_REL);
+
+    return HRTIMER_NORESTART;
+}
+
+static ssize_t set_fps(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct rk_context *platform;
+    static IMG_BOOL bOpen = IMG_FALSE;
+    static struct hrtimer timer;
+    IMG_UINT  gap = FPS_DEFAULT_GAP;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (!platform)
+        return -ENODEV;
+
+    gap = simple_strtoul(buf, NULL, 10);
+
+    if (sysfs_streq("on", buf) && !bOpen)
+    {
+        bOpen = IMG_TRUE;
+        hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+        timer.function = fps_callback;
+        hrtimer_start(&timer, HR_TIMER_DELAY_MSEC(platform->fps_gap), HRTIMER_MODE_REL);
+        printk("on fps\n");
+    }
+    else if (sysfs_streq("off", buf))
+    {
+        printk("off fps\n");
+
+        if(bOpen)
+        {
+            bOpen = IMG_FALSE;
+            hrtimer_cancel(&timer);
+        }
+    }
+    else
+    {
+        if (gap > 0  && gap < FPS_MAX_GAP)
+            platform->fps_gap = gap;
+    }
+
+    return count;
+}
+
+#if RK33_DVFS_FREQ_LIMIT
+static ssize_t show_up_limit(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct rk_context *platform;
+    ssize_t ret = 0;
+    int i;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform)
+        return -ENODEV;
+
+    if (platform->up_level >= 0 && platform->up_level < RGX_DVFS_STEP)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Up limit freq = %dMhz", rk33_dvfs_get_dvfs_up_limit_freq());
+    else
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the up limit level");
+
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings :");
+    for (i = 0;i < RGX_DVFS_STEP;i++)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_rgx_dvfs_infotbl[i].clock);
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : off");
+
+    if (ret < PAGE_SIZE - 1)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+    else
+    {
+        buf[PAGE_SIZE - 2] = '\n';
+        buf[PAGE_SIZE - 1] = '\0';
+        ret = PAGE_SIZE - 1;
+    }
+
+    return ret;
+}
+
+static ssize_t set_up_limit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct rk_context *platform;
+    unsigned int freq = 0;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform)
+        return -ENODEV;
+
+    freq = simple_strtoul(buf, NULL, 10);
+
+    if (sysfs_streq("off", buf))
+    {
+        rk33_dvfs_up_limit_off();
+    }
+    else
+    {
+        rk33_dvfs_up_limit_on(rk33_dvfs_get_level(freq));
+    }
+
+    return count;
+}
+
+static ssize_t show_down_limit(struct device *dev, struct device_attribute *attr, char *buf)
+{
+    struct rk_context *platform;
+    ssize_t ret = 0;
+    int i;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform)
+        return -ENODEV;
+
+    if (platform->down_level >= 0 && platform->down_level < RGX_DVFS_STEP)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current down limit freq = %dMhz", rk33_dvfs_get_dvfs_down_limit_freq());
+    else
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the down limit level");
+
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings :");
+    for (i = 0;i < RGX_DVFS_STEP;i++)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ", p_rgx_dvfs_infotbl[i].clock);
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
+    ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : off");
+
+    if (ret < PAGE_SIZE - 1)
+        ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+    else
+    {
+        buf[PAGE_SIZE - 2] = '\n';
+        buf[PAGE_SIZE - 1] = '\0';
+        ret = PAGE_SIZE - 1;
+    }
+
+    return ret;
+}
+
+static ssize_t set_down_limit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+    struct rk_context *platform;
+    unsigned int freq = 0;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+    if (!platform)
+        return -ENODEV;
+
+    freq = simple_strtoul(buf, NULL, 10);
+
+    if (sysfs_streq("off", buf))
+    {
+        rk33_dvfs_down_limit_off();
+    }
+    else
+    {
+        rk33_dvfs_down_limit_on(rk33_dvfs_get_level(freq));
+    }
+
+    return count;
+}
+#endif
+
+/** The sysfs file @c clock, fbdev.
+ *
+ * This is used for obtaining information about the mali t6xx operating clock & framebuffer address,
+ */
+DEVICE_ATTR(freq, S_IRUGO | S_IWUSR, show_freq, set_freq);
+DEVICE_ATTR(util, S_IRUGO | S_IWUSR, show_utilisation, set_utilisation);
+DEVICE_ATTR(fbdev, S_IRUGO, show_fbdev, NULL);
+DEVICE_ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps);
+#if RK33_DVFS_FREQ_LIMIT
+DEVICE_ATTR(dvfs_up_limit, S_IRUGO | S_IWUSR, show_up_limit, set_up_limit);
+DEVICE_ATTR(dvfs_down_limit, S_IRUGO | S_IWUSR, show_down_limit, set_down_limit);
+#endif
+
+static IMG_INT rk_create_sysfs_file(struct device *dev)
+{
+    if (device_create_file(dev, &dev_attr_freq))
+    {
+        dev_err(dev, "Couldn't create sysfs file [freq]\n");
+        goto out;
+    }
+
+    if (device_create_file(dev, &dev_attr_util))
+    {
+        dev_err(dev, "Couldn't create sysfs file [utilisation]\n");
+        goto out;
+    }
+
+    if (device_create_file(dev, &dev_attr_fbdev))
+    {
+        dev_err(dev, "Couldn't create sysfs file [fbdev]\n");
+        goto out;
+    }
+
+    if (device_create_file(dev, &dev_attr_fps))
+    {
+        dev_err(dev, "Couldn't create sysfs file [fbdev]\n");
+        goto out;
+    }
+
+#if RK33_DVFS_FREQ_LIMIT
+    if (device_create_file(dev, &dev_attr_dvfs_up_limit))
+    {
+        dev_err(dev, "Couldn't create sysfs file [dvfs_upper_lock]\n");
+        goto out;
+    }
+
+    if (device_create_file(dev, &dev_attr_dvfs_down_limit))
+    {
+        dev_err(dev, "Couldn't create sysfs file [dvfs_under_lock]\n");
+        goto out;
+    }
+#endif
+
+    return 0;
+out:
+    return -ENOENT;
+}
+
+static IMG_VOID rk_remove_sysfs_file(struct device *dev)
+{
+    device_remove_file(dev, &dev_attr_freq);
+    device_remove_file(dev, &dev_attr_util);
+    device_remove_file(dev, &dev_attr_fbdev);
+    device_remove_file(dev, &dev_attr_fps);
+#if RK33_DVFS_FREQ_LIMIT
+    device_remove_file(dev, &dev_attr_dvfs_up_limit);
+    device_remove_file(dev, &dev_attr_dvfs_down_limit);
+#endif
+}
+
+
+
+#endif //end of RK33_SYSFS_FILE_SUPPORT
+
+#if RK33_USE_RGX_GET_GPU_UTIL
+IMG_BOOL rk33_set_device_node(IMG_HANDLE hDevCookie)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+    PVRSRV_ERROR eError = PVRSRV_OK;
+    PVRSRV_RGXDEV_INFO  *psDevInfo;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if(platform)
+    {
+        platform->psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
+
+        //start timer
+#if USE_HRTIMER
+        if(platform->psDeviceNode && platform->dvfs_enabled && platform->timer.function && !platform->timer_active)
+#elif USE_KTHREAD
+        if(platform->psDeviceNode && platform->dvfs_enabled && !platform->timer_active)
+#endif
+        {
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_TRUE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+
+            if (ghGpuUtilDvfs == NULL)
+            {
+                if(platform->psDeviceNode)
+                {
+                    psDevInfo = platform->psDeviceNode->pvDevice;
+                    eError = psDevInfo->pfnRegisterGpuUtilStats(&ghGpuUtilDvfs);
+                }
+            }
+            
+#if USE_HRTIMER
+            hrtimer_start(&platform->timer, HR_TIMER_DELAY_MSEC(RK33_DVFS_FREQ), HRTIMER_MODE_REL);
+#elif USE_KTHREAD
+            wake_up_process(platform->dvfs_task);
+#endif
+         }
+    }
+    else
+    {
+        //call PVRSRVRegisterPowerDevice before RgxRkInit.
+        PVR_DPF((PVR_DBG_ERROR,"PVR_K:%s platform is null\n",__func__));
+        return IMG_FALSE;
+    }
+
+    return IMG_TRUE;
+}
+
+IMG_BOOL rk33_clear_device_node(IMG_VOID)
+{
+    struct rk_context *platform;
+    unsigned long flags;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if(platform)
+    {
+        //cacel timer
+        if(platform->timer_active && platform->dvfs_enabled)
+        {
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_FALSE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+#if USE_HRTIMER
+            hrtimer_cancel(&platform->timer);
+#endif
+        }
+        platform->psDeviceNode = NULL;
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_ERROR,"PVR_K:%s platform is null\n",__func__));
+        return IMG_FALSE;
+    }
+
+    return IMG_TRUE;
+}
+#endif //RK33_USE_RGX_GET_GPU_UTIL
+
+#endif //end of RK33_DVFS_SUPPORT
+
+static IMG_VOID RgxEnableClock(IMG_VOID)
+{
+    struct rk_context *platform;
+#if RK33_DVFS_SUPPORT
+    unsigned long flags;
+#endif
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (platform->aclk_gpu_mem && platform->aclk_gpu_cfg && !platform->gpu_active)
+    {
+        if(platform->gpu_clk_node)
+            dvfs_clk_prepare_enable(platform->gpu_clk_node);
+        else if(platform->clk_gpu)
+            clk_prepare_enable(platform->clk_gpu);
+        clk_prepare_enable(platform->aclk_gpu_mem);
+        clk_prepare_enable(platform->aclk_gpu_cfg);
+
+#if RK33_DVFS_SUPPORT
+        rk33_dvfs_record_gpu_active(platform);
+
+        if(platform->psDeviceNode && platform->dvfs_enabled && !platform->timer_active)
+        {
+
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_TRUE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+#if USE_HRTIMER
+            hrtimer_start(&platform->timer, HR_TIMER_DELAY_MSEC(RK33_DVFS_FREQ), HRTIMER_MODE_REL);
+#endif
+        }
+#endif
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_WARNING, "Failed to enable clock!"));
+    }
+
+}
+
+static IMG_VOID RgxDisableClock(IMG_VOID)
+{
+    struct rk_context *platform;
+#if RK33_DVFS_SUPPORT
+    unsigned long flags;
+#endif
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    if (platform->aclk_gpu_mem && platform->aclk_gpu_cfg && platform->gpu_active)
+    {
+#if RK33_DVFS_SUPPORT
+        if(platform->fix_freq <= 0)
+        {
+            //Force to drop freq to the lowest.
+            rk33_dvfs_set_level(0);
+        }
+
+        if(platform->dvfs_enabled && platform->timer_active)
+        {
+            spin_lock_irqsave(&platform->timer_lock, flags);
+            platform->timer_active = IMG_FALSE;
+            spin_unlock_irqrestore(&platform->timer_lock, flags);
+#if USE_HRTIMER
+            hrtimer_cancel(&platform->timer);
+#endif
+        }
+
+        rk33_dvfs_record_gpu_idle(platform);
+
+#endif
+        clk_disable_unprepare(platform->aclk_gpu_cfg);
+        clk_disable_unprepare(platform->aclk_gpu_mem);
+        if(platform->gpu_clk_node)
+            dvfs_clk_disable_unprepare(platform->gpu_clk_node);
+        else if(platform->clk_gpu)
+            clk_disable_unprepare(platform->clk_gpu);
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_WARNING, "Failed to disable clock!"));
+    }
+}
+
+#if RK_RESERVED
+static IMG_BOOL RgxIsPowerOn(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+    return platform->bEnablePd;
+}
+#endif
+
+#if OPEN_GPU_PD
+/*
+ * The power management
+ * software must power down pd_gpu_1 before power down pd_gpu_0,
+ * and power up pd_gpu_1 after power up pd_gpu_0.
+ */
+static IMG_VOID RgxEnablePower(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+    if (!platform->bEnablePd && platform->pd_gpu_0 && platform->pd_gpu_1)
+    {
+        clk_prepare_enable(platform->pd_gpu_0);
+        clk_prepare_enable(platform->pd_gpu_1);
+        platform->bEnablePd = IMG_TRUE;
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_WARNING, "Failed to enable gpu_pd clock!"));
+    }
+}
+
+static IMG_VOID RgxDisablePower(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    PVR_ASSERT(platform != NULL);
+
+    if (platform->bEnablePd && platform->pd_gpu_0 && platform->pd_gpu_1)
+    {
+        clk_disable_unprepare(platform->pd_gpu_1);
+        clk_disable_unprepare(platform->pd_gpu_0);
+        platform->bEnablePd = IMG_FALSE;
+    }
+    else
+    {
+        PVR_DPF((PVR_DBG_WARNING, "Failed to enable gpu_pd clock!"));
+    }
+}
+#endif
+
+IMG_VOID RgxResume(IMG_VOID)
+{
+#if OPEN_GPU_PD
+    RgxEnablePower();
+#endif
+
+    //mdelay(2);
+
+    /* set external isolation invalid */
+    //writel(0, SUNXI_R_PRCM_VBASE + GPU_PWROFF_GATING);
+
+    //DeAssertGpuResetSignal();
+
+    RgxEnableClock();
+
+    /* delay for internal power stability */
+    //writel(0x100, SUNXI_GPU_CTRL_VBASE + 0x18);
+}
+
+IMG_VOID RgxSuspend(IMG_VOID)
+{
+    RgxDisableClock();
+
+    //AssertGpuResetSignal();
+
+    /* set external isolation valid */
+    //writel(1, SUNXI_R_PRCM_VBASE + GPU_PWROFF_GATING);
+
+#if OPEN_GPU_PD
+    RgxDisablePower();
+#endif
+
+}
+
+PVRSRV_ERROR RkPrePowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced)
+{
+    if (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON)
+    {
+        RgxResume();
+    }
+    return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RkPostPowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced)
+{
+    if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+    {
+        RgxSuspend();
+    }
+    return PVRSRV_OK;
+}
+
+IMG_VOID RgxRkInit(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = kzalloc(sizeof(struct rk_context), GFP_KERNEL);
+
+    if (NULL == platform)
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to kzalloc rk_context"));
+        return;
+    }
+
+#if RK_TF_VERSION
+    rk_tf_check_version();
+#endif
+
+    dev_set_drvdata(&gpsPVRLDMDev->dev, platform);
+
+#if OPEN_GPU_PD
+    platform->bEnablePd = IMG_FALSE;
+#endif
+    platform->cmu_pmu_status = 0;
+    platform->psDeviceNode = NULL;
+
+    spin_lock_init(&platform->cmu_pmu_lock);
+    spin_lock_init(&platform->timer_lock);
+
+#if OPEN_GPU_PD
+    platform->pd_gpu_0 = devm_clk_get(&gpsPVRLDMDev->dev, "pd_gpu_0");
+    if (IS_ERR_OR_NULL(platform->pd_gpu_0))
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to find pd_gpu_0 clock source"));
+        goto fail0;
+    }
+
+    platform->pd_gpu_1 = devm_clk_get(&gpsPVRLDMDev->dev, "pd_gpu_1");
+    if (IS_ERR_OR_NULL(platform->pd_gpu_1))
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to find pd_gpu_1 clock source"));
+        goto fail1;
+    }
+#endif
+
+    platform->aclk_gpu_mem = devm_clk_get(&gpsPVRLDMDev->dev, "aclk_gpu_mem");
+    if (IS_ERR_OR_NULL(platform->aclk_gpu_mem))
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to find aclk_gpu_mem clock source"));
+        goto fail2;
+    }
+
+    platform->aclk_gpu_cfg = devm_clk_get(&gpsPVRLDMDev->dev, "aclk_gpu_cfg");
+    if (IS_ERR_OR_NULL(platform->aclk_gpu_cfg))
+    {
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to find aclk_gpu_cfg clock source"));
+        goto fail3;
+    }
+
+    platform->gpu_clk_node  = clk_get_dvfs_node("clk_gpu");
+    if (IS_ERR_OR_NULL(platform->gpu_clk_node))
+    {
+        platform->dvfs_enabled = IMG_FALSE;
+        PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: GPU Dvfs is disabled"));
+        platform->clk_gpu = devm_clk_get(&gpsPVRLDMDev->dev, "clk_gpu");
+        if (IS_ERR_OR_NULL(platform->clk_gpu))
+        {
+            PVR_DPF((PVR_DBG_ERROR, "RgxRkInit: Failed to find clk_gpu clock source"));
+            goto fail4;
+        }
+    }
+    else
+    {
+        platform->dvfs_enabled = IMG_TRUE;
+        rk33_clk_set_dvfs_node(platform->gpu_clk_node, RK33_DEFAULT_CLOCK);
+        rk33_clk_set_normal_node(platform->aclk_gpu_mem, RK33_DEFAULT_CLOCK);
+        rk33_clk_set_normal_node(platform->aclk_gpu_cfg, RK33_DEFAULT_CLOCK);
+#if RK33_DVFS_SUPPORT
+        rk33_dvfs_init();
+#if RK33_SYSFS_FILE_SUPPORT
+        //create sysfs file node
+        rk_create_sysfs_file(&gpsPVRLDMDev->dev);
+#endif
+
+#endif //end of RK33_DVFS_SUPPORT
+    }
+
+    RgxResume();
+
+    return;
+
+fail4:
+    devm_clk_put(&gpsPVRLDMDev->dev, platform->aclk_gpu_cfg);
+    platform->aclk_gpu_cfg = NULL;
+fail3:
+    devm_clk_put(&gpsPVRLDMDev->dev, platform->aclk_gpu_mem);
+    platform->aclk_gpu_mem = NULL;
+fail2:
+
+#if OPEN_GPU_PD
+    devm_clk_put(&gpsPVRLDMDev->dev, platform->pd_gpu_1);
+    platform->pd_gpu_1 = NULL;
+fail1:
+    devm_clk_put(&gpsPVRLDMDev->dev, platform->pd_gpu_0);
+    platform->pd_gpu_0 = NULL;
+fail0:
+#endif //end of OPEN_GPU_PD
+
+    kfree(platform);
+}
+
+IMG_VOID RgxRkUnInit(IMG_VOID)
+{
+    struct rk_context *platform;
+
+    platform = dev_get_drvdata(&gpsPVRLDMDev->dev);
+
+    RgxSuspend();
+
+    if(platform->gpu_clk_node)
+    {
+        clk_put_dvfs_node(platform->gpu_clk_node);
+        platform->gpu_clk_node = NULL;
+    }
+    else if(platform->clk_gpu)
+    {
+        devm_clk_put(&gpsPVRLDMDev->dev, platform->clk_gpu);
+        platform->clk_gpu = NULL;
+    }
+
+    if(platform->aclk_gpu_cfg)
+    {
+        devm_clk_put(&gpsPVRLDMDev->dev, platform->aclk_gpu_cfg);
+        platform->aclk_gpu_cfg = NULL;
+    }
+    if(platform->aclk_gpu_mem)
+    {
+        devm_clk_put(&gpsPVRLDMDev->dev, platform->aclk_gpu_mem);
+        platform->aclk_gpu_mem = NULL;
+    }
+#if OPEN_GPU_PD
+    if(platform->pd_gpu_1)
+    {
+        devm_clk_put(&gpsPVRLDMDev->dev, platform->pd_gpu_1);
+        platform->pd_gpu_1 = NULL;
+    }
+    if(platform->pd_gpu_0)
+    {
+        devm_clk_put(&gpsPVRLDMDev->dev, platform->pd_gpu_0);
+        platform->pd_gpu_0 = NULL;
+    }
+#endif
+
+    if(platform->dvfs_enabled)
+    {
+#if RK33_DVFS_SUPPORT
+#if RK33_SYSFS_FILE_SUPPORT
+        rk_remove_sysfs_file(&gpsPVRLDMDev->dev);
+#endif
+        rk33_dvfs_term();
+#endif
+    }
+    kfree(platform);
+}
+
+
+#if defined(SUPPORT_ION)
+struct ion_device *g_psIonDev;
+extern struct ion_device *rockchip_ion_dev;
+
+PVRSRV_ERROR IonInit(void *phPrivateData)
+{
+    g_psIonDev    = rockchip_ion_dev;
+    return PVRSRV_OK;
+}
+
+struct ion_device *IonDevAcquire(IMG_VOID)
+{
+    return g_psIonDev;
+}
+
+IMG_VOID IonDevRelease(struct ion_device *psIonDev)
+{
+    /* Nothing to do, sanity check the pointer we're passed back */
+    PVR_ASSERT(psIonDev == g_psIonDev);
+}
+
+IMG_UINT32 IonPhysHeapID(IMG_VOID)
+{
+    return 0;
+}
+
+IMG_VOID IonDeinit(IMG_VOID)
+{
+    g_psIonDev = NULL;
+}
+#endif /* defined(SUPPORT_ION) */
diff --git a/drivers/gpu/rogue_m/system/rk3368/rk_init.h b/drivers/gpu/rogue_m/system/rk3368/rk_init.h
new file mode 100644 (file)
index 0000000..b71ad46
--- /dev/null
@@ -0,0 +1,179 @@
+#if !defined(__RK_INIT__)
+#define __RK_INIT__
+
+#include <linux/hrtimer.h>
+#include <linux/kthread.h>
+#include "rgxdevice.h"
+#include "device.h"
+
+/****************************************************************************
+       Add Rockchip modificatons here!
+*****************************************************************************/
+#define RK33_DVFS_SUPPORT                   1   // 1:DVFS on   0:DVFS off
+#define RK33_SYSFS_FILE_SUPPORT             1   // 1:add information nodes in /sys/devices/ffa30000.gpu/
+
+//RK33_USE_RGX_GET_GPU_UTIL and RK33_USE_CUSTOMER_GET_GPU_UTIL are mutually exclusive
+#define RK33_USE_RGX_GET_GPU_UTIL           1
+#define RK33_USE_CUSTOMER_GET_GPU_UTIL      0
+
+#define RK33_USE_CL_COUNT_UTILS             0
+#define OPEN_GPU_PD                         1
+
+//USE_KTHREAD and USE_HRTIMER are mutually exclusive
+#define USE_KTHREAD                         0
+#define USE_HRTIMER                         1
+
+#define RK_TF_VERSION                       1
+
+#define RK33_MAX_UTILIS                 4
+#define RK33_DVFS_FREQ                  50
+#define RK33_DEFAULT_CLOCK              400
+#define RK33_DVFS_FREQ_LIMIT            1
+#define RK_RESERVED                     0
+#define RGX_DVFS_CURRENT_FREQ           0
+
+#define FPS_DEFAULT_GAP                 300
+#define FPS_MAX_GAP                     5000
+#define LIMIT_FPS                       60
+#define LIMIT_FPS_POWER_SAVE            50
+#define ONE_KHZ                         1000
+#define ONE_MHZ                         1000000
+#define HZ_TO_MHZ(m)                  ((m) / ONE_MHZ)
+/* Conversion helpers for setting up high resolution timers */
+#define HR_TIMER_DELAY_MSEC(x)          (ns_to_ktime((x)*1000000U))
+#define HR_TIMER_DELAY_NSEC(x)          (ns_to_ktime(x))
+#define RGX_DVFS_LEVEL_INTERVAL          2
+
+/* Shift used for kbasep_pm_metrics_data.time_busy/idle - units of (1 << 8) ns
+   This gives a maximum period between samples of 2^(32+8)/100 ns = slightly under 11s.
+   Exceeding this will cause overflow */
+#define RK_PM_TIME_SHIFT       8
+
+#define RK_EXPORT_API(func)  EXPORT_SYMBOL(func);
+
+typedef struct _rgx_dvfs_info
+{
+    IMG_UINT    voltage;
+    IMG_UINT    clock;
+    IMG_INT     min_threshold;
+    IMG_INT     max_threshold;
+    IMG_UINT64  time;
+    IMG_UINT    coef;
+} rgx_dvfs_info;
+
+typedef struct _rgx_dvfs_status_type
+{
+    IMG_INT step;
+    IMG_INT utilisation;
+    IMG_UINT32 temperature;
+    IMG_UINT32 temperature_time;
+#if 0
+    IMG_INT upper_lock;
+    IMG_INT under_lock;
+#endif
+
+} rgx_dvfs_status;
+
+enum
+{
+    DBG_OFF = 0,
+    DBG_LOW,
+    DBG_HIGH,
+};
+
+struct rk_utilis
+{
+    IMG_INT utilis[RK33_MAX_UTILIS];
+    IMG_INT time_busys[RK33_MAX_UTILIS];
+    IMG_INT time_idles[RK33_MAX_UTILIS];
+};
+
+struct rk_context
+{
+    /** Indicator if system clock to mail-t604 is active */
+    IMG_INT                 cmu_pmu_status;
+    /** cmd & pmu lock */
+    spinlock_t              cmu_pmu_lock;
+    /*Timer*/
+    spinlock_t              timer_lock;
+
+#if OPEN_GPU_PD
+    IMG_BOOL                bEnablePd;
+    struct clk              *pd_gpu_0;
+    struct clk              *pd_gpu_1;
+#endif
+    //struct clk              *aclk_gpu;
+    struct clk              *aclk_gpu_mem;
+    struct clk              *aclk_gpu_cfg;
+    struct clk              *clk_gpu;
+    struct dvfs_node        *gpu_clk_node;
+
+    PVRSRV_DEVICE_NODE     *psDeviceNode;
+    RGXFWIF_GPU_UTIL_STATS  sUtilStats;
+    IMG_BOOL                gpu_active;
+    IMG_BOOL                dvfs_enabled;
+
+#if RK33_DVFS_SUPPORT
+#if RK33_USE_CUSTOMER_GET_GPU_UTIL
+    ktime_t                 time_period_start;
+#endif
+
+    /*Temperature*/
+    IMG_UINT32              temperature;
+    IMG_UINT32              temperature_time;
+
+#if USE_HRTIMER
+    struct hrtimer          timer;
+#endif
+    IMG_BOOL                timer_active;
+
+#if USE_KTHREAD
+    /*dvfs kthread*/
+    struct task_struct      *dvfs_task;
+    wait_queue_head_t       dvfs_wait;
+#endif
+
+    /*To calculate utilization for x sec */
+    IMG_INT         freq_level;
+    IMG_INT         freq;
+    IMG_INT         time_tick;
+    struct rk_utilis stUtilis;
+    IMG_INT         utilisation;
+    IMG_UINT32      time_busy;
+    IMG_UINT32      time_idle;
+
+#if RK33_USE_CL_COUNT_UTILS
+    IMG_UINT32      abs_load[4];
+#endif
+
+#if RK33_SYSFS_FILE_SUPPORT
+#if RK33_DVFS_FREQ_LIMIT
+    IMG_INT         up_level;
+    IMG_INT         down_level;
+#endif //end of RK33_DVFS_FREQ_LIMIT
+    IMG_INT         debug_level;
+    IMG_UINT        fps_gap;
+    IMG_INT         fix_freq;
+#endif //end of RK33_SYSFS_FILE_SUPPORT
+
+#endif  //end of RK33_DVFS_SUPPORT
+};
+
+IMG_VOID RgxRkInit(IMG_VOID);
+IMG_VOID RgxRkUnInit(IMG_VOID);
+IMG_VOID RgxResume(IMG_VOID);
+IMG_VOID RgxSuspend(IMG_VOID);
+
+IMG_BOOL rk33_dvfs_init(IMG_VOID);
+IMG_VOID rk33_dvfs_term(IMG_VOID);
+
+#if RK33_DVFS_SUPPORT && RK33_USE_RGX_GET_GPU_UTIL
+IMG_BOOL rk33_set_device_node(IMG_HANDLE hDevCookie);
+IMG_BOOL rk33_clear_device_node(IMG_VOID);
+#endif
+
+PVRSRV_ERROR IonInit(void *pvPrivateData);
+IMG_VOID IonDeinit(IMG_VOID);
+PVRSRV_ERROR RkPrePowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced);
+PVRSRV_ERROR RkPostPowerState(PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState, IMG_BOOL bForced);
+#endif /* __SUNXI_INIT__ */
diff --git a/drivers/gpu/rogue_m/system/rk3368/sysconfig.c b/drivers/gpu/rogue_m/system/rk3368/sysconfig.c
new file mode 100644 (file)
index 0000000..ad852a5
--- /dev/null
@@ -0,0 +1,264 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Configuration
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    System Configuration functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "syscommon.h"
+#include "sysconfig.h"
+#include "physheap.h"
+#if defined(SUPPORT_ION)
+#include "ion_support.h"
+#endif
+#include "rk_init.h"
+
+static RGX_TIMING_INFORMATION  gsRGXTimingInfo;
+static RGX_DATA                        gsRGXData;
+static PVRSRV_DEVICE_CONFIG    gsDevices[1];
+static PVRSRV_SYSTEM_CONFIG    gsSysConfig;
+
+static PHYS_HEAP_FUNCTIONS     gsPhysHeapFuncs;
+#if defined(TDMETACODE)
+static PHYS_HEAP_CONFIG                gsPhysHeapConfig[3];
+#else
+static PHYS_HEAP_CONFIG                gsPhysHeapConfig[1];
+#endif
+
+/*
+       CPU to Device physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr)
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+
+       /* Optimise common case */
+       psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       Device to CPU physcial address translation
+*/
+static
+IMG_VOID UMAPhysHeapDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
+                                                                          IMG_UINT32 ui32NumOfAddr,
+                                                                          IMG_CPU_PHYADDR *psCpuPAddr,
+                                                                          IMG_DEV_PHYADDR *psDevPAddr)                           
+{
+       PVR_UNREFERENCED_PARAMETER(hPrivData);
+
+       /* Optimise common case */
+       psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr;
+       if (ui32NumOfAddr > 1)
+       {
+               IMG_UINT32 ui32Idx;
+               for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
+               {
+                       psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr;
+               }
+       }
+}
+
+/*
+       SysCreateConfigData
+*/
+PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *hDevice)
+{
+       PVR_UNREFERENCED_PARAMETER(hDevice);
+       /* Rk Init */
+       RgxRkInit();
+
+       /*
+        * Setup information about physical memory heap(s) we have
+        */
+       gsPhysHeapFuncs.pfnCpuPAddrToDevPAddr = UMAPhysHeapCpuPAddrToDevPAddr;
+       gsPhysHeapFuncs.pfnDevPAddrToCpuPAddr = UMAPhysHeapDevPAddrToCpuPAddr;
+
+       gsPhysHeapConfig[0].ui32PhysHeapID = 0;
+       gsPhysHeapConfig[0].pszPDumpMemspaceName = "SYSMEM";
+       gsPhysHeapConfig[0].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[0].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[0].hPrivData = IMG_NULL;
+
+#if defined(TDMETACODE)
+       gsPhysHeapConfig[1].ui32PhysHeapID = 1;
+       gsPhysHeapConfig[1].pszPDumpMemspaceName = "TDMETACODEMEM";
+       gsPhysHeapConfig[1].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[1].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[1].hPrivData = IMG_NULL;
+
+       gsPhysHeapConfig[2].ui32PhysHeapID = 2;
+       gsPhysHeapConfig[2].pszPDumpMemspaceName = "TDSECUREBUFMEM";
+       gsPhysHeapConfig[2].eType = PHYS_HEAP_TYPE_UMA;
+       gsPhysHeapConfig[2].psMemFuncs = &gsPhysHeapFuncs;
+       gsPhysHeapConfig[2].hPrivData = IMG_NULL;
+#endif
+
+       gsSysConfig.pasPhysHeaps = &(gsPhysHeapConfig[0]);
+       gsSysConfig.ui32PhysHeapCount = IMG_ARR_NUM_ELEMS(gsPhysHeapConfig);
+
+       gsSysConfig.pui32BIFTilingHeapConfigs = gauiBIFTilingHeapXStrides;
+       gsSysConfig.ui32BIFTilingHeapCount = IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides);
+
+       /*
+        * Setup RGX specific timing data
+        */
+       gsRGXTimingInfo.ui32CoreClockSpeed        = RGX_RK_CORE_CLOCK_SPEED;
+       gsRGXTimingInfo.bEnableActivePM           = IMG_TRUE;
+       gsRGXTimingInfo.bEnableRDPowIsland        = IMG_FALSE;
+       gsRGXTimingInfo.ui32ActivePMLatencyms     = SYS_RGX_ACTIVE_POWER_LATENCY_MS;
+
+       /*
+        *Setup RGX specific data
+        */
+       gsRGXData.psRGXTimingInfo = &gsRGXTimingInfo;
+#if defined(TDMETACODE)
+       gsRGXData.bHasTDMetaCodePhysHeap = IMG_TRUE;
+       gsRGXData.uiTDMetaCodePhysHeapID = 1;
+
+       gsRGXData.bHasTDSecureBufPhysHeap = IMG_TRUE;
+       gsRGXData.uiTDSecureBufPhysHeapID = 2;
+#endif
+
+       /*
+        * Setup RGX device
+        */
+       gsDevices[0].eDeviceType            = PVRSRV_DEVICE_TYPE_RGX;
+       gsDevices[0].pszName                = "RGX";
+
+       /* Device setup information */
+       gsDevices[0].sRegsCpuPBase.uiAddr   = RK_GPU_PBASE;
+       gsDevices[0].ui32RegsSize           = RK_GPU_SIZE;
+       gsDevices[0].ui32IRQ                = RK_IRQ_GPU;
+       gsDevices[0].bIRQIsShared           = IMG_FALSE;
+
+       /* Device's physical heap IDs */
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] = 0;
+       gsDevices[0].aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] = 0;
+
+       /* No power management on RK system */
+       gsDevices[0].pfnPrePowerState       = RkPrePowerState;
+       gsDevices[0].pfnPostPowerState      = RkPostPowerState;
+
+       /* No clock frequency either */
+       gsDevices[0].pfnClockFreqGet        = IMG_NULL;
+
+       /* No interrupt handled either */
+       gsDevices[0].pfnInterruptHandled    = IMG_NULL;
+
+       gsDevices[0].pfnCheckMemAllocSize   = SysCheckMemAllocSize;
+
+       gsDevices[0].hDevData               = &gsRGXData;
+
+       /*
+        * Setup system config
+        */
+       gsSysConfig.pszSystemName = RGX_RK_SYSTEM_NAME;
+       gsSysConfig.uiDeviceCount = sizeof(gsDevices)/sizeof(gsDevices[0]);
+       gsSysConfig.pasDevices = &gsDevices[0];
+
+       /* No power management on no HW system */
+       gsSysConfig.pfnSysPrePowerState = IMG_NULL;
+       gsSysConfig.pfnSysPostPowerState = IMG_NULL;
+
+       /* no cache snooping */
+       gsSysConfig.eCacheSnoopingMode = PVRSRV_SYSTEM_SNOOP_NONE;
+
+       /* Setup other system specific stuff */
+#if defined(SUPPORT_ION)
+       IonInit(NULL);
+#endif
+
+       *ppsSysConfig = &gsSysConfig;
+
+       return PVRSRV_OK;
+}
+
+/*
+       SysDestroyConfigData
+*/
+IMG_VOID SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+
+       /* Rk UnInit */
+       RgxRkUnInit();
+
+#if defined(SUPPORT_ION)
+       IonDeinit();
+#endif
+}
+
+PVRSRV_ERROR SysAcquireSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysReleaseSystemData(IMG_HANDLE hSysData)
+{
+       PVR_UNREFERENCED_PARAMETER(hSysData);
+
+       return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
+{
+       PVR_UNREFERENCED_PARAMETER(psSysConfig);
+       PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf);
+       return PVRSRV_OK;
+}
+
+/******************************************************************************
+ End of file (sysconfig.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/system/rk3368/sysconfig.h b/drivers/gpu/rogue_m/system/rk3368/sysconfig.h
new file mode 100644 (file)
index 0000000..ef11fbc
--- /dev/null
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "pvrsrv_device.h"
+#include "rgxdevice.h"
+
+#if !defined(__SYSCCONFIG_H__)
+#define __SYSCCONFIG_H__
+
+//zxl:rk special data
+#define RGX_RK_CORE_CLOCK_SPEED (100*1000*1000)
+#define RGX_RK_SYSTEM_NAME "RGX RK"
+#define RK_GPU_PBASE        0xffa30000
+#define RK_GPU_SIZE         0x10000
+#define RK_IRQ_GPU          40
+
+#define SYS_RGX_ACTIVE_POWER_LATENCY_MS (100)
+
+/* default BIF tiling heap x-stride configurations. */
+static IMG_UINT32 gauiBIFTilingHeapXStrides[RGXFWIF_NUM_BIF_TILING_CONFIGS] =
+{
+       0, /* BIF tiling heap 1 x-stride */
+       1, /* BIF tiling heap 2 x-stride */
+       2, /* BIF tiling heap 3 x-stride */
+       3  /* BIF tiling heap 4 x-stride */
+};
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+#endif /* __SYSCCONFIG_H__ */
diff --git a/drivers/gpu/rogue_m/system/rk3368/sysinfo.h b/drivers/gpu/rogue_m/system/rk3368/sysinfo.h
new file mode 100644 (file)
index 0000000..b7efa09
--- /dev/null
@@ -0,0 +1,71 @@
+/*************************************************************************/ /*!
+@File
+@Title          System Description Header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    This header provides system-specific declarations and macros
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#define MAX_HW_TIME_US                           (500000)
+#define DEVICES_WATCHDOG_POWER_ON_SLEEP_TIMEOUT  (10000)
+#define DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT (3600000)
+#define WAIT_TRY_COUNT                           (10000)
+
+#define SYS_DEVICE_COUNT 3 /* RGX, DISPLAY (external), BUFFER (external) */
+
+#if defined(TDMETACODE)
+/* in systems that support trusted device address protection, there are three
+   physical heaps from which pages should be allocated:
+   - one heap for normal allocations
+   - one heap for allocations holding META code memory
+   - one heap for allocations holding secured DRM data
+*/
+#define SYS_PHYS_HEAP_COUNT            3
+#else
+#define SYS_PHYS_HEAP_COUNT            1
+#endif
+
+#if defined(__linux__)
+#define SYS_RGX_DEV_NAME    "rgxnohw"
+#endif
+
+#endif /* !defined(__SYSINFO_H__) */
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Kbuild.mk b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Kbuild.mk
new file mode 100644 (file)
index 0000000..95ccf09
--- /dev/null
@@ -0,0 +1,50 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ccflags-y += \
+       -I$(TOP)/tools/services/debug/dbgdriv/common \
+       -I$(TOP)/tools/services/debug/include
+
+dbgdrv-y += \
+       tools/services/debug/dbgdriv/common/dbgdriv.o \
+       tools/services/debug/dbgdriv/common/ioctl.o \
+       tools/services/debug/dbgdriv/common/handle.o \
+       tools/services/debug/dbgdriv/linux/main.o \
+       tools/services/debug/dbgdriv/linux/hostfunc.o
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Linux.mk b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/Linux.mk
new file mode 100644 (file)
index 0000000..e050879
--- /dev/null
@@ -0,0 +1,45 @@
+########################################################################### ###
+#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License       Dual MIT/GPLv2
+# 
+# The contents of this file are subject to the MIT license as set out below.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+# 
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+# 
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+# 
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := dbgdrv
+
+dbgdrv_type := kernel_module
+dbgdrv_target := dbgdrv.ko
+dbgdrv_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.c b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.c
new file mode 100644 (file)
index 0000000..3e93b70
--- /dev/null
@@ -0,0 +1,1572 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug Driver
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    32 Bit kernel mode debug driver
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(_WIN32)
+#pragma  warning(disable:4201)
+#pragma  warning(disable:4214)
+#pragma  warning(disable:4115)
+#pragma  warning(disable:4514)
+
+
+#include <ntddk.h>
+#include <windef.h>
+#include <winerror.h>
+#endif /* _WIN32 */
+
+#ifdef LINUX
+#include <linux/string.h>
+#endif
+
+#if defined (__QNXNTO__)
+#include <string.h>
+#endif
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "dbgdrvif_srv5.h"
+#include "dbgdriv.h"
+#include "hostfunc.h"
+
+#ifdef _WIN32
+#pragma  warning(default:4214)
+#pragma  warning(default:4115)
+#endif /* _WIN32 */
+
+
+/******************************************************************************
+ Types
+******************************************************************************/
+
+#define DBG_STREAM_NAME_MAX            30
+
+/*
+       Per-buffer control structure.
+*/
+typedef struct _DBG_STREAM_
+{
+       struct _DBG_STREAM_* psNext;
+       struct _DBG_STREAM_* psInitStream;
+       struct _DBG_STREAM_* psDeinitStream;
+       IMG_UINT32 ui32Flags;                   /*!< flags (see DEBUG_FLAGS) */
+       IMG_PVOID  pvBase;
+       IMG_UINT32 ui32Size;
+       IMG_UINT32 ui32RPtr;
+       IMG_UINT32 ui32WPtr;
+
+       IMG_UINT32 ui32Marker;                  /*!< Size marker for file splitting */
+
+       IMG_UINT32 ui32InitPhaseWOff;   /*!< snapshot offset for init phase end for follow-on pdump */
+
+       IMG_CHAR   szName[DBG_STREAM_NAME_MAX];                 /* Give this a size, some compilers don't like [] */
+} DBG_STREAM;
+
+/* Check 4xDBG_STREAM will fit in one page */
+BLD_ASSERT(sizeof(DBG_STREAM)<<2<HOST_PAGESIZE,dbgdriv_c)
+
+/******************************************************************************
+ Global variables
+******************************************************************************/
+
+static PDBG_STREAM          g_psStreamList = 0;
+
+/* Mutex used to prevent UM threads (via the dbgdrv ioctl interface) and KM
+ * threads (from pvrsrvkm via the ExtDBG API) entering the debug driver core
+ * and changing the state of share data at the same time.
+ */
+IMG_VOID *                  g_pvAPIMutex=IMG_NULL;
+
+static IMG_UINT32                      g_PDumpCurrentFrameNo = 0;
+
+DBGKM_SERVICE_TABLE g_sDBGKMServices =
+{
+       sizeof (DBGKM_SERVICE_TABLE),
+       ExtDBGDrivCreateStream,
+       ExtDBGDrivDestroyStream,
+       ExtDBGDrivWrite2,
+       ExtDBGDrivSetMarker,
+       ExtDBGDrivWaitForEvent,
+       ExtDBGDrivGetCtrlState,
+       ExtDBGDrivSetFrame
+};
+
+
+/***************************************************************************
+ Forward declarations
+***************************************************************************/
+
+IMG_BOOL   IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *pszName, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Pages, IMG_HANDLE* phInit, IMG_HANDLE* phMain, IMG_HANDLE* phDeinit);
+IMG_VOID   IMG_CALLCONV DBGDrivDestroyStream(IMG_HANDLE hInit,IMG_HANDLE hMain, IMG_HANDLE hDeinit);
+IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_UINT32 ui32BufID, 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_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize);
+IMG_VOID   IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetCtrlState(PDBG_STREAM psStream, IMG_UINT32 ui32StateID);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(void);
+IMG_VOID   IMG_CALLCONV DBGDrivSetFrame(IMG_UINT32 ui32Frame);
+IMG_VOID   DestroyAllStreams(IMG_VOID);
+
+/* Static function declarations */
+static IMG_UINT32 SpaceInStream(PDBG_STREAM psStream);
+static IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize);
+static IMG_VOID InvalidateAllStreams(IMG_VOID);
+
+
+/*****************************************************************************
+ Code
+*****************************************************************************/
+
+/*!
+ @name ExtDBGDrivCreateStream
+ */
+IMG_BOOL IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *pszName, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_HANDLE* phInit, IMG_HANDLE* phMain, IMG_HANDLE* phDeinit)
+{
+       IMG_BOOL pvRet;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       pvRet=DBGDrivCreateStream(pszName, ui32Flags, ui32Size, phInit, phMain, phDeinit);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return pvRet;
+}
+
+/*!
+ @name ExtDBGDrivDestroyStream
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivDestroyStream(IMG_HANDLE hInit,IMG_HANDLE hMain, IMG_HANDLE hDeinit)
+{
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       DBGDrivDestroyStream(hInit, hMain, hDeinit);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return;
+}
+
+/*!
+ @name ExtDBGDrivFindStream
+ */
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+       IMG_VOID *      pvRet;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       pvRet=DBGDrivFindStream(pszName, bResetStream);
+       if (pvRet == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "ExtDBGDrivFindStream: Stream not found"));
+       }
+
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return pvRet;
+}
+
+/*!
+ @name ExtDBGDrivRead
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_UINT32 ui32BufID, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+       IMG_UINT32 ui32Ret;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       ui32Ret=DBGDrivRead(psStream, ui32BufID, ui32OutBuffSize, pui8OutBuf);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivWrite2
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+       IMG_UINT32      ui32Ret;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivSetMarker
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       DBGDrivSetMarker(psStream, ui32Marker);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return;
+}
+
+/*!
+ @name ExtDBGDrivGetMarker
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream)
+{
+       IMG_UINT32      ui32Marker;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       ui32Marker = DBGDrivGetMarker(psStream);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return ui32Marker;
+}
+
+/*!
+ @name ExtDBGDrivWaitForEvent
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+       DBGDrivWaitForEvent(eEvent);
+#else  /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+       PVR_UNREFERENCED_PARAMETER(eEvent);                             /* PRQA S 3358 */
+#endif /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+}
+
+
+/*!
+ @name ExtDBGDrivGetCtrlState
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetCtrlState(PDBG_STREAM psStream, IMG_UINT32 ui32StateID)
+{
+       IMG_UINT32 ui32State = 0;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       ui32State = DBGDrivGetCtrlState(psStream, ui32StateID);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return ui32State;
+}
+
+/*!
+ @name ExtDBGDrivGetFrame
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(void)
+{
+       IMG_UINT32 ui32Frame = 0;
+
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       ui32Frame = DBGDrivGetFrame();
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return ui32Frame;
+}
+
+/*!
+ @name ExtDBGDrivGetCtrlState
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetFrame(IMG_UINT32 ui32Frame)
+{
+       /* Aquire API Mutex */
+       HostAquireMutex(g_pvAPIMutex);
+
+       DBGDrivSetFrame(ui32Frame);
+
+       /* Release API Mutex */
+       HostReleaseMutex(g_pvAPIMutex);
+
+       return;
+}
+
+
+
+/*!****************************************************************************
+ @name         AtoI
+ @brief                Returns the integer value of a decimal string
+ @param                szIn - String with hexadecimal value
+ @return       IMG_UINT32 integer value, 0 if string is null or not valid
+                               Based on Max`s one, now copes with (only) hex ui32ords, upper or lower case a-f.
+*****************************************************************************/
+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;
+
+       //get len of string
+       while (szIn[iLen] > 0)
+       {
+               iLen ++;
+       }
+
+       //nothing to do
+       if (iLen == 0)
+       {
+               return (0);
+       }
+
+       /* See if we have an 'x' or 'X' before the number to make it a hex number */
+       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';
+       }
+
+       //go through string from right (least significant) to left
+       for (iPos = iLen - 1; iPos >= 0; iPos --)
+       {
+               bc = szIn[iPos];
+
+               if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16)                      //handle lower case a-f
+               {
+                       bc -= 'a' - 0xa;
+               }
+               else
+               if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16)                      //handle upper case A-F
+               {
+                       bc -= 'A' - 0xa;
+               }
+               else
+               if ((bc >= '0') && (bc <= '9'))                         //if char out of range, return 0
+               {
+                       bc -= '0';
+               }
+               else
+                       return (0);
+
+               ui32Value += (IMG_UINT32)bc  * ui32Digit;
+
+               ui32Digit = ui32Digit * ui32Base;
+       }
+       return (ui32Value);
+}
+
+
+/*!****************************************************************************
+ @name         StreamValid
+ @brief                Validates supplied debug buffer.
+ @param                psStream - debug stream
+ @return       true if valid
+*****************************************************************************/
+static IMG_BOOL StreamValid(PDBG_STREAM psStream)
+{
+       PDBG_STREAM     psThis;
+
+       psThis = g_psStreamList;
+
+       while (psThis)
+       {
+               if (psStream && ((psThis == psStream) ||
+                                               (psThis->psInitStream == psStream) ||
+                                               (psThis->psDeinitStream == psStream)) )
+               {
+                       return(IMG_TRUE);
+               }
+               else
+               {
+                       psThis = psThis->psNext;
+               }
+       }
+
+       return(IMG_FALSE);
+}
+
+
+/*!****************************************************************************
+ @name         StreamValidForRead
+ @brief                Validates supplied debug buffer for read op.
+ @param                psStream - debug stream
+ @return       true if readable
+*****************************************************************************/
+static IMG_BOOL StreamValidForRead(PDBG_STREAM psStream)
+{
+       if( StreamValid(psStream) &&
+               ((psStream->ui32Flags & DEBUG_FLAGS_WRITEONLY) == 0) )
+       {
+               return(IMG_TRUE);
+       }
+
+       return(IMG_FALSE);
+}
+
+/*!****************************************************************************
+ @name         StreamValidForWrite
+ @brief                Validates supplied debug buffer for write op.
+ @param                psStream - debug stream
+ @return       true if writable
+*****************************************************************************/
+static IMG_BOOL StreamValidForWrite(PDBG_STREAM psStream)
+{
+       if( StreamValid(psStream) &&
+               ((psStream->ui32Flags & DEBUG_FLAGS_READONLY) == 0) )
+       {
+               return(IMG_TRUE);
+       }
+
+       return(IMG_FALSE);
+}
+
+/*!****************************************************************************
+ @name         Write
+ @brief                Copies data from a buffer into selected stream. Stream size is fixed.
+ @param                psStream - stream for output
+ @param                pui8Data - input buffer
+ @param                ui32InBuffSize - size of input
+ @return       none
+*****************************************************************************/
+static IMG_VOID Write(PDBG_STREAM psStream,IMG_PUINT8 pui8Data,IMG_UINT32 ui32InBuffSize)
+{
+       /*
+               Split copy into two bits as necessary (if we're allowed to wrap).
+       */
+       if ((psStream->ui32Flags & DEBUG_FLAGS_CIRCULAR) == 0)
+       {
+               PVR_ASSERT( (psStream->ui32WPtr + ui32InBuffSize) < psStream->ui32Size );
+       }
+
+       if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size)
+       {
+               /* Yes we need two bits, calculate their sizes */
+               IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
+               IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1;
+
+               /* Copy first block to current location */
+               HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+                               (IMG_PVOID) pui8Data,
+                               ui32B1);
+
+               /* Copy second block to start of buffer */
+               HostMemCopy(psStream->pvBase,
+                               (IMG_PVOID)(pui8Data + ui32B1),
+                               ui32B2);
+
+               /* Set pointer to be the new end point */
+               psStream->ui32WPtr = ui32B2;
+       }
+       else
+       {       /* Can fit block in single chunk */
+               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;
+               }
+       }
+}
+
+
+/*!****************************************************************************
+ @name         WriteExpandingBuffer
+ @brief                Copies data from a buffer into selected stream. Stream size may be expandable.
+ @param                psStream - stream for output
+ @param                pui8InBuf - input buffer
+ @param                ui32InBuffSize - size of input
+ @return       bytes copied
+*****************************************************************************/
+static IMG_UINT32 WriteExpandingBuffer(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+       IMG_UINT ui32Space;
+
+       /*
+               How much space have we got in the buffer ?
+       */
+       ui32Space = SpaceInStream(psStream);
+
+       /*
+               Check if we can expand the buffer 
+       */
+       if (psStream->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION)
+       {
+               /*
+                       Don't do anything if we've got less that 32 ui8tes of space and
+                       we're not allowing expansion of buffer space...
+               */
+               if (ui32Space < 32)
+               {
+                       PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %p is full and isn't expandable", psStream));
+                       return(0);
+               }
+       }
+       else
+       {
+               if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4)))
+               {
+                       IMG_UINT32      ui32NewBufSize;
+
+                       /*
+                               Find new buffer size, double the current size or increase by 1MB
+                       */
+                       ui32NewBufSize = MIN(psStream->ui32Size<<1,psStream->ui32Size+(1<<20));
+                       ui32NewBufSize = MIN(ui32NewBufSize, (PDUMP_STREAMBUF_MAX_SIZE_MB<<20));
+
+                       PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanding buffer size = %x, new size = %x",
+                                       psStream->ui32Size, ui32NewBufSize));
+
+                       if (ui32InBuffSize > psStream->ui32Size)
+                       {
+                               ui32NewBufSize += ui32InBuffSize;
+                               PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %p is expanding by size of input buffer %u", psStream, ui32NewBufSize));
+                       }
+
+                       /* 
+                               Attempt to expand the buffer 
+                       */
+                       if ((ui32NewBufSize < psStream->ui32Size) ||
+                                       !ExpandStreamBuffer(psStream,ui32NewBufSize))
+                       {
+                               if (ui32Space < 32)
+                               {
+                                       if((psStream->ui32Flags & DEBUG_FLAGS_CIRCULAR) != 0)
+                                       {
+                                               return(0);
+                                       }
+                                       else
+                                       {
+                                               /* out of memory */
+                                               PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: Unable to expand %p. Out of memory.", psStream));
+                                               InvalidateAllStreams();
+                                               return (0xFFFFFFFFUL);
+                                       }
+                               }
+                       }
+
+                       /* 
+                               Recalc the space in the buffer 
+                       */
+                       ui32Space = SpaceInStream(psStream);
+                       PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanded buffer, free space = %x",
+                                       ui32Space));
+               }
+       }
+
+       /*
+               Only copy what we can..
+       */
+       if (ui32Space <= (ui32InBuffSize + 4))
+       {
+               ui32InBuffSize = ui32Space - 4;
+       }
+
+       /*
+               Write the stuff...
+       */
+       Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+       if (ui32InBuffSize)
+       {
+               HostSignalEvent(DBG_EVENT_STREAM_DATA);
+       }
+#endif
+       return(ui32InBuffSize);
+}
+
+/*****************************************************************************
+******************************************************************************
+******************************************************************************
+ THE ACTUAL FUNCTIONS
+******************************************************************************
+******************************************************************************
+*****************************************************************************/
+
+static IMG_VOID DBGDrivSetStreamName(PDBG_STREAM psStream,
+                                                                        IMG_CHAR* pszBase,
+                                                                        IMG_CHAR* pszExt)
+{
+       IMG_CHAR* pCh = psStream->szName;
+       IMG_CHAR* pChEnd = psStream->szName+DBG_STREAM_NAME_MAX-8;
+       IMG_CHAR* pSrcCh;
+       IMG_CHAR* pSrcChEnd;
+
+       for (pSrcCh = pszBase, pSrcChEnd = pszBase+strlen(pszBase);
+                       (pSrcCh < pSrcChEnd) && (pCh < pChEnd) ;
+                       pSrcCh++, pCh++)
+       {
+               *pCh = *pSrcCh;
+       }
+
+       for (pSrcCh = pszExt, pSrcChEnd = pszExt+strlen(pszExt);
+                       (pSrcCh < pSrcChEnd) && (pCh < pChEnd) ;
+                       pSrcCh++, pCh++)
+       {
+               *pCh = *pSrcCh;
+       }
+
+       *pCh = '\0';
+}
+
+/*!****************************************************************************
+ @name         DBGDrivCreateStream
+ @brief                Creates a pdump/debug stream
+ @param                pszName - stream name
+ @param                ui32Flags - output flags, text stream bit is set for pdumping
+ @param                ui32Size - size of stream buffer in pages
+ @return       none
+*****************************************************************************/
+IMG_BOOL IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *pszName,
+                                          IMG_UINT32 ui32Flags,
+                                          IMG_UINT32 ui32Size,
+                                          IMG_HANDLE* phInit,
+                                          IMG_HANDLE* phMain,
+                                          IMG_HANDLE* phDeinit)
+{
+       IMG_BOOL            bUseNonPagedMem4Buffers = ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0);
+       PDBG_STREAM         psStream = IMG_NULL;
+       PDBG_STREAM             psInitStream = IMG_NULL;
+       PDBG_STREAM         psStreamDeinit = IMG_NULL;
+       IMG_VOID*           pvBase = IMG_NULL;
+
+       /*
+               If we already have a buffer using this name just return
+               its handle.
+       */
+       psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE);
+       if (psStream)
+       {
+               *phInit = psStream->psInitStream;
+               *phMain = psStream;
+               *phDeinit = psStream->psDeinitStream;
+               return IMG_TRUE;
+       }
+
+       /*
+               Allocate memory for control structures
+       */
+       psStream = HostNonPageablePageAlloc(1);
+       if      (!psStream)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc control structs\n\r"));
+               goto errCleanup;
+       }
+       psInitStream = psStream+1;
+       psStreamDeinit = psStream+2;
+
+
+       /* Allocate memory for Main buffer */
+       psStream->pvBase = IMG_NULL;
+       if (bUseNonPagedMem4Buffers)
+       {
+               pvBase = HostNonPageablePageAlloc(ui32Size);
+       }
+       else
+       {
+               pvBase = HostPageablePageAlloc(ui32Size);
+       }
+
+       if (!pvBase)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc Stream buffer\n\r"));
+               goto errCleanup;
+       }
+
+       /*
+               Setup debug buffer state.
+       */
+       psStream->psNext = 0;
+       psStream->pvBase = pvBase;
+       psStream->ui32Flags = ui32Flags | DEBUG_FLAGS_CIRCULAR;
+       psStream->ui32Size = ui32Size * HOST_PAGESIZE;
+       psStream->ui32RPtr = 0;
+       psStream->ui32WPtr = 0;
+       psStream->ui32Marker = 0;
+       psStream->ui32InitPhaseWOff = 0;
+       DBGDrivSetStreamName(psStream, pszName, "");
+       PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Created stream with deinit name (%s)\n\r", psStream->szName));
+
+       /* Allocate memory for Init buffer */
+       psInitStream->pvBase = IMG_NULL;
+       if (bUseNonPagedMem4Buffers)
+       {
+               pvBase = HostNonPageablePageAlloc(ui32Size);
+       }
+       else
+       {
+               pvBase = HostPageablePageAlloc(ui32Size);
+       }
+
+       if (!pvBase)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc InitStream buffer\n\r"));
+               goto errCleanup;
+       }
+
+       /* Initialise the stream for the Init phase */
+       psInitStream->psNext = psInitStream->psInitStream = psInitStream->psDeinitStream = IMG_NULL;
+       psInitStream->ui32Flags = ui32Flags;
+       psInitStream->pvBase = pvBase;
+       psInitStream->ui32Size = ui32Size * HOST_PAGESIZE;
+       psInitStream->ui32RPtr = 0;
+       psInitStream->ui32WPtr = 0;
+       psInitStream->ui32Marker = 0;
+       psInitStream->ui32InitPhaseWOff = 0;
+       DBGDrivSetStreamName(psInitStream, pszName, "_Init");
+       PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Created stream with init name (%s)\n\r", psInitStream->szName));
+       psStream->psInitStream = psInitStream;
+
+       /* Allocate memory for Deinit buffer */
+       psStreamDeinit->pvBase = IMG_NULL;
+       if (bUseNonPagedMem4Buffers)
+       {
+               pvBase = HostNonPageablePageAlloc(1);
+       }
+       else
+       {
+               pvBase = HostPageablePageAlloc(1);
+       }
+
+       if (!pvBase)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc DeinitStream buffer\n\r"));
+               goto errCleanup;
+       }
+
+       /* Initialise the stream for the Deinit phase */
+       psStreamDeinit->psNext = psStreamDeinit->psInitStream = psStreamDeinit->psDeinitStream = IMG_NULL;
+       psStreamDeinit->pvBase = pvBase;
+       psStreamDeinit->ui32Flags = ui32Flags;
+       psStreamDeinit->ui32Size = HOST_PAGESIZE;
+       psStreamDeinit->ui32RPtr = 0;
+       psStreamDeinit->ui32WPtr = 0;
+       psStreamDeinit->ui32Marker = 0;
+       psStreamDeinit->ui32InitPhaseWOff = 0;
+       DBGDrivSetStreamName(psStreamDeinit, pszName, "_Deinit");
+       PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Created stream with deinit name (%s)\n\r", psStreamDeinit->szName));
+
+       psStream->psDeinitStream = psStreamDeinit;
+
+       /*
+               Insert into list.
+       */
+       psStream->psNext = g_psStreamList;
+       g_psStreamList = psStream;
+
+       AddSIDEntry(psStream);
+       
+       *phInit = psStream->psInitStream;
+       *phMain = psStream;
+       *phDeinit = psStream->psDeinitStream;
+
+       return IMG_TRUE;
+
+errCleanup:
+       if (bUseNonPagedMem4Buffers)
+       {
+               if (psStream) HostNonPageablePageFree(psStream->pvBase);
+               if (psInitStream) HostNonPageablePageFree(psInitStream->pvBase);
+               if (psStreamDeinit) HostNonPageablePageFree(psStreamDeinit->pvBase);
+       }
+       else
+       {
+               if (psStream) HostPageablePageFree(psStream->pvBase);
+               if (psInitStream) HostPageablePageFree(psInitStream->pvBase);
+               if (psStreamDeinit) HostPageablePageFree(psStreamDeinit->pvBase);
+       }
+       HostNonPageablePageFree(psStream);
+       psStream = psInitStream = psStreamDeinit = IMG_NULL;
+       return IMG_FALSE;
+}
+
+/*!****************************************************************************
+ @name         DBGDrivDestroyStream
+ @brief                Delete a stream and free its memory
+ @param                psStream - stream to be removed
+ @return       none
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivDestroyStream(IMG_HANDLE hInit,IMG_HANDLE hMain, IMG_HANDLE hDeinit)
+{
+       PDBG_STREAM psStreamInit = (PDBG_STREAM) hInit;
+       PDBG_STREAM psStream = (PDBG_STREAM) hMain;
+       PDBG_STREAM     psStreamDeinit = (PDBG_STREAM) hDeinit;
+       PDBG_STREAM     psStreamThis;
+       PDBG_STREAM     psStreamPrev;
+
+       PVR_DPF((PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n", psStream->szName ));
+
+       /*
+               Validate buffer.
+       */
+       if (!StreamValid(psStream))
+       {
+               return;
+       }
+
+       RemoveSIDEntry(psStream);
+       
+       /*
+               Remove from linked list.
+       */
+       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;
+               }
+       }
+
+       /*
+               And free its memory.
+       */
+       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+       {
+               HostNonPageablePageFree(psStream->pvBase);
+               HostNonPageablePageFree(psStreamInit->pvBase);
+               HostNonPageablePageFree(psStreamDeinit->pvBase);
+       }
+       else
+       {
+               HostPageablePageFree(psStream->pvBase);
+               HostPageablePageFree(psStreamInit->pvBase);
+               HostPageablePageFree(psStreamDeinit->pvBase);
+       }
+
+       /* Free the shared page used for the three stream tuple */
+       HostNonPageablePageFree(psStream);
+       psStream = psStreamInit = psStreamDeinit = IMG_NULL;
+
+       if (g_psStreamList == 0)
+       {
+               PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" ));
+       }
+
+       return;
+}
+
+/*!****************************************************************************
+ @name         DBGDrivFindStream
+ @brief                Finds/resets a named stream
+ @param                pszName - stream name
+ @param                bResetStream - whether to reset the stream, e.g. to end pdump init phase
+ @return       none
+*****************************************************************************/
+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"));
+
+       /*
+               Scan buffer names for supplied one.
+       */
+       for (psThis = g_psStreamList; psThis != IMG_NULL; psThis = psThis->psNext)
+       {
+               bAreSame = IMG_TRUE;
+               ui32Off = 0;
+
+               if (strlen(psThis->szName) == strlen(pszName))
+               {
+                       while ((ui32Off < DBG_STREAM_NAME_MAX) && (psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && bAreSame)
+                       {
+                               if (psThis->szName[ui32Off] != pszName[ui32Off])
+                               {
+                                       bAreSame = IMG_FALSE;
+                               }
+
+                               ui32Off++;
+                       }
+               }
+               else
+               {
+                       bAreSame = IMG_FALSE;
+               }
+
+               if (bAreSame)
+               {
+                       psStream = psThis;
+                       break;
+               }
+       }
+
+       if(psStream)
+       {
+               psStream->psInitStream->ui32RPtr = 0;
+               psStream->psDeinitStream->ui32RPtr = 0;
+               psStream->ui32RPtr = 0;
+               if (bResetStream)
+               {
+                       /* This will erase any data written to the main stream 
+                        * before the client starts. */
+                       psStream->ui32WPtr = 0;
+               }
+               psStream->ui32Marker = psStream->psInitStream->ui32Marker = 0;
+
+
+               /* mark init stream to prevent further reading by pdump client */
+               /* Check for possible race condition */
+               psStream->psInitStream->ui32InitPhaseWOff = psStream->psInitStream->ui32WPtr;
+
+               PVR_DPF((PVR_DBGDRIV_MESSAGE, "Set %s client marker bo %x",
+                               psStream->szName,
+                               psStream->psInitStream->ui32InitPhaseWOff));
+       }
+
+       return((IMG_VOID *) psStream);
+}
+
+static IMG_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", psStream->szName ));
+
+       /*
+               Validate buffer.
+       */
+       /*
+       if (!StreamValid(psStream))
+       {
+               return;
+       }
+*/
+       /* Write what we can of the error message */
+       ui32Space = SpaceInStream(psStream);
+
+       /* Make sure there's space for termination character */
+       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;
+
+       /* Buffer will accept no more params from Services/client driver */
+       psStream->ui32Flags |= DEBUG_FLAGS_READONLY;
+}
+
+/*!****************************************************************************
+ @name         InvalidateAllStreams
+ @brief                invalidate all streams in list
+ @return       none
+*****************************************************************************/
+static IMG_VOID InvalidateAllStreams(IMG_VOID)
+{
+       PDBG_STREAM psStream = g_psStreamList;
+       while (psStream != IMG_NULL)
+       {
+               DBGDrivInvalidateStream(psStream);
+               DBGDrivInvalidateStream(psStream->psInitStream);
+               DBGDrivInvalidateStream(psStream->psDeinitStream);
+               psStream = psStream->psNext;
+       }
+       return;
+}
+
+/*!****************************************************************************
+ @name         DBGDrivWrite2
+ @brief                Copies data from a buffer into selected (expandable) stream.
+ @param                psStream - stream for output
+ @param                pui8InBuf - input buffer
+ @param                ui32InBuffSize - size of input
+ @return       bytes copied, 0 if recoverable error, -1 if unrecoverable error
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+
+       /*
+               Validate buffer.
+       */
+       if (!StreamValidForWrite(psStream))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite2: stream not valid"));
+               return(0xFFFFFFFFUL);
+       }
+
+       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) );
+}
+
+/*!****************************************************************************
+ @name         DBGDrivRead
+ @brief                Read from debug driver buffers
+ @param                psMainStream - stream
+ @param                ui32BufID - on of the DEBUG_READ_BUFID flags to indicate which buffer
+ @param                ui32OutBuffSize - available space in client buffer
+ @param                pui8OutBuf - output buffer
+ @return       bytes read, 0 if failure occurred
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_UINT32 ui32BufID, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+       IMG_UINT32 ui32Data;
+       DBG_STREAM *psStream;
+
+       /*
+               Validate buffer.
+       */
+       if (!StreamValidForRead(psMainStream))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DBGDrivRead: buffer %p is invalid", psMainStream));
+               return(0);
+       }
+
+       if(ui32BufID == DEBUG_READ_BUFID_INIT)
+       {
+               psStream = psMainStream->psInitStream;
+       }
+       else if (ui32BufID == DEBUG_READ_BUFID_DEINIT)
+       {
+               psStream = psMainStream->psDeinitStream;
+       }
+       else
+       {
+               psStream = psMainStream;
+       }
+
+       /* Don't read beyond the init phase marker point */
+       if (psStream->ui32RPtr == psStream->ui32WPtr ||
+               ((psStream->ui32InitPhaseWOff > 0) &&
+                (psStream->ui32RPtr >= psStream->ui32InitPhaseWOff)) )
+       {
+               return(0);
+       }
+
+       /*
+               Get amount of data in buffer.
+       */
+       if (psStream->ui32RPtr <= psStream->ui32WPtr)
+       {
+               ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
+       }
+       else
+       {
+               ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr);
+       }
+
+       /*
+               Don't read beyond the init phase marker point
+       */
+       if ((psStream->ui32InitPhaseWOff > 0) &&
+               (psStream->ui32InitPhaseWOff < psStream->ui32WPtr))
+       {
+               ui32Data = psStream->ui32InitPhaseWOff - psStream->ui32RPtr;
+       }
+
+       /*
+               Only transfer what target buffer can handle.
+       */
+       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));
+
+       /*
+               Split copy into two bits or one depending on W/R position.
+       */
+       if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size)
+       {       /* Calc block 1 and block 2 sizes */
+               IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
+               IMG_UINT32 ui32B2 = ui32Data - ui32B1;
+
+               /* Copy up to end of circular buffer */
+               HostMemCopy((IMG_VOID *) pui8OutBuf,
+                               (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+                               ui32B1);
+
+               /* Copy from start of circular buffer */
+               HostMemCopy((IMG_VOID *)(pui8OutBuf + ui32B1),
+                               psStream->pvBase,
+                               ui32B2);
+
+               /* Update read pointer now that we've copied the data out */
+               psStream->ui32RPtr = ui32B2;
+       }
+       else
+       {       /* Copy data from wherever */
+               HostMemCopy((IMG_VOID *) pui8OutBuf,
+                               (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+                               ui32Data);
+
+               /* Update read pointer now that we've copied the data out */
+               psStream->ui32RPtr += ui32Data;
+
+               /* Check for wrapping */
+               if ((psStream->ui32RPtr != psStream->ui32WPtr) &&
+                       (psStream->ui32RPtr >= psStream->ui32Size))
+               {
+                       psStream->ui32RPtr = 0;
+               }
+       }
+
+       return(ui32Data);
+}
+
+/*!****************************************************************************
+ @name         DBGDrivSetMarker
+ @brief                Sets the marker in the stream to split output files
+ @param                psStream, ui32Marker
+ @return       nothing
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+       /*
+               Validate buffer
+       */
+       if (!StreamValid(psStream))
+       {
+               return;
+       }
+
+       /* Called by PDump client to reset the marker to zero after a file split */
+       if ((ui32Marker == 0) && (psStream->ui32Marker == 0))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "DBGDrivSetMarker: Client resetting marker that is already zero!"));
+       }
+       /* Called by pvrsrvkm to set the marker to signal a file split is required */
+       if ((ui32Marker != 0) && (psStream->ui32Marker != 0))
+       {
+               /* In this case a previous split request is still outstanding. The
+                * client has not yet actioned and acknowledged the previous
+                * marker. This may be an error if the client does not catch-up and
+                * the stream's written data is allowed to pass the max file
+                * size again. If this happens the PDump is invalid as the offsets
+                * from the script file will be incorrect.
+                */
+               PVR_DPF((PVR_DBG_ERROR, "DBGDrivSetMarker: Server setting marker that is already set!"));
+       }
+       else
+       {
+               PVR_DPF((PVR_DBG_MESSAGE, "DBGDrivSetMarker: Setting stream split marker to %d (was %d)", ui32Marker, psStream->ui32Marker));
+       }
+
+       psStream->ui32Marker = ui32Marker;
+}
+
+/*!****************************************************************************
+ @name         DBGDrivGetMarker
+ @brief        Gets the marker in the stream to split output files
+ @param                psStream - stream
+ @return       marker offset
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream)
+{
+       /*
+               Validate buffer
+       */
+       if (!StreamValid(psStream))
+       {
+               return 0;
+       }
+
+       return psStream->ui32Marker;
+}
+
+/*!****************************************************************************
+ @name         DBGDrivGetServiceTable
+ @brief                get jump table for Services driver
+ @return       pointer to jump table
+*****************************************************************************/
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID)
+{
+       return((IMG_PVOID)&g_sDBGKMServices);
+}
+
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+/*!****************************************************************************
+ @name         DBGDrivWaitForEvent
+ @brief                waits for an event
+ @param                eEvent - debug driver event
+ @return       IMG_VOID
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+       HostWaitForEvent(eEvent);
+}
+#endif
+
+/*     Use PVR_DPF() to avoid state messages in release build */
+#if defined(PVR_DISABLE_LOGGING) || !defined(DEBUG)
+#define PVR_LOG(...)
+#else
+
+extern IMG_VOID PVRSRVDebugPrintf(IMG_UINT32   ui32DebugLevel,
+                                               const IMG_CHAR* pszFileName,
+                                               IMG_UINT32      ui32Line,
+                                               const IMG_CHAR* pszFormat,
+                                               ...     );
+/* Reproduce the PVR_LOG macro here but direct it to DPF */
+#define PVR_LOG(...)   PVRSRVDebugPrintf( DBGPRIV_CALLTRACE, __FILE__, __LINE__ , __VA_ARGS__);
+
+#endif
+
+
+/*!****************************************************************************
+ @name         DBGDrivGetCtrlState
+ @brief                Gets a state value from the debug driver or stream
+ @param                psStream - stream
+ @param                ui32StateID - state ID
+ @return       Nothing
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivGetCtrlState(PDBG_STREAM psStream, IMG_UINT32 ui32StateID)
+{
+       /* Validate buffer */
+       if (!StreamValid(psStream))
+       {
+               return (0xFFFFFFFF);
+       }
+
+       /* Retrieve the state asked for */
+       switch (ui32StateID)
+       {
+       case DBG_GET_STATE_FLAG_IS_READONLY:
+               return ((psStream->ui32Flags & DEBUG_FLAGS_READONLY) != 0);
+               break;
+
+       case 0xFE: /* Dump the current stream state */
+               PVR_LOG("------ PDUMP DBGDriv: psStream( %p ) ( -- %s -- ) ui32Flags( %x )",
+                               psStream, psStream->szName, psStream->ui32Flags);
+               PVR_LOG("------ PDUMP DBGDriv: psStream->pvBase( %p ) psStream->ui32Size( %u )",
+                               psStream->pvBase, psStream->ui32Size);
+               PVR_LOG("------ PDUMP DBGDriv: psStream->ui32RPtr( %u ) psStream->ui32WPtr( %u )",
+                               psStream->ui32RPtr, psStream->ui32WPtr);
+               PVR_LOG("------ PDUMP DBGDriv: psStream->ui32Marker( %u ) psStream->ui32InitPhaseWOff( %u )",
+                               psStream->ui32Marker, psStream->ui32InitPhaseWOff);
+               if (psStream->psInitStream)
+               {
+                       PVR_LOG("-------- PDUMP DBGDriv: psInitStream( %p ) ( -- %s -- ) ui32Flags( %x )",
+                                       psStream->psInitStream, psStream->psInitStream->szName, psStream->ui32Flags);
+                       PVR_LOG("-------- PDUMP DBGDriv: psInitStream->pvBase( %p ) psInitStream->ui32Size( %u )",
+                                       psStream->psInitStream->pvBase, psStream->psInitStream->ui32Size);
+                       PVR_LOG("-------- PDUMP DBGDriv: psInitStream->ui32RPtr( %u ) psInitStream->ui32WPtr( %u )",
+                                       psStream->psInitStream->ui32RPtr, psStream->psInitStream->ui32WPtr);
+                       PVR_LOG("-------- PDUMP DBGDriv: psInitStream->ui32Marker( %u ) psInitStream->ui32InitPhaseWOff( %u ) ",
+                                       psStream->psInitStream->ui32Marker, psStream->psInitStream->ui32InitPhaseWOff);
+               }
+
+               break;
+
+       case 0xFF: /* Dump driver state not in a stream */
+               {
+                       PVR_LOG("------ PDUMP DBGDriv: g_psStreamList( head %p ) g_pvAPIMutex( %p ) g_PDumpCurrentFrameNo( %u )", g_psStreamList, g_pvAPIMutex, g_PDumpCurrentFrameNo);
+               }
+               break;
+
+       default:
+               PVR_ASSERT(0);
+       }
+
+       return (0xFFFFFFFF);
+}
+
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(void)
+{
+       return g_PDumpCurrentFrameNo;
+}
+
+IMG_VOID IMG_CALLCONV DBGDrivSetFrame(IMG_UINT32 ui32Frame)
+{
+       g_PDumpCurrentFrameNo = ui32Frame;
+}
+
+
+/*!****************************************************************************
+ @name         ExpandStreamBuffer
+ @brief                allocates a new buffer when the current one is full
+ @param                psStream - stream
+ @param                ui32NewSize - new size
+ @return       IMG_TRUE - if allocation succeeded, IMG_FALSE - if not
+*****************************************************************************/
+static IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize)
+{
+       IMG_VOID *      pvNewBuf;
+       IMG_UINT32      ui32NewSizeInPages;
+       IMG_UINT32      ui32NewWOffset;
+       IMG_UINT32      ui32NewROffset;
+       IMG_UINT32      ui32SpaceInOldBuf;
+
+       /* 
+               First check new size is bigger than existing size 
+       */
+       if (psStream->ui32Size >= ui32NewSize)
+       {
+               return IMG_FALSE;
+       }
+
+       /*
+               Calc space in old buffer 
+       */
+       ui32SpaceInOldBuf = SpaceInStream(psStream);
+
+       /*
+               Allocate new buffer 
+       */
+       ui32NewSizeInPages = ((ui32NewSize + 0xfffUL) & ~0xfffUL) / 4096UL;
+
+       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+       {
+               pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
+       }
+       else
+       {
+               pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
+       }
+
+       if (pvNewBuf == IMG_NULL)
+       {
+               return IMG_FALSE;
+       }
+
+       if ((psStream->ui32Flags & DEBUG_FLAGS_CIRCULAR) != 0)
+       {
+               /*
+                       Copy over old buffer to new one, we place data at start of buffer
+                       even if Read offset is not at start of buffer
+               */
+               if (psStream->ui32RPtr <= psStream->ui32WPtr)
+               {
+                       /*
+                               No wrapping of data so copy data to start of new buffer 
+                       */
+               HostMemCopy(pvNewBuf,
+                                       (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+                                       psStream->ui32WPtr - psStream->ui32RPtr);
+               }
+               else
+               {
+                       IMG_UINT32      ui32FirstCopySize;
+       
+                       /*
+                               The data has wrapped around the buffer, copy beginning of buffer first 
+                       */
+                       ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
+       
+                       HostMemCopy(pvNewBuf,
+                                       (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+                                       ui32FirstCopySize);
+       
+                       /*
+                               Now second half 
+                       */
+                       HostMemCopy((IMG_VOID *)((IMG_UINTPTR_T)pvNewBuf + ui32FirstCopySize),
+                                       (IMG_VOID *)(IMG_PBYTE)psStream->pvBase,
+                                       psStream->ui32WPtr);
+               }
+               ui32NewROffset = 0;
+       }
+       else
+       {
+               /* Copy everything in the old buffer to the new one */
+               HostMemCopy(pvNewBuf, psStream->pvBase, psStream->ui32WPtr);
+               ui32NewROffset = psStream->ui32RPtr;
+       }
+
+       /*
+               New Write offset is at end of data 
+       */                                                        
+       ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
+
+       /*
+               Free old buffer 
+       */
+       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+       {
+               HostNonPageablePageFree(psStream->pvBase);
+       }
+       else
+       {
+               HostPageablePageFree(psStream->pvBase);
+       }
+
+       /*
+               Now set new params up 
+       */
+       psStream->pvBase = pvNewBuf;
+       psStream->ui32RPtr = ui32NewROffset;
+       psStream->ui32WPtr = ui32NewWOffset;
+       psStream->ui32Size = ui32NewSizeInPages * 4096;
+
+       return IMG_TRUE;
+}
+
+/*!****************************************************************************
+ @name         SpaceInStream
+ @brief                remaining space in stream
+ @param                psStream - stream
+ @return       bytes remaining
+*****************************************************************************/
+static IMG_UINT32 SpaceInStream(PDBG_STREAM psStream)
+{
+       IMG_UINT32      ui32Space;
+
+       if ((psStream->ui32Flags & DEBUG_FLAGS_CIRCULAR) != 0)
+       {
+               /* Allow overwriting the buffer which was already read */
+               if (psStream->ui32RPtr > psStream->ui32WPtr)
+               {
+                       ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
+               }
+               else
+               {
+                       ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr);
+               }
+       }
+       else
+       {
+               /* Don't overwrite anything */
+               ui32Space = psStream->ui32Size - psStream->ui32WPtr;
+       }
+
+       return ui32Space;
+}
+
+
+/*!****************************************************************************
+ @name         DestroyAllStreams
+ @brief                delete all streams in list
+ @return       none
+*****************************************************************************/
+IMG_VOID DestroyAllStreams(IMG_VOID)
+{
+       PDBG_STREAM psStream = g_psStreamList;
+       PDBG_STREAM psStreamToFree;
+
+       while (psStream != IMG_NULL)
+       {
+               psStreamToFree = psStream;
+               psStream = psStream->psNext;
+               DBGDrivDestroyStream(psStreamToFree->psInitStream, psStreamToFree, psStreamToFree->psDeinitStream);
+       }
+       g_psStreamList = IMG_NULL;
+       return;
+}
+
+/******************************************************************************
+ End of file (DBGDRIV.C)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.h b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv.h
new file mode 100644 (file)
index 0000000..6649e5c
--- /dev/null
@@ -0,0 +1,114 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DBGDRIV_
+#define _DBGDRIV_
+
+/*****************************************************************************
+ The odd constant or two
+*****************************************************************************/
+
+#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;
+
+/*****************************************************************************
+ Internal debug driver core functions
+*****************************************************************************/
+/* Called by WDDM debug driver win7/hostfunc.c */
+IMG_BOOL IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *pszName, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Pages,
+                                                                                       IMG_HANDLE* phInit, IMG_HANDLE* phMain, IMG_HANDLE* phDeinit);
+
+/* Called by Linux debug driver main.c to allow the API mutex lock to be used
+ * to protect the common IOCTL read buffer while avoiding deadlock in the Ext
+ * layer
+ */
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_UINT32 ui32BufID,
+                                                                       IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
+
+/* Used in ioctl.c in DBGDIOCDrivGetServiceTable() which is called in WDDM PDump files */
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID);
+
+/* Used in WDDM version of debug driver win7/main.c */
+IMG_VOID DestroyAllStreams(IMG_VOID);
+
+/*****************************************************************************
+ Function prototypes
+*****************************************************************************/
+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);
+
+/*****************************************************************************
+ Secure handle Function prototypes
+*****************************************************************************/
+IMG_SID PStream2SID(PDBG_STREAM psStream);
+PDBG_STREAM SID2PStream(IMG_SID hStream); 
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream);
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream);
+
+/*****************************************************************************
+ Declarations for IOCTL Service table and KM table entry points
+*****************************************************************************/
+IMG_BOOL   IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *pszName, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_HANDLE* phInit, IMG_HANDLE* phMain, IMG_HANDLE* phDeinit);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivDestroyStream(IMG_HANDLE hInit, IMG_HANDLE hMain, IMG_HANDLE hDeinit);
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_UINT32 ui32BufID, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 *pui8OutBuf);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetCtrlState(PDBG_STREAM psStream, IMG_UINT32 ui32StateID);
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(void);
+IMG_VOID   IMG_CALLCONV ExtDBGDrivSetFrame(IMG_UINT32 ui32Frame);
+
+#endif
+
+/*****************************************************************************
+ End of file (DBGDRIV.H)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv_ioctl.h b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/dbgdriv_ioctl.h
new file mode 100644 (file)
index 0000000..bce7b96
--- /dev/null
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DBGDRIV_IOCTL_H_
+#define _DBGDRIV_IOCTL_H_
+
+#include "dbgdrvif_srv5.h"
+
+
+/* Share this debug driver global with the OS layer so that IOCTL calls
+ * coming from the OS enter the common table of entry points.
+ */
+extern IMG_UINT32 (*g_DBGDrivProc[DEBUG_SERVICE_MAX_API])(IMG_VOID *, IMG_VOID *, IMG_BOOL);
+
+
+#endif /* _DBGDRIV_IOCTL_H_ */
+
+/*****************************************************************************
+ End of file
+ *****************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/handle.c b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/handle.c
new file mode 100644 (file)
index 0000000..af54eee
--- /dev/null
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@File
+@Title          Resource Handle Manager
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Provide resource handle management
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "img_defs.h"
+#include "dbgdrvif_srv5.h"
+#include "dbgdriv.h"
+
+/* max number of streams held in SID info table */
+#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)
+                       {
+                               /* idx is one based */
+                               return (IMG_SID)iIdx+1;
+                       }
+               }
+       }
+
+       return (IMG_SID)0;
+}
+
+
+PDBG_STREAM SID2PStream(IMG_SID hStream)
+{
+       /* changed to zero based */
+       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)
+                       {
+                               /* already created */
+                               return IMG_TRUE;
+                       }
+
+                       if (gaSID_Xlat_Table[iIdx].psStream == (PDBG_STREAM)IMG_NULL)
+                       {
+                               /* free entry */
+                               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;
+}
+
+
+/******************************************************************************
+ End of file (handle.c)
+******************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/hostfunc.h b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/hostfunc.h
new file mode 100644 (file)
index 0000000..096bc3d
--- /dev/null
@@ -0,0 +1,102 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _HOSTFUNC_
+#define _HOSTFUNC_
+
+/*****************************************************************************
+ Defines
+*****************************************************************************/
+#define HOST_PAGESIZE                  (4096)
+#define DBG_MEMORY_INITIALIZER (0xe2)
+
+/*****************************************************************************
+ Function prototypes
+*****************************************************************************/
+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);
+
+/* Direct macros for Linux to avoid LockDep false-positives from occurring */
+#if defined(LINUX) && defined(__KERNEL__)
+
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#define HostCreateMutex(IMG_VOID) ({ \
+       struct mutex* pMutex = NULL; \
+       pMutex = kmalloc(sizeof(struct mutex), GFP_KERNEL); \
+       if (pMutex) { mutex_init(pMutex); }; \
+       pMutex;})
+#define HostDestroyMutex(hLock) ({mutex_destroy((hLock)); kfree((hLock)); PVRSRV_OK;})
+
+#define HostAquireMutex(hLock) ({mutex_lock((hLock)); PVRSRV_OK;})
+#define HostReleaseMutex(hLock) ({mutex_unlock((hLock)); PVRSRV_OK;})
+
+#else /* defined(LINUX) && defined(__KERNEL__) */
+
+IMG_VOID * HostCreateMutex(IMG_VOID);
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex);
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex);
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex);
+
+#endif
+
+#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 /*defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+
+#endif
+
+/*****************************************************************************
+ End of file (HOSTFUNC.H)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/ioctl.c b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/common/ioctl.c
new file mode 100644 (file)
index 0000000..43b38ed
--- /dev/null
@@ -0,0 +1,308 @@
+/*************************************************************************/ /*!
+@File
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(_WIN32)
+#pragma  warning(disable:4201)
+#pragma  warning(disable:4214)
+#pragma  warning(disable:4115)
+#pragma  warning(disable:4514)
+
+#include <ntddk.h>
+#include <windef.h>
+
+#endif /* _WIN32 */
+
+#ifdef LINUX
+#include <asm/uaccess.h>
+#include "pvr_uaccess.h"
+#endif /* LINUX */
+
+#include "img_types.h"
+#include "dbgdrvif_srv5.h"
+#include "dbgdriv.h"
+#include "dbgdriv_ioctl.h"
+#include "hostfunc.h"
+
+#ifdef _WIN32
+#pragma  warning(default:4214)
+#pragma  warning(default:4115)
+#endif /* _WIN32 */
+
+/*****************************************************************************
+ Code
+*****************************************************************************/
+
+/*****************************************************************************
+ FUNCTION      :       DBGDIOCDrivGetServiceTable
+
+ PURPOSE       :
+
+ PARAMETERS    :
+
+ RETURNS       :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       IMG_PVOID *     ppvOut;
+
+       PVR_UNREFERENCED_PARAMETER(pvInBuffer);
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+       ppvOut = (IMG_PVOID *) pvOutBuffer;
+
+       *ppvOut = DBGDrivGetServiceTable();
+
+    return(IMG_TRUE);
+}
+
+#if defined(__QNXNTO__)
+/*****************************************************************************
+ FUNCTION      :       DBGIODrivCreateStream
+
+ PURPOSE       :
+
+ PARAMETERS    :
+
+ RETURNS       :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       PDBG_IN_CREATESTREAM psIn;
+       PDBG_OUT_CREATESTREAM psOut;
+
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+
+       psIn = (PDBG_IN_CREATESTREAM) pvInBuffer;
+       psOut = (PDBG_OUT_CREATESTREAM) pvOutBuffer;
+
+       return (ExtDBGDrivCreateStream(psIn->u.pszName, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages, &psOut->phInit, &psOut->phMain, &psOut->phDeinit));
+}
+#endif
+
+/*****************************************************************************
+ FUNCTION      :       DBGDIOCDrivGetStream
+
+ PURPOSE       :
+
+ PARAMETERS    :
+
+ RETURNS       :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       PDBG_IN_FINDSTREAM psParams;
+       IMG_SID *       phStream;
+
+       psParams        = (PDBG_IN_FINDSTREAM)pvInBuffer;
+       phStream        = (IMG_SID *)pvOutBuffer;
+
+       *phStream = PStream2SID(ExtDBGDrivFindStream(WIDEPTR_GET_PTR(psParams->pszName, bCompat), psParams->bResetStream));
+
+       return(IMG_TRUE);
+}
+
+/*****************************************************************************
+ FUNCTION      :       DBGDIOCDrivRead
+
+ PURPOSE       :
+
+ PARAMETERS    :
+
+ RETURNS       :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       IMG_UINT32 *    pui32BytesCopied;
+       PDBG_IN_READ    psInParams;
+       PDBG_STREAM             psStream;
+       IMG_UINT8       *pui8ReadBuffer;
+
+       psInParams = (PDBG_IN_READ) pvInBuffer;
+       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+       pui8ReadBuffer = WIDEPTR_GET_PTR(psInParams->pui8OutBuffer, bCompat);
+
+       psStream = SID2PStream(psInParams->hStream);
+
+       if (psStream != (PDBG_STREAM)IMG_NULL)
+       {
+               *pui32BytesCopied = ExtDBGDrivRead(psStream,
+                                                                          psInParams->ui32BufID,
+                                                                          psInParams->ui32OutBufferSize,
+                                                                          pui8ReadBuffer);
+               return(IMG_TRUE);
+       }
+       else
+       {
+               /* invalid SID */
+               *pui32BytesCopied = 0;
+               return(IMG_FALSE);
+       }
+}
+
+/*****************************************************************************
+ FUNCTION      : DBGDIOCDrivSetMarker
+
+ PURPOSE       : Sets the marker in the stream to split output files
+
+ PARAMETERS    : pvInBuffer, pvOutBuffer
+
+ RETURNS       : success
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       PDBG_IN_SETMARKER       psParams;
+       PDBG_STREAM                     psStream;
+
+       psParams = (PDBG_IN_SETMARKER) pvInBuffer;
+       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+
+       psStream = SID2PStream(psParams->hStream);
+       if (psStream != (PDBG_STREAM)IMG_NULL)
+       {
+               ExtDBGDrivSetMarker(psStream, psParams->ui32Marker);
+               return(IMG_TRUE);
+       }
+       else
+       {
+               /* invalid SID */
+               return(IMG_FALSE);
+       }
+}
+
+/*****************************************************************************
+ FUNCTION      : DBGDIOCDrivGetMarker
+
+ PURPOSE       : Gets the marker in the stream to split output files
+
+ PARAMETERS    : pvInBuffer, pvOutBuffer
+
+ RETURNS       : success
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       PDBG_STREAM  psStream;
+       IMG_UINT32  *pui32Current;
+
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+
+       pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+       psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+       if (psStream != (PDBG_STREAM)IMG_NULL)
+       {
+               *pui32Current = ExtDBGDrivGetMarker(psStream);
+               return(IMG_TRUE);
+       }
+       else
+       {
+               /* invalid SID */
+               *pui32Current = 0;
+               return(IMG_FALSE);
+       }
+}
+
+
+/*****************************************************************************
+ FUNCTION      :       DBGDIOCDrivWaitForEvent
+
+ PURPOSE       :
+
+ PARAMETERS    :
+
+ RETURNS       :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       DBG_EVENT eEvent = (DBG_EVENT)(*(IMG_UINT32 *)pvInBuffer);
+
+       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+
+       ExtDBGDrivWaitForEvent(eEvent);
+
+       return(IMG_TRUE);
+}
+
+
+/*****************************************************************************
+ FUNCTION      : DBGDIOCDrivGetFrame
+
+ PURPOSE       : Gets the marker in the stream to split output files
+
+ PARAMETERS    : pvInBuffer, pvOutBuffer
+
+ RETURNS       : success
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer, IMG_BOOL bCompat)
+{
+       IMG_UINT32  *pui32Current;
+
+       PVR_UNREFERENCED_PARAMETER(pvInBuffer);
+       PVR_UNREFERENCED_PARAMETER(bCompat);
+
+       pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+       *pui32Current = ExtDBGDrivGetFrame();
+
+       return(IMG_TRUE);
+}
+
+/*
+       ioctl interface jump table.
+       Accessed from the UM debug driver client
+*/
+IMG_UINT32 (*g_DBGDrivProc[DEBUG_SERVICE_MAX_API])(IMG_VOID *, IMG_VOID *, IMG_BOOL) =
+{
+       DBGDIOCDrivGetServiceTable, /* WDDM only for KMD to retrieve address from DBGDRV, Not used by umdbgdrvlnx */
+       DBGDIOCDrivGetStream,
+       DBGDIOCDrivRead,
+       DBGDIOCDrivSetMarker,
+       DBGDIOCDrivGetMarker,
+       DBGDIOCDrivWaitForEvent,
+       DBGDIOCDrivGetFrame,
+#if defined(__QNXNTO__)
+       DBGDIOCDrivCreateStream
+#endif
+};
+
+/*****************************************************************************
+ End of file (IOCTL.C)
+*****************************************************************************/
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/hostfunc.c b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/hostfunc.c
new file mode 100644 (file)
index 0000000..ede5aba
--- /dev/null
@@ -0,0 +1,328 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug driver file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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 /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+
+#include "img_types.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif_srv5.h"
+#include "hostfunc.h"
+#include "dbgdriv.h"
+
+#if defined(PVRSRV_NEED_PVR_DPF) && !defined(SUPPORT_DRM)
+IMG_UINT32     gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING |
+               DBGPRIV_CALLTRACE); /* Added call trace level to support PVR_LOGging of state in debug driver */
+
+#define PVR_STRING_TERMINATOR          '\0'
+#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
+
+/******************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+<function>
+       FUNCTION   : PVRSRVDebugPrintf
+       PURPOSE    : To output a debug message to the user
+       PARAMETERS : In : uDebugLevel - The current debug level
+                    In : pszFile - The source file generating the message
+                    In : uLine - The line of the source file
+                    In : pszFormat - The message format string
+                    In : ... - Zero or more arguments for use by the format string
+       RETURNS    : None
+</function>
+------------------------------------------------------------------------------*/
+void PVRSRVDebugPrintf (
+                                               IMG_UINT32      ui32DebugLevel,
+                                               const IMG_CHAR* pszFileName,
+                                               IMG_UINT32      ui32Line,
+                                               const IMG_CHAR* pszFormat,
+                                               ...
+                                       )
+{
+       IMG_BOOL bTrace;
+       IMG_CHAR *pszLeafName;
+
+       pszLeafName = (char *)strrchr (pszFileName, '/');
+
+       if (pszLeafName)
+       {
+               pszFileName = pszLeafName;
+       }
+
+       bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+       if (gPVRDebugLevel & ui32DebugLevel)
+       {
+               va_list vaArgs;
+               static char szBuffer[512];
+
+               va_start (vaArgs, pszFormat);
+
+               /* Add in the level of warning */
+               if (bTrace == IMG_FALSE)
+               {
+                       switch(ui32DebugLevel)
+                       {
+                               case DBGPRIV_FATAL:
+                               {
+                                       strcpy (szBuffer, "PVR_K:(Fatal): ");
+                                       break;
+                               }
+                               case DBGPRIV_ERROR:
+                               {
+                                       strcpy (szBuffer, "PVR_K:(Error): ");
+                                       break;
+                               }
+                               case DBGPRIV_WARNING:
+                               {
+                                       strcpy (szBuffer, "PVR_K:(Warning): ");
+                                       break;
+                               }
+                               case DBGPRIV_MESSAGE:
+                               {
+                                       strcpy (szBuffer, "PVR_K:(Message): ");
+                                       break;
+                               }
+                               case DBGPRIV_VERBOSE:
+                               {
+                                       strcpy (szBuffer, "PVR_K:(Verbose): ");
+                                       break;
+                               }
+                               default:
+                               {
+                                       strcpy (szBuffer, "PVR_K:()");
+                                       break;
+                               }
+                       }
+               }
+               else
+               {
+                       strcpy (szBuffer, "PVR_K: ");
+               }
+
+               vsprintf (&szBuffer[strlen(szBuffer)], pszFormat, vaArgs);
+
+               /*
+                * Metrics and Traces don't need a location
+                */
+               if (bTrace == IMG_FALSE)
+               {
+                       sprintf (&szBuffer[strlen(szBuffer)], " [%d, %s]", (int)ui32Line, pszFileName);
+               }
+
+               printk(KERN_INFO "%s\n", szBuffer);
+
+               va_end (vaArgs);
+       }
+}
+#endif /* defined(PVRSRV_NEED_PVR_DPF) && !defined(SUPPORT_DRM) */
+
+/*!
+******************************************************************************
+
+ @Function     HostMemSet
+
+ @Description Function that does the same as the C memset() functions
+
+ @Modified *pvDest :   pointer to start of buffer to be set
+
+ @Input    ui8Value:   value to set each byte to
+
+ @Input    ui32Size :  number of bytes to set
+
+ @Return   IMG_VOID
+
+******************************************************************************/
+IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+       memset(pvDest, (int) ui8Value, (size_t) ui32Size);
+}
+
+/*!
+******************************************************************************
+
+ @Function             HostMemCopy
+
+ @Description  Copies memory around
+
+ @Input    pvDst - pointer to dst
+ @Output   pvSrc - pointer to src
+ @Input    ui32Size - bytes to copy
+
+ @Return  none
+
+******************************************************************************/
+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)
+{
+    /* XXX Not yet implemented */
+       return 0;
+}
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);/*, GFP_KERNEL);*/
+}
+
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);/*, GFP_KERNEL);*/
+}
+
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
+{
+    /* XXX Not yet implemented */
+       return IMG_NULL;
+}
+
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
+{
+    /* XXX Not yet implemented */
+}
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
+{
+    /* XXX Not yet implemented */
+}
+
+#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:
+                       /*
+                        * More than one process may be woken up.
+                        * Any process that wakes up should consume
+                        * all the data from the streams.
+                        */
+                       wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
+                       iStreamData = 0;
+                       break;
+               default:
+                       /*
+                        * For unknown events, enter an interruptible sleep.
+                        */
+                       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 /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
diff --git a/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/main.c b/drivers/gpu/rogue_m/tools/services/debug/dbgdriv/linux/main.c
new file mode 100644 (file)
index 0000000..3c34df0
--- /dev/null
@@ -0,0 +1,373 @@
+/*************************************************************************/ /*!
+@File
+@Title          Debug driver main file
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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_DRM)
+#include <linux/platform_device.h>
+#endif
+
+#if defined(LDM_PCI) && !defined(SUPPORT_DRM)
+#include <linux/pci.h>
+#endif
+
+#include <asm/uaccess.h>
+
+#if defined(SUPPORT_DRM)
+#include <drm/drmP.h>
+#endif
+
+#include "img_types.h"
+#include "linuxsrv.h"
+#include "dbgdriv_ioctl.h"
+#include "dbgdrvif_srv5.h"
+#include "dbgdriv.h"
+#include "hostfunc.h"
+#include "pvr_debug.h"
+#include "pvrmodule.h"
+#include "pvr_uaccess.h"
+
+#if defined(SUPPORT_DRM)
+
+#include "pvr_drm_shared.h"
+#include "pvr_drm.h"
+
+#else /* defined(SUPPORT_DRM) */
+
+#define DRVNAME "dbgdrv"
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+
+static struct class *psDbgDrvClass;
+
+static int AssignedMajorNumber = 0;
+
+long dbgdrv_ioctl(struct file *, unsigned int, unsigned long);
+long dbgdrv_ioctl_compat(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,
+       .compat_ioctl   = dbgdrv_ioctl_compat,
+       .open           = dbgdrv_open,
+       .release        = dbgdrv_release,
+       .mmap           = dbgdrv_mmap,
+};
+
+#endif  /* defined(SUPPORT_DRM) */
+
+/* Outward temp buffer used by IOCTL handler allocated once and grows as needed.
+ * This optimisation means the debug driver performs less vmallocs/vfrees
+ * reducing the chance of kernel vmalloc space exhaustion.
+ * Singular out buffer for PDump UM reads is not multi-thread safe and so
+ * it now needs a mutex to protect it from multiple simultaneous reads in 
+ * the future.
+ */
+static IMG_CHAR*  g_outTmpBuf = IMG_NULL;
+static IMG_UINT32 g_outTmpBufSize = 64*PAGE_SIZE;
+static void*      g_pvOutTmpBufMutex = IMG_NULL;
+
+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_DRM)
+void dbgdrv_cleanup(void)
+#else
+void cleanup_module(void)
+#endif
+{
+       if (g_outTmpBuf)
+       {
+               vfree(g_outTmpBuf);
+               g_outTmpBuf = IMG_NULL;
+       }
+
+#if !defined(SUPPORT_DRM)
+       device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
+       class_destroy(psDbgDrvClass);
+       unregister_chrdev(AssignedMajorNumber, DRVNAME);
+#endif /* !defined(SUPPORT_DRM) */
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+       HostDestroyEventObjects();
+#endif
+       HostDestroyMutex(g_pvOutTmpBufMutex);
+       HostDestroyMutex(g_pvAPIMutex);
+       return;
+}
+
+#if defined(SUPPORT_DRM)
+IMG_INT dbgdrv_init(void)
+#else
+int init_module(void)
+#endif
+{
+#if !defined(SUPPORT_DRM)
+       struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRM)
+       int err = -EBUSY;
+#endif
+
+       /* Init API mutex */
+       if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL)
+       {
+               return -ENOMEM;
+       }
+
+       /* Init TmpBuf mutex */
+       if ((g_pvOutTmpBufMutex=HostCreateMutex()) == IMG_NULL)
+       {
+               return -ENOMEM;
+       }
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+       /*
+        * The current implementation of HostCreateEventObjects on Linux
+        * can never fail, so there is no need to check for error.
+        */
+       (void) HostCreateEventObjects();
+#endif
+
+#if !defined(SUPPORT_DRM)
+       AssignedMajorNumber =
+               register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
+
+       if (AssignedMajorNumber <= 0)
+       {
+               PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
+               goto ErrDestroyEventObjects;
+       }
+
+       /*
+        * This code (using GPL symbols) facilitates automatic device
+        * node creation on platforms with udev (or similar).
+        */
+       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), NULL, DRVNAME);
+       if (IS_ERR(psDev))
+       {
+               PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
+                                                               __func__, PTR_ERR(psDev)));
+               goto ErrDestroyClass;
+       }
+#endif /* !defined(SUPPORT_DRM) */
+
+       return 0;
+
+#if !defined(SUPPORT_DRM)
+ErrDestroyEventObjects:
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+       HostDestroyEventObjects();
+#endif
+ErrUnregisterCharDev:
+       unregister_chrdev(AssignedMajorNumber, DRVNAME);
+ErrDestroyClass:
+       class_destroy(psDbgDrvClass);
+       return err;
+#endif /* !defined(SUPPORT_DRM) */
+}
+
+static IMG_INT dbgdrv_ioctl_work(IMG_VOID *arg, IMG_BOOL bCompat)
+{
+       IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
+       char *buffer, *in, *out;
+       unsigned int cmd;
+       IMG_VOID *pBufferIn, *pBufferOut;
+
+       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);
+
+       pBufferIn = WIDEPTR_GET_PTR(pIP->pInBuffer, bCompat);
+       pBufferOut = WIDEPTR_GET_PTR(pIP->pOutBuffer, bCompat);
+
+       if (pvr_copy_from_user(in, pBufferIn, pIP->ui32InBufferSize) != 0)
+       {
+               goto init_failed;
+       }
+
+       /* Extra -1 because ioctls start at DEBUG_SERVICE_IOCTL_BASE + 1 */
+       cmd = MAKEIOCTLINDEX(pIP->ui32Cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
+
+       if (pIP->ui32Cmd == DEBUG_SERVICE_READ)
+       {
+               IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
+               DBG_OUT_READ *psReadOutParams = (DBG_OUT_READ *)out;
+               DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in;
+               IMG_VOID *pvOutBuffer;
+               PDBG_STREAM psStream;
+
+               psStream = SID2PStream(psReadInParams->hStream);
+               if (!psStream)
+               {
+                       goto init_failed;
+               }
+
+               /* Serialise IOCTL Read op access to the singular output buffer */
+               HostAquireMutex(g_pvOutTmpBufMutex);
+
+               if ((g_outTmpBuf == IMG_NULL) || (psReadInParams->ui32OutBufferSize > g_outTmpBufSize))
+               {
+                       if (psReadInParams->ui32OutBufferSize > g_outTmpBufSize)
+                       {
+                               g_outTmpBufSize = psReadInParams->ui32OutBufferSize;
+                       }
+                       g_outTmpBuf = vmalloc(g_outTmpBufSize);
+                       if (!g_outTmpBuf)
+                       {
+                               HostReleaseMutex(g_pvOutTmpBufMutex);
+                               goto init_failed;
+                       }
+               }
+
+               /* Ensure only one thread is allowed into the DBGDriv core at a time */
+               HostAquireMutex(g_pvAPIMutex);
+
+               psReadOutParams->ui32DataRead = DBGDrivRead(psStream,
+                                                                                  psReadInParams->ui32BufID,
+                                                                                  psReadInParams->ui32OutBufferSize,
+                                                                                  g_outTmpBuf);
+               psReadOutParams->ui32SplitMarker = DBGDrivGetMarker(psStream);
+
+               HostReleaseMutex(g_pvAPIMutex);
+
+               pvOutBuffer = WIDEPTR_GET_PTR(psReadInParams->pui8OutBuffer, bCompat);
+
+               if (pvr_copy_to_user(pvOutBuffer,
+                                               g_outTmpBuf,
+                                               *pui32BytesCopied) != 0)
+               {
+                       HostReleaseMutex(g_pvOutTmpBufMutex);
+                       goto init_failed;
+               }
+
+               HostReleaseMutex(g_pvOutTmpBufMutex);
+
+       }
+       else
+       {
+               (g_DBGDrivProc[cmd])(in, out, bCompat);
+       }
+
+       if (copy_to_user(pBufferOut, out, pIP->ui32OutBufferSize) != 0)
+       {
+               goto init_failed;
+       }
+
+       HostPageablePageFree((IMG_VOID *)buffer);
+       return 0;
+
+init_failed:
+       HostPageablePageFree((IMG_VOID *)buffer);
+       return -EFAULT;
+}
+
+#if defined(SUPPORT_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
+{
+       return dbgdrv_ioctl_work((IMG_VOID *) arg, IMG_FALSE);
+}
+
+#if defined(SUPPORT_DRM)
+int dbgdrv_ioctl_compat(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+#else
+long dbgdrv_ioctl_compat(struct file *file, unsigned int ioctlCmd, unsigned long arg)
+#endif
+{
+       return dbgdrv_ioctl_work((IMG_VOID *) arg, IMG_TRUE);
+}
+
+
+
+EXPORT_SYMBOL(DBGDrvGetServiceTable);
diff --git a/drivers/gpu/rogue_m/tools/services/debug/include/linuxsrv.h b/drivers/gpu/rogue_m/tools/services/debug/include/linuxsrv.h
new file mode 100644 (file)
index 0000000..1966906
--- /dev/null
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@File
+@Title          Module defs for pvr core drivers
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _LINUXSRV_H__
+#define _LINUXSRV_H__
+
+#include "dbgdrvif_srv5.h"
+
+typedef struct  tagIOCTL_PACKAGE
+{
+       IMG_UINT32 ui32Cmd;              // ioctl command
+       IMG_UINT32 ui32Size;                       // needs to be correctly set
+       DBG_WIDEPTR     pInBuffer;          // input data buffer
+       IMG_UINT32  ui32InBufferSize;     // size of input data buffer
+       DBG_WIDEPTR    pOutBuffer;         // output data buffer
+       IMG_UINT32  ui32OutBufferSize;    // size of output data buffer
+#if defined(SUPPORT_DRM)
+       IMG_UINT32 ui32PtrSize;
+#endif
+} 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__*/
index 7e0ac1996627b064f2a84c6acc247cc0ddcfc869..9be0f251e7e23ddee747eda1b35e9ec5cf4a2ace 100644 (file)
@@ -24,6 +24,8 @@ source "drivers/gpu/ipu-v3/Kconfig"
 
 source "drivers/gpu/drm/Kconfig"
 
+source "drivers/gpu/rogue_m/Kconfig"
+
 menu "Frame buffer Devices"
 source "drivers/video/fbdev/Kconfig"
 endmenu